diff options
845 files changed, 15351 insertions, 6361 deletions
diff --git a/Android.mk b/Android.mk index 1469c2cdf93e..ae5d67ed2de3 100644 --- a/Android.mk +++ b/Android.mk @@ -197,7 +197,6 @@ LOCAL_SRC_FILES += \ core/java/android/net/ICaptivePortal.aidl \ core/java/android/net/IConnectivityManager.aidl \ core/java/android/net/IConnectivityMetricsLogger.aidl \ - core/java/android/net/IConnectivityMetricsLoggerSubscriber.aidl \ core/java/android/net/IEthernetManager.aidl \ core/java/android/net/IEthernetServiceListener.aidl \ core/java/android/net/INetworkManagementEventObserver.aidl \ @@ -245,6 +244,8 @@ LOCAL_SRC_FILES += \ core/java/android/service/notification/IConditionListener.aidl \ core/java/android/service/notification/IConditionProvider.aidl \ core/java/android/service/vr/IVrListener.aidl \ + core/java/android/service/vr/IVrManager.aidl \ + core/java/android/service/vr/IVrStateCallbacks.aidl \ core/java/android/print/ILayoutResultCallback.aidl \ core/java/android/print/IPrinterDiscoveryObserver.aidl \ core/java/android/print/IPrintDocumentAdapter.aidl \ diff --git a/api/current.txt b/api/current.txt index 07a4f6d117d9..f346e0b6f054 100644 --- a/api/current.txt +++ b/api/current.txt @@ -2485,6 +2485,7 @@ package android { field public static final int Widget_Material_CompoundButton_CheckBox = 16974435; // 0x1030263 field public static final int Widget_Material_CompoundButton_RadioButton = 16974436; // 0x1030264 field public static final int Widget_Material_CompoundButton_Star = 16974437; // 0x1030265 + field public static final int Widget_Material_CompoundButton_Switch = 16974554; // 0x10302da field public static final int Widget_Material_DatePicker = 16974438; // 0x1030266 field public static final int Widget_Material_DropDownItem = 16974439; // 0x1030267 field public static final int Widget_Material_DropDownItem_Spinner = 16974440; // 0x1030268 @@ -2519,6 +2520,7 @@ package android { field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974500; // 0x10302a4 field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974501; // 0x10302a5 field public static final int Widget_Material_Light_CompoundButton_Star = 16974502; // 0x10302a6 + field public static final int Widget_Material_Light_CompoundButton_Switch = 16974555; // 0x10302db field public static final int Widget_Material_Light_DatePicker = 16974503; // 0x10302a7 field public static final int Widget_Material_Light_DropDownItem = 16974504; // 0x10302a8 field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974505; // 0x10302a9 @@ -4977,7 +4979,7 @@ package android.app { field public int ledARGB; field public int ledOffMS; field public int ledOnMS; - field public int number; + field public deprecated int number; field public int priority; field public android.app.Notification publicVersion; field public android.net.Uri sound; @@ -5024,11 +5026,13 @@ package android.app { method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Builder); method public java.lang.CharSequence getCancelLabel(); method public java.lang.CharSequence getConfirmLabel(); + method public boolean getHintContentIntentLaunchesActivity(); method public java.lang.CharSequence getInProgressLabel(); method public boolean isAvailableOffline(); method public android.app.Notification.Action.WearableExtender setAvailableOffline(boolean); method public android.app.Notification.Action.WearableExtender setCancelLabel(java.lang.CharSequence); method public android.app.Notification.Action.WearableExtender setConfirmLabel(java.lang.CharSequence); + method public android.app.Notification.Action.WearableExtender setHintContentIntentLaunchesActivity(boolean); method public android.app.Notification.Action.WearableExtender setInProgressLabel(java.lang.CharSequence); } @@ -5070,7 +5074,7 @@ package android.app { method public android.app.Notification.Builder setChronometerCountsDown(boolean); method public android.app.Notification.Builder setColor(int); method public deprecated android.app.Notification.Builder setContent(android.widget.RemoteViews); - method public android.app.Notification.Builder setContentInfo(java.lang.CharSequence); + method public deprecated android.app.Notification.Builder setContentInfo(java.lang.CharSequence); method public android.app.Notification.Builder setContentIntent(android.app.PendingIntent); method public android.app.Notification.Builder setContentText(java.lang.CharSequence); method public android.app.Notification.Builder setContentTitle(java.lang.CharSequence); @@ -5087,7 +5091,7 @@ package android.app { method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon); method public android.app.Notification.Builder setLights(int, int, int); method public android.app.Notification.Builder setLocalOnly(boolean); - method public android.app.Notification.Builder setNumber(int); + method public deprecated android.app.Notification.Builder setNumber(int); method public android.app.Notification.Builder setOngoing(boolean); method public android.app.Notification.Builder setOnlyAlertOnce(boolean); method public android.app.Notification.Builder setPriority(int); @@ -5205,6 +5209,7 @@ package android.app { method public android.app.PendingIntent getDisplayIntent(); method public int getGravity(); method public boolean getHintAvoidBackgroundClipping(); + method public boolean getHintContentIntentLaunchesActivity(); method public boolean getHintHideIcon(); method public int getHintScreenTimeout(); method public boolean getHintShowBackgroundOnly(); @@ -5220,6 +5225,7 @@ package android.app { method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent); method public android.app.Notification.WearableExtender setGravity(int); method public android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean); + method public android.app.Notification.WearableExtender setHintContentIntentLaunchesActivity(boolean); method public android.app.Notification.WearableExtender setHintHideIcon(boolean); method public android.app.Notification.WearableExtender setHintScreenTimeout(int); method public android.app.Notification.WearableExtender setHintShowBackgroundOnly(boolean); @@ -5919,7 +5925,7 @@ package android.app.admin { method public java.util.List<android.app.admin.SecurityLog.SecurityEvent> retrievePreRebootSecurityLogs(android.content.ComponentName); method public java.util.List<android.app.admin.SecurityLog.SecurityEvent> retrieveSecurityLogs(android.content.ComponentName); method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean); - method public boolean setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String); + method public void setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException, java.lang.UnsupportedOperationException; method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean); method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle); method public void setApplicationRestrictionsManagingPackage(android.content.ComponentName, java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; @@ -7883,6 +7889,7 @@ package android.content { method public static boolean isSyncPending(android.accounts.Account, java.lang.String); method public void notifyChange(android.net.Uri, android.database.ContentObserver); method public void notifyChange(android.net.Uri, android.database.ContentObserver, boolean); + method public void notifyChange(android.net.Uri, android.database.ContentObserver, int); method public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException; method public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException; method public final android.os.ParcelFileDescriptor openFileDescriptor(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException; @@ -7913,6 +7920,8 @@ package android.content { field public static final java.lang.String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; field public static final java.lang.String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; field public static final java.lang.String EXTRA_SIZE = "android.content.extra.SIZE"; + field public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 2; // 0x2 + field public static final int NOTIFY_SYNC_TO_NETWORK = 1; // 0x1 field public static final java.lang.String SCHEME_ANDROID_RESOURCE = "android.resource"; field public static final java.lang.String SCHEME_CONTENT = "content"; field public static final java.lang.String SCHEME_FILE = "file"; @@ -8521,8 +8530,9 @@ package android.content { field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED"; field public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN"; field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED"; - field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED"; + field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABLE = "android.intent.action.MANAGED_PROFILE_AVAILABLE"; field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED"; + field public static final java.lang.String ACTION_MANAGED_PROFILE_UNAVAILABLE = "android.intent.action.MANAGED_PROFILE_UNAVAILABLE"; field public static final java.lang.String ACTION_MANAGED_PROFILE_UNLOCKED = "android.intent.action.MANAGED_PROFILE_UNLOCKED"; field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE"; field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE"; @@ -20070,7 +20080,6 @@ package android.media { } public abstract class DrmInitData { - ctor public DrmInitData(); method public abstract android.media.DrmInitData.SchemeInitData get(java.util.UUID); } @@ -20325,8 +20334,8 @@ package android.media { public class MediaActionSound { ctor public MediaActionSound(); - method public synchronized void load(int); - method public synchronized void play(int); + method public void load(int); + method public void play(int); method public void release(); field public static final int FOCUS_COMPLETE = 1; // 0x1 field public static final int SHUTTER_CLICK = 0; // 0x0 @@ -23449,6 +23458,7 @@ package android.net { method public boolean isActiveNetworkMetered(); method public boolean isDefaultNetworkActive(); method public static deprecated boolean isNetworkTypeValid(int); + method public void registerDefaultNetworkCallback(android.net.ConnectivityManager.NetworkCallback); method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback); method public void registerNetworkCallback(android.net.NetworkRequest, android.app.PendingIntent); method public void releaseNetworkRequest(android.app.PendingIntent); @@ -29074,6 +29084,7 @@ package android.os { method public boolean isInteractive(); method public boolean isPowerSaveMode(); method public deprecated boolean isScreenOn(); + method public boolean isSustainedPerformanceModeSupported(); method public boolean isWakeLockLevelSupported(int); method public android.os.PowerManager.WakeLock newWakeLock(int, java.lang.String); method public void reboot(java.lang.String); @@ -29700,7 +29711,6 @@ package android.preference { method protected void onClick(); method protected android.view.View onCreateView(android.view.ViewGroup); method public void onDependencyChanged(android.preference.Preference, boolean); - method protected void onDetachedFromActivity(); method protected java.lang.Object onGetDefaultValue(android.content.res.TypedArray, int); method public void onParentChanged(android.preference.Preference, boolean); method protected void onPrepareForRemoval(); @@ -36618,7 +36628,6 @@ package android.telecom { method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle); method public boolean isInCall(); method public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, java.lang.String); - method public deprecated void launchManageBlockedNumbersActivity(); method public void placeCall(android.net.Uri, android.os.Bundle); method public void registerPhoneAccount(android.telecom.PhoneAccount); method public void showInCallScreen(boolean); @@ -37307,7 +37316,8 @@ package android.telephony { method public java.lang.String getDeviceSoftwareVersion(); method public java.lang.String getGroupIdLevel1(); method public java.lang.String getGroupIdLevel1(int); - method public java.lang.String getIccSimChallengeResponse(int, java.lang.String); + method public java.lang.String getIccAuthentication(int, int, java.lang.String); + method public java.lang.String getIccAuthentication(int, int, int, java.lang.String); method public java.lang.String getLine1AlphaTag(int); method public java.lang.String getLine1Number(); method public java.lang.String getLine1Number(int); @@ -37376,6 +37386,13 @@ package android.telephony { field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL"; field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE"; field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE"; + field public static final int APPTYPE_CSIM = 4; // 0x4 + field public static final int APPTYPE_ISIM = 5; // 0x5 + field public static final int APPTYPE_RUIM = 3; // 0x3 + field public static final int APPTYPE_SIM = 1; // 0x1 + field public static final int APPTYPE_USIM = 2; // 0x2 + field public static final int AUTHTYPE_EAP_AKA = 129; // 0x81 + field public static final int AUTHTYPE_EAP_SIM = 128; // 0x80 field public static final int CALL_STATE_IDLE = 0; // 0x0 field public static final int CALL_STATE_OFFHOOK = 2; // 0x2 field public static final int CALL_STATE_RINGING = 1; // 0x1 @@ -42273,6 +42290,7 @@ package android.view { method public boolean dispatchDragEvent(android.view.DragEvent); method protected void dispatchDraw(android.graphics.Canvas); method public void dispatchDrawableHotspotChanged(float, float); + method public void dispatchFinishTemporaryDetach(); method protected boolean dispatchGenericFocusedEvent(android.view.MotionEvent); method public boolean dispatchGenericMotionEvent(android.view.MotionEvent); method protected boolean dispatchGenericPointerEvent(android.view.MotionEvent); @@ -42292,6 +42310,7 @@ package android.view { method protected void dispatchSetActivated(boolean); method protected void dispatchSetPressed(boolean); method protected void dispatchSetSelected(boolean); + method public void dispatchStartTemporaryDetach(); method public void dispatchSystemUiVisibilityChanged(int); method public boolean dispatchTouchEvent(android.view.MotionEvent); method public boolean dispatchTrackballEvent(android.view.MotionEvent); @@ -42504,6 +42523,7 @@ package android.view { method public boolean isSelected(); method public boolean isShown(); method public boolean isSoundEffectsEnabled(); + method public final boolean isTemporarilyDetached(); method public boolean isTextAlignmentResolved(); method public boolean isTextDirectionResolved(); method public boolean isVerticalFadingEdgeEnabled(); @@ -44088,8 +44108,6 @@ package android.view.accessibility { method public void setVisibleToUser(boolean); method public void writeToParcel(android.os.Parcel, int); field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40 - field public static final java.lang.String ACTION_ARGUMENT_CLICK_CHARACTER_INDEX_INT = "android.view.accessibility.action.ARGUMENT_CLICK_CHARACTER_INDEX_INT"; - field public static final java.lang.String ACTION_ARGUMENT_CLICK_SPAN_INDEX_INT = "android.view.accessibility.action.ARGUMENT_CLICK_SPAN_INDEX_INT"; field public static final java.lang.String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT"; field public static final java.lang.String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN"; field public static final java.lang.String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING"; @@ -44260,6 +44278,7 @@ package android.view.accessibility { public final class AccessibilityWindowInfo implements android.os.Parcelable { method public int describeContents(); + method public android.view.accessibility.AccessibilityNodeInfo getAnchor(); method public void getBoundsInScreen(android.graphics.Rect); method public android.view.accessibility.AccessibilityWindowInfo getChild(int); method public int getChildCount(); @@ -44267,6 +44286,7 @@ package android.view.accessibility { method public int getLayer(); method public android.view.accessibility.AccessibilityWindowInfo getParent(); method public android.view.accessibility.AccessibilityNodeInfo getRoot(); + method public java.lang.CharSequence getTitle(); method public int getType(); method public boolean isAccessibilityFocused(); method public boolean isActive(); @@ -46258,7 +46278,7 @@ package android.widget { method public long getMinDate(); method public deprecated android.graphics.drawable.Drawable getSelectedDateVerticalBar(); method public deprecated int getSelectedWeekBackgroundColor(); - method public boolean getShowWeekNumber(); + method public deprecated boolean getShowWeekNumber(); method public deprecated int getShownWeekCount(); method public deprecated int getUnfocusedMonthDateColor(); method public int getWeekDayTextAppearance(); @@ -46275,7 +46295,7 @@ package android.widget { method public deprecated void setSelectedDateVerticalBar(int); method public deprecated void setSelectedDateVerticalBar(android.graphics.drawable.Drawable); method public deprecated void setSelectedWeekBackgroundColor(int); - method public void setShowWeekNumber(boolean); + method public deprecated void setShowWeekNumber(boolean); method public deprecated void setShownWeekCount(int); method public deprecated void setUnfocusedMonthDateColor(int); method public void setWeekDayTextAppearance(int); @@ -46422,21 +46442,21 @@ package android.widget { ctor public DatePicker(android.content.Context, android.util.AttributeSet); ctor public DatePicker(android.content.Context, android.util.AttributeSet, int); ctor public DatePicker(android.content.Context, android.util.AttributeSet, int, int); - method public android.widget.CalendarView getCalendarView(); - method public boolean getCalendarViewShown(); + method public deprecated android.widget.CalendarView getCalendarView(); + method public deprecated boolean getCalendarViewShown(); method public int getDayOfMonth(); method public int getFirstDayOfWeek(); method public long getMaxDate(); method public long getMinDate(); method public int getMonth(); - method public boolean getSpinnersShown(); + method public deprecated boolean getSpinnersShown(); method public int getYear(); method public void init(int, int, int, android.widget.DatePicker.OnDateChangedListener); - method public void setCalendarViewShown(boolean); + method public deprecated void setCalendarViewShown(boolean); method public void setFirstDayOfWeek(int); method public void setMaxDate(long); method public void setMinDate(long); - method public void setSpinnersShown(boolean); + method public deprecated void setSpinnersShown(boolean); method public void updateDate(int, int, int); } @@ -50008,6 +50028,7 @@ package java.lang { method public static int compare(boolean, boolean); method public int compareTo(java.lang.Boolean); method public static boolean getBoolean(java.lang.String); + method public static int hashCode(boolean); method public static boolean parseBoolean(java.lang.String); method public static java.lang.String toString(boolean); method public static java.lang.Boolean valueOf(boolean); @@ -50025,6 +50046,7 @@ package java.lang { method public static java.lang.Byte decode(java.lang.String) throws java.lang.NumberFormatException; method public double doubleValue(); method public float floatValue(); + method public static int hashCode(byte); method public int intValue(); method public long longValue(); method public static byte parseByte(java.lang.String, int) throws java.lang.NumberFormatException; @@ -50033,6 +50055,7 @@ package java.lang { method public static java.lang.Byte valueOf(byte); method public static java.lang.Byte valueOf(java.lang.String, int) throws java.lang.NumberFormatException; method public static java.lang.Byte valueOf(java.lang.String) throws java.lang.NumberFormatException; + field public static final int BYTES = 1; // 0x1 field public static final byte MAX_VALUE = 127; // 0x7f field public static final byte MIN_VALUE = -128; // 0xffffff80 field public static final int SIZE = 8; // 0x8 @@ -50070,6 +50093,7 @@ package java.lang { method public static int getNumericValue(int); method public static int getType(char); method public static int getType(int); + method public static int hashCode(char); method public static char highSurrogate(int); method public static boolean isAlphabetic(int); method public static boolean isBmpCodePoint(int); @@ -50130,6 +50154,7 @@ package java.lang { method public static char toUpperCase(char); method public static int toUpperCase(int); method public static java.lang.Character valueOf(char); + field public static final int BYTES = 2; // 0x2 field public static final byte COMBINING_SPACING_MARK = 8; // 0x8 field public static final byte CONNECTOR_PUNCTUATION = 23; // 0x17 field public static final byte CONTROL = 15; // 0xf @@ -50756,6 +50781,7 @@ package java.lang { method public static int floatToIntBits(float); method public static int floatToRawIntBits(float); method public float floatValue(); + method public static int hashCode(float); method public static float intBitsToFloat(int); method public int intValue(); method public static boolean isFinite(float); @@ -50764,11 +50790,15 @@ package java.lang { method public static boolean isNaN(float); method public boolean isNaN(); method public long longValue(); + method public static float max(float, float); + method public static float min(float, float); method public static float parseFloat(java.lang.String) throws java.lang.NumberFormatException; + method public static float sum(float, float); method public static java.lang.String toHexString(float); method public static java.lang.String toString(float); method public static java.lang.Float valueOf(java.lang.String) throws java.lang.NumberFormatException; method public static java.lang.Float valueOf(float); + field public static final int BYTES = 4; // 0x4 field public static final int MAX_EXPONENT = 127; // 0x7f field public static final float MAX_VALUE = 3.4028235E38f; field public static final int MIN_EXPONENT = -126; // 0xffffff82 @@ -50948,6 +50978,7 @@ package java.lang { method public static java.lang.Long valueOf(java.lang.String, int) throws java.lang.NumberFormatException; method public static java.lang.Long valueOf(java.lang.String) throws java.lang.NumberFormatException; method public static java.lang.Long valueOf(long); + field public static final int BYTES = 8; // 0x8 field public static final long MAX_VALUE = 9223372036854775807L; // 0x7fffffffffffffffL field public static final long MIN_VALUE = -9223372036854775808L; // 0x8000000000000000L field public static final int SIZE = 64; // 0x40 @@ -51251,6 +51282,7 @@ package java.lang { method public static java.lang.Short decode(java.lang.String) throws java.lang.NumberFormatException; method public double doubleValue(); method public float floatValue(); + method public static int hashCode(short); method public int intValue(); method public long longValue(); method public static short parseShort(java.lang.String, int) throws java.lang.NumberFormatException; @@ -51260,6 +51292,7 @@ package java.lang { method public static java.lang.Short valueOf(java.lang.String, int) throws java.lang.NumberFormatException; method public static java.lang.Short valueOf(java.lang.String) throws java.lang.NumberFormatException; method public static java.lang.Short valueOf(short); + field public static final int BYTES = 2; // 0x2 field public static final short MAX_VALUE = 32767; // 0x7fff field public static final short MIN_VALUE = -32768; // 0xffff8000 field public static final int SIZE = 16; // 0x10 diff --git a/api/system-current.txt b/api/system-current.txt index fe562bb9014f..e73287ea82f0 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -2588,6 +2588,7 @@ package android { field public static final int Widget_Material_CompoundButton_CheckBox = 16974435; // 0x1030263 field public static final int Widget_Material_CompoundButton_RadioButton = 16974436; // 0x1030264 field public static final int Widget_Material_CompoundButton_Star = 16974437; // 0x1030265 + field public static final int Widget_Material_CompoundButton_Switch = 16974554; // 0x10302da field public static final int Widget_Material_DatePicker = 16974438; // 0x1030266 field public static final int Widget_Material_DropDownItem = 16974439; // 0x1030267 field public static final int Widget_Material_DropDownItem_Spinner = 16974440; // 0x1030268 @@ -2622,6 +2623,7 @@ package android { field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974500; // 0x10302a4 field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974501; // 0x10302a5 field public static final int Widget_Material_Light_CompoundButton_Star = 16974502; // 0x10302a6 + field public static final int Widget_Material_Light_CompoundButton_Switch = 16974555; // 0x10302db field public static final int Widget_Material_Light_DatePicker = 16974503; // 0x10302a7 field public static final int Widget_Material_Light_DropDownItem = 16974504; // 0x10302a8 field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974505; // 0x10302a9 @@ -5110,7 +5112,7 @@ package android.app { field public int ledARGB; field public int ledOffMS; field public int ledOnMS; - field public int number; + field public deprecated int number; field public int priority; field public android.app.Notification publicVersion; field public android.net.Uri sound; @@ -5157,11 +5159,13 @@ package android.app { method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Builder); method public java.lang.CharSequence getCancelLabel(); method public java.lang.CharSequence getConfirmLabel(); + method public boolean getHintContentIntentLaunchesActivity(); method public java.lang.CharSequence getInProgressLabel(); method public boolean isAvailableOffline(); method public android.app.Notification.Action.WearableExtender setAvailableOffline(boolean); method public android.app.Notification.Action.WearableExtender setCancelLabel(java.lang.CharSequence); method public android.app.Notification.Action.WearableExtender setConfirmLabel(java.lang.CharSequence); + method public android.app.Notification.Action.WearableExtender setHintContentIntentLaunchesActivity(boolean); method public android.app.Notification.Action.WearableExtender setInProgressLabel(java.lang.CharSequence); } @@ -5203,7 +5207,7 @@ package android.app { method public android.app.Notification.Builder setChronometerCountsDown(boolean); method public android.app.Notification.Builder setColor(int); method public deprecated android.app.Notification.Builder setContent(android.widget.RemoteViews); - method public android.app.Notification.Builder setContentInfo(java.lang.CharSequence); + method public deprecated android.app.Notification.Builder setContentInfo(java.lang.CharSequence); method public android.app.Notification.Builder setContentIntent(android.app.PendingIntent); method public android.app.Notification.Builder setContentText(java.lang.CharSequence); method public android.app.Notification.Builder setContentTitle(java.lang.CharSequence); @@ -5220,7 +5224,7 @@ package android.app { method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon); method public android.app.Notification.Builder setLights(int, int, int); method public android.app.Notification.Builder setLocalOnly(boolean); - method public android.app.Notification.Builder setNumber(int); + method public deprecated android.app.Notification.Builder setNumber(int); method public android.app.Notification.Builder setOngoing(boolean); method public android.app.Notification.Builder setOnlyAlertOnce(boolean); method public android.app.Notification.Builder setPriority(int); @@ -5338,6 +5342,7 @@ package android.app { method public android.app.PendingIntent getDisplayIntent(); method public int getGravity(); method public boolean getHintAvoidBackgroundClipping(); + method public boolean getHintContentIntentLaunchesActivity(); method public boolean getHintHideIcon(); method public int getHintScreenTimeout(); method public boolean getHintShowBackgroundOnly(); @@ -5353,6 +5358,7 @@ package android.app { method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent); method public android.app.Notification.WearableExtender setGravity(int); method public android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean); + method public android.app.Notification.WearableExtender setHintContentIntentLaunchesActivity(boolean); method public android.app.Notification.WearableExtender setHintHideIcon(boolean); method public android.app.Notification.WearableExtender setHintScreenTimeout(int); method public android.app.Notification.WearableExtender setHintShowBackgroundOnly(boolean); @@ -6068,7 +6074,7 @@ package android.app.admin { method public java.util.List<android.app.admin.SecurityLog.SecurityEvent> retrieveSecurityLogs(android.content.ComponentName); method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean); method public deprecated boolean setActiveProfileOwner(android.content.ComponentName, java.lang.String) throws java.lang.IllegalArgumentException; - method public boolean setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String); + method public void setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException, java.lang.UnsupportedOperationException; method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean); method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle); method public void setApplicationRestrictionsManagingPackage(android.content.ComponentName, java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; @@ -8181,6 +8187,7 @@ package android.content { method public static boolean isSyncPending(android.accounts.Account, java.lang.String); method public void notifyChange(android.net.Uri, android.database.ContentObserver); method public void notifyChange(android.net.Uri, android.database.ContentObserver, boolean); + method public void notifyChange(android.net.Uri, android.database.ContentObserver, int); method public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException; method public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException; method public final android.os.ParcelFileDescriptor openFileDescriptor(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException; @@ -8211,6 +8218,8 @@ package android.content { field public static final java.lang.String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; field public static final java.lang.String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; field public static final java.lang.String EXTRA_SIZE = "android.content.extra.SIZE"; + field public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 2; // 0x2 + field public static final int NOTIFY_SYNC_TO_NETWORK = 1; // 0x1 field public static final java.lang.String SCHEME_ANDROID_RESOURCE = "android.resource"; field public static final java.lang.String SCHEME_CONTENT = "content"; field public static final java.lang.String SCHEME_FILE = "file"; @@ -8837,8 +8846,9 @@ package android.content { field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED"; field public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN"; field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED"; - field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED"; + field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABLE = "android.intent.action.MANAGED_PROFILE_AVAILABLE"; field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED"; + field public static final java.lang.String ACTION_MANAGED_PROFILE_UNAVAILABLE = "android.intent.action.MANAGED_PROFILE_UNAVAILABLE"; field public static final java.lang.String ACTION_MANAGED_PROFILE_UNLOCKED = "android.intent.action.MANAGED_PROFILE_UNLOCKED"; field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE"; field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE"; @@ -21549,7 +21559,6 @@ package android.media { } public abstract class DrmInitData { - ctor public DrmInitData(); method public abstract android.media.DrmInitData.SchemeInitData get(java.util.UUID); } @@ -21804,8 +21813,8 @@ package android.media { public class MediaActionSound { ctor public MediaActionSound(); - method public synchronized void load(int); - method public synchronized void play(int); + method public void load(int); + method public void play(int); method public void release(); field public static final int FOCUS_COMPLETE = 1; // 0x1 field public static final int SHUTTER_CLICK = 0; // 0x0 @@ -25185,6 +25194,7 @@ package android.net { method public boolean isDefaultNetworkActive(); method public static deprecated boolean isNetworkTypeValid(int); method public boolean isTetheringSupported(); + method public void registerDefaultNetworkCallback(android.net.ConnectivityManager.NetworkCallback); method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback); method public void registerNetworkCallback(android.net.NetworkRequest, android.app.PendingIntent); method public void releaseNetworkRequest(android.app.PendingIntent); @@ -31307,6 +31317,7 @@ package android.os { method public boolean isPowerSaveMode(); method public boolean isScreenBrightnessBoosted(); method public deprecated boolean isScreenOn(); + method public boolean isSustainedPerformanceModeSupported(); method public boolean isWakeLockLevelSupported(int); method public android.os.PowerManager.WakeLock newWakeLock(int, java.lang.String); method public void reboot(java.lang.String); @@ -32004,7 +32015,6 @@ package android.preference { method protected void onClick(); method protected android.view.View onCreateView(android.view.ViewGroup); method public void onDependencyChanged(android.preference.Preference, boolean); - method protected void onDetachedFromActivity(); method protected java.lang.Object onGetDefaultValue(android.content.res.TypedArray, int); method public void onParentChanged(android.preference.Preference, boolean); method protected void onPrepareForRemoval(); @@ -39287,7 +39297,6 @@ package android.telecom { method public boolean isRinging(); method public boolean isTtySupported(); method public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, java.lang.String); - method public deprecated void launchManageBlockedNumbersActivity(); method public void placeCall(android.net.Uri, android.os.Bundle); method public void registerPhoneAccount(android.telecom.PhoneAccount); method public void showInCallScreen(boolean); @@ -40002,7 +40011,8 @@ package android.telephony { method public java.lang.String getDeviceSoftwareVersion(); method public java.lang.String getGroupIdLevel1(); method public java.lang.String getGroupIdLevel1(int); - method public java.lang.String getIccSimChallengeResponse(int, java.lang.String); + method public java.lang.String getIccAuthentication(int, int, java.lang.String); + method public java.lang.String getIccAuthentication(int, int, int, java.lang.String); method public java.lang.String getLine1AlphaTag(int); method public java.lang.String getLine1Number(); method public java.lang.String getLine1Number(int); @@ -40092,6 +40102,13 @@ package android.telephony { field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE"; field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE"; field public static final java.lang.String ACTION_SHOW_VOICEMAIL_NOTIFICATION = "android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION"; + field public static final int APPTYPE_CSIM = 4; // 0x4 + field public static final int APPTYPE_ISIM = 5; // 0x5 + field public static final int APPTYPE_RUIM = 3; // 0x3 + field public static final int APPTYPE_SIM = 1; // 0x1 + field public static final int APPTYPE_USIM = 2; // 0x2 + field public static final int AUTHTYPE_EAP_AKA = 129; // 0x81 + field public static final int AUTHTYPE_EAP_SIM = 128; // 0x80 field public static final int CALL_STATE_IDLE = 0; // 0x0 field public static final int CALL_STATE_OFFHOOK = 2; // 0x2 field public static final int CALL_STATE_RINGING = 1; // 0x1 @@ -45013,6 +45030,7 @@ package android.view { method public boolean dispatchDragEvent(android.view.DragEvent); method protected void dispatchDraw(android.graphics.Canvas); method public void dispatchDrawableHotspotChanged(float, float); + method public void dispatchFinishTemporaryDetach(); method protected boolean dispatchGenericFocusedEvent(android.view.MotionEvent); method public boolean dispatchGenericMotionEvent(android.view.MotionEvent); method protected boolean dispatchGenericPointerEvent(android.view.MotionEvent); @@ -45032,6 +45050,7 @@ package android.view { method protected void dispatchSetActivated(boolean); method protected void dispatchSetPressed(boolean); method protected void dispatchSetSelected(boolean); + method public void dispatchStartTemporaryDetach(); method public void dispatchSystemUiVisibilityChanged(int); method public boolean dispatchTouchEvent(android.view.MotionEvent); method public boolean dispatchTrackballEvent(android.view.MotionEvent); @@ -45244,6 +45263,7 @@ package android.view { method public boolean isSelected(); method public boolean isShown(); method public boolean isSoundEffectsEnabled(); + method public final boolean isTemporarilyDetached(); method public boolean isTextAlignmentResolved(); method public boolean isTextDirectionResolved(); method public boolean isVerticalFadingEdgeEnabled(); @@ -46831,8 +46851,6 @@ package android.view.accessibility { method public void setVisibleToUser(boolean); method public void writeToParcel(android.os.Parcel, int); field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40 - field public static final java.lang.String ACTION_ARGUMENT_CLICK_CHARACTER_INDEX_INT = "android.view.accessibility.action.ARGUMENT_CLICK_CHARACTER_INDEX_INT"; - field public static final java.lang.String ACTION_ARGUMENT_CLICK_SPAN_INDEX_INT = "android.view.accessibility.action.ARGUMENT_CLICK_SPAN_INDEX_INT"; field public static final java.lang.String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT"; field public static final java.lang.String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN"; field public static final java.lang.String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING"; @@ -47003,6 +47021,7 @@ package android.view.accessibility { public final class AccessibilityWindowInfo implements android.os.Parcelable { method public int describeContents(); + method public android.view.accessibility.AccessibilityNodeInfo getAnchor(); method public void getBoundsInScreen(android.graphics.Rect); method public android.view.accessibility.AccessibilityWindowInfo getChild(int); method public int getChildCount(); @@ -47010,6 +47029,7 @@ package android.view.accessibility { method public int getLayer(); method public android.view.accessibility.AccessibilityWindowInfo getParent(); method public android.view.accessibility.AccessibilityNodeInfo getRoot(); + method public java.lang.CharSequence getTitle(); method public int getType(); method public boolean isAccessibilityFocused(); method public boolean isActive(); @@ -48645,6 +48665,7 @@ package android.webkit { method public int getPackageId(android.content.res.Resources, java.lang.String); method public void invokeDrawGlFunctor(android.view.View, long, boolean); method public boolean isTraceTagEnabled(); + method public java.lang.Runnable setDrawGlFunctionDetachedCallback(android.view.View, java.lang.Runnable); method public void setOnTraceEnabledChangeListener(android.webkit.WebViewDelegate.OnTraceEnabledChangeListener); } @@ -49354,7 +49375,7 @@ package android.widget { method public long getMinDate(); method public deprecated android.graphics.drawable.Drawable getSelectedDateVerticalBar(); method public deprecated int getSelectedWeekBackgroundColor(); - method public boolean getShowWeekNumber(); + method public deprecated boolean getShowWeekNumber(); method public deprecated int getShownWeekCount(); method public deprecated int getUnfocusedMonthDateColor(); method public int getWeekDayTextAppearance(); @@ -49371,7 +49392,7 @@ package android.widget { method public deprecated void setSelectedDateVerticalBar(int); method public deprecated void setSelectedDateVerticalBar(android.graphics.drawable.Drawable); method public deprecated void setSelectedWeekBackgroundColor(int); - method public void setShowWeekNumber(boolean); + method public deprecated void setShowWeekNumber(boolean); method public deprecated void setShownWeekCount(int); method public deprecated void setUnfocusedMonthDateColor(int); method public void setWeekDayTextAppearance(int); @@ -49518,21 +49539,21 @@ package android.widget { ctor public DatePicker(android.content.Context, android.util.AttributeSet); ctor public DatePicker(android.content.Context, android.util.AttributeSet, int); ctor public DatePicker(android.content.Context, android.util.AttributeSet, int, int); - method public android.widget.CalendarView getCalendarView(); - method public boolean getCalendarViewShown(); + method public deprecated android.widget.CalendarView getCalendarView(); + method public deprecated boolean getCalendarViewShown(); method public int getDayOfMonth(); method public int getFirstDayOfWeek(); method public long getMaxDate(); method public long getMinDate(); method public int getMonth(); - method public boolean getSpinnersShown(); + method public deprecated boolean getSpinnersShown(); method public int getYear(); method public void init(int, int, int, android.widget.DatePicker.OnDateChangedListener); - method public void setCalendarViewShown(boolean); + method public deprecated void setCalendarViewShown(boolean); method public void setFirstDayOfWeek(int); method public void setMaxDate(long); method public void setMinDate(long); - method public void setSpinnersShown(boolean); + method public deprecated void setSpinnersShown(boolean); method public void updateDate(int, int, int); } @@ -53104,6 +53125,7 @@ package java.lang { method public static int compare(boolean, boolean); method public int compareTo(java.lang.Boolean); method public static boolean getBoolean(java.lang.String); + method public static int hashCode(boolean); method public static boolean parseBoolean(java.lang.String); method public static java.lang.String toString(boolean); method public static java.lang.Boolean valueOf(boolean); @@ -53121,6 +53143,7 @@ package java.lang { method public static java.lang.Byte decode(java.lang.String) throws java.lang.NumberFormatException; method public double doubleValue(); method public float floatValue(); + method public static int hashCode(byte); method public int intValue(); method public long longValue(); method public static byte parseByte(java.lang.String, int) throws java.lang.NumberFormatException; @@ -53129,6 +53152,7 @@ package java.lang { method public static java.lang.Byte valueOf(byte); method public static java.lang.Byte valueOf(java.lang.String, int) throws java.lang.NumberFormatException; method public static java.lang.Byte valueOf(java.lang.String) throws java.lang.NumberFormatException; + field public static final int BYTES = 1; // 0x1 field public static final byte MAX_VALUE = 127; // 0x7f field public static final byte MIN_VALUE = -128; // 0xffffff80 field public static final int SIZE = 8; // 0x8 @@ -53166,6 +53190,7 @@ package java.lang { method public static int getNumericValue(int); method public static int getType(char); method public static int getType(int); + method public static int hashCode(char); method public static char highSurrogate(int); method public static boolean isAlphabetic(int); method public static boolean isBmpCodePoint(int); @@ -53226,6 +53251,7 @@ package java.lang { method public static char toUpperCase(char); method public static int toUpperCase(int); method public static java.lang.Character valueOf(char); + field public static final int BYTES = 2; // 0x2 field public static final byte COMBINING_SPACING_MARK = 8; // 0x8 field public static final byte CONNECTOR_PUNCTUATION = 23; // 0x17 field public static final byte CONTROL = 15; // 0xf @@ -53852,6 +53878,7 @@ package java.lang { method public static int floatToIntBits(float); method public static int floatToRawIntBits(float); method public float floatValue(); + method public static int hashCode(float); method public static float intBitsToFloat(int); method public int intValue(); method public static boolean isFinite(float); @@ -53860,11 +53887,15 @@ package java.lang { method public static boolean isNaN(float); method public boolean isNaN(); method public long longValue(); + method public static float max(float, float); + method public static float min(float, float); method public static float parseFloat(java.lang.String) throws java.lang.NumberFormatException; + method public static float sum(float, float); method public static java.lang.String toHexString(float); method public static java.lang.String toString(float); method public static java.lang.Float valueOf(java.lang.String) throws java.lang.NumberFormatException; method public static java.lang.Float valueOf(float); + field public static final int BYTES = 4; // 0x4 field public static final int MAX_EXPONENT = 127; // 0x7f field public static final float MAX_VALUE = 3.4028235E38f; field public static final int MIN_EXPONENT = -126; // 0xffffff82 @@ -54044,6 +54075,7 @@ package java.lang { method public static java.lang.Long valueOf(java.lang.String, int) throws java.lang.NumberFormatException; method public static java.lang.Long valueOf(java.lang.String) throws java.lang.NumberFormatException; method public static java.lang.Long valueOf(long); + field public static final int BYTES = 8; // 0x8 field public static final long MAX_VALUE = 9223372036854775807L; // 0x7fffffffffffffffL field public static final long MIN_VALUE = -9223372036854775808L; // 0x8000000000000000L field public static final int SIZE = 64; // 0x40 @@ -54347,6 +54379,7 @@ package java.lang { method public static java.lang.Short decode(java.lang.String) throws java.lang.NumberFormatException; method public double doubleValue(); method public float floatValue(); + method public static int hashCode(short); method public int intValue(); method public long longValue(); method public static short parseShort(java.lang.String, int) throws java.lang.NumberFormatException; @@ -54356,6 +54389,7 @@ package java.lang { method public static java.lang.Short valueOf(java.lang.String, int) throws java.lang.NumberFormatException; method public static java.lang.Short valueOf(java.lang.String) throws java.lang.NumberFormatException; method public static java.lang.Short valueOf(short); + field public static final int BYTES = 2; // 0x2 field public static final short MAX_VALUE = 32767; // 0x7fff field public static final short MIN_VALUE = -32768; // 0xffff8000 field public static final int SIZE = 16; // 0x10 diff --git a/api/test-current.txt b/api/test-current.txt index 09c55b927c60..a4408be22859 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -2485,6 +2485,7 @@ package android { field public static final int Widget_Material_CompoundButton_CheckBox = 16974435; // 0x1030263 field public static final int Widget_Material_CompoundButton_RadioButton = 16974436; // 0x1030264 field public static final int Widget_Material_CompoundButton_Star = 16974437; // 0x1030265 + field public static final int Widget_Material_CompoundButton_Switch = 16974554; // 0x10302da field public static final int Widget_Material_DatePicker = 16974438; // 0x1030266 field public static final int Widget_Material_DropDownItem = 16974439; // 0x1030267 field public static final int Widget_Material_DropDownItem_Spinner = 16974440; // 0x1030268 @@ -2519,6 +2520,7 @@ package android { field public static final int Widget_Material_Light_CompoundButton_CheckBox = 16974500; // 0x10302a4 field public static final int Widget_Material_Light_CompoundButton_RadioButton = 16974501; // 0x10302a5 field public static final int Widget_Material_Light_CompoundButton_Star = 16974502; // 0x10302a6 + field public static final int Widget_Material_Light_CompoundButton_Switch = 16974555; // 0x10302db field public static final int Widget_Material_Light_DatePicker = 16974503; // 0x10302a7 field public static final int Widget_Material_Light_DropDownItem = 16974504; // 0x10302a8 field public static final int Widget_Material_Light_DropDownItem_Spinner = 16974505; // 0x10302a9 @@ -4977,7 +4979,7 @@ package android.app { field public int ledARGB; field public int ledOffMS; field public int ledOnMS; - field public int number; + field public deprecated int number; field public int priority; field public android.app.Notification publicVersion; field public android.net.Uri sound; @@ -5024,11 +5026,13 @@ package android.app { method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Builder); method public java.lang.CharSequence getCancelLabel(); method public java.lang.CharSequence getConfirmLabel(); + method public boolean getHintContentIntentLaunchesActivity(); method public java.lang.CharSequence getInProgressLabel(); method public boolean isAvailableOffline(); method public android.app.Notification.Action.WearableExtender setAvailableOffline(boolean); method public android.app.Notification.Action.WearableExtender setCancelLabel(java.lang.CharSequence); method public android.app.Notification.Action.WearableExtender setConfirmLabel(java.lang.CharSequence); + method public android.app.Notification.Action.WearableExtender setHintContentIntentLaunchesActivity(boolean); method public android.app.Notification.Action.WearableExtender setInProgressLabel(java.lang.CharSequence); } @@ -5070,7 +5074,7 @@ package android.app { method public android.app.Notification.Builder setChronometerCountsDown(boolean); method public android.app.Notification.Builder setColor(int); method public deprecated android.app.Notification.Builder setContent(android.widget.RemoteViews); - method public android.app.Notification.Builder setContentInfo(java.lang.CharSequence); + method public deprecated android.app.Notification.Builder setContentInfo(java.lang.CharSequence); method public android.app.Notification.Builder setContentIntent(android.app.PendingIntent); method public android.app.Notification.Builder setContentText(java.lang.CharSequence); method public android.app.Notification.Builder setContentTitle(java.lang.CharSequence); @@ -5087,7 +5091,7 @@ package android.app { method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon); method public android.app.Notification.Builder setLights(int, int, int); method public android.app.Notification.Builder setLocalOnly(boolean); - method public android.app.Notification.Builder setNumber(int); + method public deprecated android.app.Notification.Builder setNumber(int); method public android.app.Notification.Builder setOngoing(boolean); method public android.app.Notification.Builder setOnlyAlertOnce(boolean); method public android.app.Notification.Builder setPriority(int); @@ -5205,6 +5209,7 @@ package android.app { method public android.app.PendingIntent getDisplayIntent(); method public int getGravity(); method public boolean getHintAvoidBackgroundClipping(); + method public boolean getHintContentIntentLaunchesActivity(); method public boolean getHintHideIcon(); method public int getHintScreenTimeout(); method public boolean getHintShowBackgroundOnly(); @@ -5220,6 +5225,7 @@ package android.app { method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent); method public android.app.Notification.WearableExtender setGravity(int); method public android.app.Notification.WearableExtender setHintAvoidBackgroundClipping(boolean); + method public android.app.Notification.WearableExtender setHintContentIntentLaunchesActivity(boolean); method public android.app.Notification.WearableExtender setHintHideIcon(boolean); method public android.app.Notification.WearableExtender setHintScreenTimeout(int); method public android.app.Notification.WearableExtender setHintShowBackgroundOnly(boolean); @@ -5923,7 +5929,7 @@ package android.app.admin { method public java.util.List<android.app.admin.SecurityLog.SecurityEvent> retrievePreRebootSecurityLogs(android.content.ComponentName); method public java.util.List<android.app.admin.SecurityLog.SecurityEvent> retrieveSecurityLogs(android.content.ComponentName); method public void setAccountManagementDisabled(android.content.ComponentName, java.lang.String, boolean); - method public boolean setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String); + method public void setAlwaysOnVpnPackage(android.content.ComponentName, java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException, java.lang.UnsupportedOperationException; method public boolean setApplicationHidden(android.content.ComponentName, java.lang.String, boolean); method public void setApplicationRestrictions(android.content.ComponentName, java.lang.String, android.os.Bundle); method public void setApplicationRestrictionsManagingPackage(android.content.ComponentName, java.lang.String) throws android.content.pm.PackageManager.NameNotFoundException; @@ -7888,6 +7894,7 @@ package android.content { method public static boolean isSyncPending(android.accounts.Account, java.lang.String); method public void notifyChange(android.net.Uri, android.database.ContentObserver); method public void notifyChange(android.net.Uri, android.database.ContentObserver, boolean); + method public void notifyChange(android.net.Uri, android.database.ContentObserver, int); method public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException; method public final android.content.res.AssetFileDescriptor openAssetFileDescriptor(android.net.Uri, java.lang.String, android.os.CancellationSignal) throws java.io.FileNotFoundException; method public final android.os.ParcelFileDescriptor openFileDescriptor(android.net.Uri, java.lang.String) throws java.io.FileNotFoundException; @@ -7918,6 +7925,8 @@ package android.content { field public static final java.lang.String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir"; field public static final java.lang.String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item"; field public static final java.lang.String EXTRA_SIZE = "android.content.extra.SIZE"; + field public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 2; // 0x2 + field public static final int NOTIFY_SYNC_TO_NETWORK = 1; // 0x1 field public static final java.lang.String SCHEME_ANDROID_RESOURCE = "android.resource"; field public static final java.lang.String SCHEME_CONTENT = "content"; field public static final java.lang.String SCHEME_FILE = "file"; @@ -8528,8 +8537,9 @@ package android.content { field public static final java.lang.String ACTION_LOCKED_BOOT_COMPLETED = "android.intent.action.LOCKED_BOOT_COMPLETED"; field public static final java.lang.String ACTION_MAIN = "android.intent.action.MAIN"; field public static final java.lang.String ACTION_MANAGED_PROFILE_ADDED = "android.intent.action.MANAGED_PROFILE_ADDED"; - field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED"; + field public static final java.lang.String ACTION_MANAGED_PROFILE_AVAILABLE = "android.intent.action.MANAGED_PROFILE_AVAILABLE"; field public static final java.lang.String ACTION_MANAGED_PROFILE_REMOVED = "android.intent.action.MANAGED_PROFILE_REMOVED"; + field public static final java.lang.String ACTION_MANAGED_PROFILE_UNAVAILABLE = "android.intent.action.MANAGED_PROFILE_UNAVAILABLE"; field public static final java.lang.String ACTION_MANAGED_PROFILE_UNLOCKED = "android.intent.action.MANAGED_PROFILE_UNLOCKED"; field public static final java.lang.String ACTION_MANAGE_NETWORK_USAGE = "android.intent.action.MANAGE_NETWORK_USAGE"; field public static final java.lang.String ACTION_MANAGE_PACKAGE_STORAGE = "android.intent.action.MANAGE_PACKAGE_STORAGE"; @@ -20135,7 +20145,6 @@ package android.media { } public abstract class DrmInitData { - ctor public DrmInitData(); method public abstract android.media.DrmInitData.SchemeInitData get(java.util.UUID); } @@ -20390,8 +20399,8 @@ package android.media { public class MediaActionSound { ctor public MediaActionSound(); - method public synchronized void load(int); - method public synchronized void play(int); + method public void load(int); + method public void play(int); method public void release(); field public static final int FOCUS_COMPLETE = 1; // 0x1 field public static final int SHUTTER_CLICK = 0; // 0x0 @@ -23514,6 +23523,7 @@ package android.net { method public boolean isActiveNetworkMetered(); method public boolean isDefaultNetworkActive(); method public static deprecated boolean isNetworkTypeValid(int); + method public void registerDefaultNetworkCallback(android.net.ConnectivityManager.NetworkCallback); method public void registerNetworkCallback(android.net.NetworkRequest, android.net.ConnectivityManager.NetworkCallback); method public void registerNetworkCallback(android.net.NetworkRequest, android.app.PendingIntent); method public void releaseNetworkRequest(android.app.PendingIntent); @@ -29139,6 +29149,7 @@ package android.os { method public boolean isInteractive(); method public boolean isPowerSaveMode(); method public deprecated boolean isScreenOn(); + method public boolean isSustainedPerformanceModeSupported(); method public boolean isWakeLockLevelSupported(int); method public android.os.PowerManager.WakeLock newWakeLock(int, java.lang.String); method public void reboot(java.lang.String); @@ -29766,7 +29777,6 @@ package android.preference { method protected void onClick(); method protected android.view.View onCreateView(android.view.ViewGroup); method public void onDependencyChanged(android.preference.Preference, boolean); - method protected void onDetachedFromActivity(); method protected java.lang.Object onGetDefaultValue(android.content.res.TypedArray, int); method public void onParentChanged(android.preference.Preference, boolean); method protected void onPrepareForRemoval(); @@ -36690,7 +36700,6 @@ package android.telecom { method public boolean handleMmi(java.lang.String, android.telecom.PhoneAccountHandle); method public boolean isInCall(); method public boolean isVoiceMailNumber(android.telecom.PhoneAccountHandle, java.lang.String); - method public deprecated void launchManageBlockedNumbersActivity(); method public void placeCall(android.net.Uri, android.os.Bundle); method public void registerPhoneAccount(android.telecom.PhoneAccount); method public void showInCallScreen(boolean); @@ -37379,7 +37388,8 @@ package android.telephony { method public java.lang.String getDeviceSoftwareVersion(); method public java.lang.String getGroupIdLevel1(); method public java.lang.String getGroupIdLevel1(int); - method public java.lang.String getIccSimChallengeResponse(int, java.lang.String); + method public java.lang.String getIccAuthentication(int, int, java.lang.String); + method public java.lang.String getIccAuthentication(int, int, int, java.lang.String); method public java.lang.String getLine1AlphaTag(int); method public java.lang.String getLine1Number(); method public java.lang.String getLine1Number(int); @@ -37448,6 +37458,13 @@ package android.telephony { field public static final java.lang.String ACTION_CONFIGURE_VOICEMAIL = "android.telephony.action.CONFIGURE_VOICEMAIL"; field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE"; field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE"; + field public static final int APPTYPE_CSIM = 4; // 0x4 + field public static final int APPTYPE_ISIM = 5; // 0x5 + field public static final int APPTYPE_RUIM = 3; // 0x3 + field public static final int APPTYPE_SIM = 1; // 0x1 + field public static final int APPTYPE_USIM = 2; // 0x2 + field public static final int AUTHTYPE_EAP_AKA = 129; // 0x81 + field public static final int AUTHTYPE_EAP_SIM = 128; // 0x80 field public static final int CALL_STATE_IDLE = 0; // 0x0 field public static final int CALL_STATE_OFFHOOK = 2; // 0x2 field public static final int CALL_STATE_RINGING = 1; // 0x1 @@ -42347,6 +42364,7 @@ package android.view { method public boolean dispatchDragEvent(android.view.DragEvent); method protected void dispatchDraw(android.graphics.Canvas); method public void dispatchDrawableHotspotChanged(float, float); + method public void dispatchFinishTemporaryDetach(); method protected boolean dispatchGenericFocusedEvent(android.view.MotionEvent); method public boolean dispatchGenericMotionEvent(android.view.MotionEvent); method protected boolean dispatchGenericPointerEvent(android.view.MotionEvent); @@ -42366,6 +42384,7 @@ package android.view { method protected void dispatchSetActivated(boolean); method protected void dispatchSetPressed(boolean); method protected void dispatchSetSelected(boolean); + method public void dispatchStartTemporaryDetach(); method public void dispatchSystemUiVisibilityChanged(int); method public boolean dispatchTouchEvent(android.view.MotionEvent); method public boolean dispatchTrackballEvent(android.view.MotionEvent); @@ -42578,6 +42597,7 @@ package android.view { method public boolean isSelected(); method public boolean isShown(); method public boolean isSoundEffectsEnabled(); + method public final boolean isTemporarilyDetached(); method public boolean isTextAlignmentResolved(); method public boolean isTextDirectionResolved(); method public boolean isVerticalFadingEdgeEnabled(); @@ -44162,8 +44182,6 @@ package android.view.accessibility { method public void setVisibleToUser(boolean); method public void writeToParcel(android.os.Parcel, int); field public static final int ACTION_ACCESSIBILITY_FOCUS = 64; // 0x40 - field public static final java.lang.String ACTION_ARGUMENT_CLICK_CHARACTER_INDEX_INT = "android.view.accessibility.action.ARGUMENT_CLICK_CHARACTER_INDEX_INT"; - field public static final java.lang.String ACTION_ARGUMENT_CLICK_SPAN_INDEX_INT = "android.view.accessibility.action.ARGUMENT_CLICK_SPAN_INDEX_INT"; field public static final java.lang.String ACTION_ARGUMENT_COLUMN_INT = "android.view.accessibility.action.ARGUMENT_COLUMN_INT"; field public static final java.lang.String ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN = "ACTION_ARGUMENT_EXTEND_SELECTION_BOOLEAN"; field public static final java.lang.String ACTION_ARGUMENT_HTML_ELEMENT_STRING = "ACTION_ARGUMENT_HTML_ELEMENT_STRING"; @@ -44334,6 +44352,7 @@ package android.view.accessibility { public final class AccessibilityWindowInfo implements android.os.Parcelable { method public int describeContents(); + method public android.view.accessibility.AccessibilityNodeInfo getAnchor(); method public void getBoundsInScreen(android.graphics.Rect); method public android.view.accessibility.AccessibilityWindowInfo getChild(int); method public int getChildCount(); @@ -44341,6 +44360,7 @@ package android.view.accessibility { method public int getLayer(); method public android.view.accessibility.AccessibilityWindowInfo getParent(); method public android.view.accessibility.AccessibilityNodeInfo getRoot(); + method public java.lang.CharSequence getTitle(); method public int getType(); method public boolean isAccessibilityFocused(); method public boolean isActive(); @@ -46332,7 +46352,7 @@ package android.widget { method public long getMinDate(); method public deprecated android.graphics.drawable.Drawable getSelectedDateVerticalBar(); method public deprecated int getSelectedWeekBackgroundColor(); - method public boolean getShowWeekNumber(); + method public deprecated boolean getShowWeekNumber(); method public deprecated int getShownWeekCount(); method public deprecated int getUnfocusedMonthDateColor(); method public int getWeekDayTextAppearance(); @@ -46349,7 +46369,7 @@ package android.widget { method public deprecated void setSelectedDateVerticalBar(int); method public deprecated void setSelectedDateVerticalBar(android.graphics.drawable.Drawable); method public deprecated void setSelectedWeekBackgroundColor(int); - method public void setShowWeekNumber(boolean); + method public deprecated void setShowWeekNumber(boolean); method public deprecated void setShownWeekCount(int); method public deprecated void setUnfocusedMonthDateColor(int); method public void setWeekDayTextAppearance(int); @@ -46496,21 +46516,21 @@ package android.widget { ctor public DatePicker(android.content.Context, android.util.AttributeSet); ctor public DatePicker(android.content.Context, android.util.AttributeSet, int); ctor public DatePicker(android.content.Context, android.util.AttributeSet, int, int); - method public android.widget.CalendarView getCalendarView(); - method public boolean getCalendarViewShown(); + method public deprecated android.widget.CalendarView getCalendarView(); + method public deprecated boolean getCalendarViewShown(); method public int getDayOfMonth(); method public int getFirstDayOfWeek(); method public long getMaxDate(); method public long getMinDate(); method public int getMonth(); - method public boolean getSpinnersShown(); + method public deprecated boolean getSpinnersShown(); method public int getYear(); method public void init(int, int, int, android.widget.DatePicker.OnDateChangedListener); - method public void setCalendarViewShown(boolean); + method public deprecated void setCalendarViewShown(boolean); method public void setFirstDayOfWeek(int); method public void setMaxDate(long); method public void setMinDate(long); - method public void setSpinnersShown(boolean); + method public deprecated void setSpinnersShown(boolean); method public void updateDate(int, int, int); } @@ -48344,6 +48364,7 @@ package android.widget { method public android.view.Menu getMenu(); method public java.lang.CharSequence getNavigationContentDescription(); method public android.graphics.drawable.Drawable getNavigationIcon(); + method public android.view.View getNavigationView(); method public android.graphics.drawable.Drawable getOverflowIcon(); method public int getPopupTheme(); method public java.lang.CharSequence getSubtitle(); @@ -50082,6 +50103,7 @@ package java.lang { method public static int compare(boolean, boolean); method public int compareTo(java.lang.Boolean); method public static boolean getBoolean(java.lang.String); + method public static int hashCode(boolean); method public static boolean parseBoolean(java.lang.String); method public static java.lang.String toString(boolean); method public static java.lang.Boolean valueOf(boolean); @@ -50099,6 +50121,7 @@ package java.lang { method public static java.lang.Byte decode(java.lang.String) throws java.lang.NumberFormatException; method public double doubleValue(); method public float floatValue(); + method public static int hashCode(byte); method public int intValue(); method public long longValue(); method public static byte parseByte(java.lang.String, int) throws java.lang.NumberFormatException; @@ -50107,6 +50130,7 @@ package java.lang { method public static java.lang.Byte valueOf(byte); method public static java.lang.Byte valueOf(java.lang.String, int) throws java.lang.NumberFormatException; method public static java.lang.Byte valueOf(java.lang.String) throws java.lang.NumberFormatException; + field public static final int BYTES = 1; // 0x1 field public static final byte MAX_VALUE = 127; // 0x7f field public static final byte MIN_VALUE = -128; // 0xffffff80 field public static final int SIZE = 8; // 0x8 @@ -50144,6 +50168,7 @@ package java.lang { method public static int getNumericValue(int); method public static int getType(char); method public static int getType(int); + method public static int hashCode(char); method public static char highSurrogate(int); method public static boolean isAlphabetic(int); method public static boolean isBmpCodePoint(int); @@ -50204,6 +50229,7 @@ package java.lang { method public static char toUpperCase(char); method public static int toUpperCase(int); method public static java.lang.Character valueOf(char); + field public static final int BYTES = 2; // 0x2 field public static final byte COMBINING_SPACING_MARK = 8; // 0x8 field public static final byte CONNECTOR_PUNCTUATION = 23; // 0x17 field public static final byte CONTROL = 15; // 0xf @@ -50830,6 +50856,7 @@ package java.lang { method public static int floatToIntBits(float); method public static int floatToRawIntBits(float); method public float floatValue(); + method public static int hashCode(float); method public static float intBitsToFloat(int); method public int intValue(); method public static boolean isFinite(float); @@ -50838,11 +50865,15 @@ package java.lang { method public static boolean isNaN(float); method public boolean isNaN(); method public long longValue(); + method public static float max(float, float); + method public static float min(float, float); method public static float parseFloat(java.lang.String) throws java.lang.NumberFormatException; + method public static float sum(float, float); method public static java.lang.String toHexString(float); method public static java.lang.String toString(float); method public static java.lang.Float valueOf(java.lang.String) throws java.lang.NumberFormatException; method public static java.lang.Float valueOf(float); + field public static final int BYTES = 4; // 0x4 field public static final int MAX_EXPONENT = 127; // 0x7f field public static final float MAX_VALUE = 3.4028235E38f; field public static final int MIN_EXPONENT = -126; // 0xffffff82 @@ -51022,6 +51053,7 @@ package java.lang { method public static java.lang.Long valueOf(java.lang.String, int) throws java.lang.NumberFormatException; method public static java.lang.Long valueOf(java.lang.String) throws java.lang.NumberFormatException; method public static java.lang.Long valueOf(long); + field public static final int BYTES = 8; // 0x8 field public static final long MAX_VALUE = 9223372036854775807L; // 0x7fffffffffffffffL field public static final long MIN_VALUE = -9223372036854775808L; // 0x8000000000000000L field public static final int SIZE = 64; // 0x40 @@ -51325,6 +51357,7 @@ package java.lang { method public static java.lang.Short decode(java.lang.String) throws java.lang.NumberFormatException; method public double doubleValue(); method public float floatValue(); + method public static int hashCode(short); method public int intValue(); method public long longValue(); method public static short parseShort(java.lang.String, int) throws java.lang.NumberFormatException; @@ -51334,6 +51367,7 @@ package java.lang { method public static java.lang.Short valueOf(java.lang.String, int) throws java.lang.NumberFormatException; method public static java.lang.Short valueOf(java.lang.String) throws java.lang.NumberFormatException; method public static java.lang.Short valueOf(short); + field public static final int BYTES = 2; // 0x2 field public static final short MAX_VALUE = 32767; // 0x7fff field public static final short MIN_VALUE = -32768; // 0xffff8000 field public static final int SIZE = 16; // 0x10 diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 221b2d36fcec..456be02021e0 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -44,6 +44,7 @@ import android.content.Context; import android.content.IIntentReceiver; import android.content.Intent; import android.content.pm.IPackageManager; +import android.content.pm.InstrumentationInfo; import android.content.pm.ParceledListSlice; import android.content.pm.ResolveInfo; import android.content.pm.UserInfo; @@ -96,6 +97,7 @@ public class Am extends BaseCommand { private static final int STACK_BOUNDS_INSET = 10; private IActivityManager mAm; + private IPackageManager mPm; private int mStartFlags = 0; private boolean mWaitOption = false; @@ -224,7 +226,8 @@ public class Am extends BaseCommand { " --receiver-permission <PERMISSION>: Require receiver to hold permission.\n" + "\n" + "am instrument: start an Instrumentation. Typically this target <COMPONENT>\n" + - " is the form <TEST_PACKAGE>/<RUNNER_CLASS>. Options are:\n" + + " is the form <TEST_PACKAGE>/<RUNNER_CLASS> or only <TEST_PACKAGE> if there \n" + + " is only one instrumentation. Options are:\n" + " -r: print raw results (otherwise decode REPORT_KEY_STREAMRESULT). Use with\n" + " [-e perf true] to generate raw output for performance measurements.\n" + " -e <NAME> <VALUE>: set argument <NAME> to <VALUE>. For test runners a\n" + @@ -373,6 +376,12 @@ public class Am extends BaseCommand { throw new AndroidException("Can't connect to activity manager; is the system running?"); } + mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package")); + if (mPm == null) { + System.err.println(NO_SYSTEM_ERROR_CODE); + throw new AndroidException("Can't connect to package manager; is the system running?"); + } + String op = nextArgRequired(); if (op.equals("start")) { @@ -570,13 +579,7 @@ public class Am extends BaseCommand { if (intent.getComponent() != null) { packageName = intent.getComponent().getPackageName(); } else { - IPackageManager pm = IPackageManager.Stub.asInterface( - ServiceManager.getService("package")); - if (pm == null) { - System.err.println("Error: Package manager not running; aborting"); - return; - } - List<ResolveInfo> activities = pm.queryIntentActivities(intent, mimeType, 0, + List<ResolveInfo> activities = mPm.queryIntentActivities(intent, mimeType, 0, mUserId).getList(); if (activities == null || activities.size() <= 0) { System.err.println("Error: Intent does not match any activities: " @@ -813,8 +816,44 @@ public class Am extends BaseCommand { } String cnArg = nextArgRequired(); - ComponentName cn = ComponentName.unflattenFromString(cnArg); - if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg); + + ComponentName cn; + if (cnArg.contains("/")) { + cn = ComponentName.unflattenFromString(cnArg); + if (cn == null) throw new IllegalArgumentException("Bad component name: " + cnArg); + } else { + List<InstrumentationInfo> infos = mPm.queryInstrumentation(null, 0).getList(); + + final int numInfos = infos == null ? 0: infos.size(); + List<ComponentName> cns = new ArrayList<>(); + for (int i = 0; i < numInfos; i++) { + InstrumentationInfo info = infos.get(i); + + ComponentName c = new ComponentName(info.packageName, info.name); + if (cnArg.equals(info.packageName)) { + cns.add(c); + } + } + + if (cns.size() == 0) { + throw new IllegalArgumentException("No instrumentation found for: " + cnArg); + } else if (cns.size() == 1) { + cn = cns.get(0); + } else { + StringBuilder cnsStr = new StringBuilder(); + final int numCns = cns.size(); + for (int i = 0; i < numCns; i++) { + cnsStr.append(cns.get(i).flattenToString()); + cnsStr.append(", "); + } + + // Remove last ", " + cnsStr.setLength(cnsStr.length() - 2); + + throw new IllegalArgumentException("Found multiple instrumentations: " + + cnsStr.toString()); + } + } InstrumentationWatcher watcher = null; UiAutomationConnection connection = null; diff --git a/cmds/sm/src/com/android/commands/sm/Sm.java b/cmds/sm/src/com/android/commands/sm/Sm.java index b208e438f171..0e674c864137 100644 --- a/cmds/sm/src/com/android/commands/sm/Sm.java +++ b/cmds/sm/src/com/android/commands/sm/Sm.java @@ -88,6 +88,8 @@ public final class Sm { runForget(); } else if ("set-emulate-fbe".equals(op)) { runSetEmulateFbe(); + } else if ("get-fbe-mode".equals(op)) { + runGetFbeMode(); } else { throw new IllegalArgumentException(); } @@ -145,6 +147,16 @@ public final class Sm { StorageManager.DEBUG_EMULATE_FBE); } + public void runGetFbeMode() { + if (StorageManager.isFileEncryptedNativeOnly()) { + System.out.println("native"); + } else if (StorageManager.isFileEncryptedEmulatedOnly()) { + System.out.println("emulated"); + } else { + System.out.println("none"); + } + } + public void runPartition() throws RemoteException { final String diskId = nextArg(); final String type = nextArg(); diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java index 4019a56133b4..ee03280578e5 100644 --- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java +++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java @@ -36,11 +36,11 @@ import android.view.View; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; +import com.android.internal.R; + import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import com.android.internal.R; - import java.io.IOException; import java.util.ArrayList; import java.util.Collections; @@ -319,6 +319,9 @@ public class AccessibilityServiceInfo implements Parcelable { */ public static final int FLAG_RETRIEVE_INTERACTIVE_WINDOWS = 0x00000040; + /** {@hide} */ + public static final int FLAG_FORCE_DIRECT_BOOT_AWARE = 0x00010000; + /** * The event types an {@link AccessibilityService} is interested in. * <p> @@ -687,8 +690,9 @@ public class AccessibilityServiceInfo implements Parcelable { } /** {@hide} */ - public boolean isEncryptionAware() { - return mResolveInfo.serviceInfo.directBootAware; + public boolean isDirectBootAware() { + return ((flags & FLAG_FORCE_DIRECT_BOOT_AWARE) != 0) + || mResolveInfo.serviceInfo.directBootAware; } /** diff --git a/core/java/android/accessibilityservice/GestureDescription.java b/core/java/android/accessibilityservice/GestureDescription.java index 7a0c89b75a4a..e18a34de3f91 100644 --- a/core/java/android/accessibilityservice/GestureDescription.java +++ b/core/java/android/accessibilityservice/GestureDescription.java @@ -36,8 +36,7 @@ import java.util.List; * Accessibility services with the * {@link android.R.styleable#AccessibilityService_canPerformGestures} property can dispatch * gestures. This class describes those gestures. Gestures are made up of one or more strokes. - * Gestures are immutable; use the {@code create} methods to get common gesture, or a - * {@code Builder} to create a new one. + * Gestures are immutable once built. * <p> * Spatial dimensions throughout are in screen pixels. Time is measured in milliseconds. */ diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 336218522c77..65d48e609618 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -95,7 +95,7 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM } return sSystemReady; } - static boolean sSystemReady = false; + static volatile boolean sSystemReady = false; static public void broadcastStickyIntent(Intent intent, String permission, int userId) { broadcastStickyIntent(intent, permission, AppOpsManager.OP_NONE, userId); diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 5b94696c1461..14c4fc6451fc 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -91,6 +91,7 @@ import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseIntArray; import android.util.SuperNotCalledException; +import android.view.ContextThemeWrapper; import android.view.Display; import android.view.ThreadedRenderer; import android.view.View; @@ -4632,7 +4633,21 @@ public final class ActivityThread { } if (reportToActivity) { - cb.onConfigurationChanged(newConfig); + Configuration configToReport = newConfig; + + if (cb instanceof ContextThemeWrapper) { + // ContextThemeWrappers may override the configuration for that context. + // We must check and apply any overrides defined. + ContextThemeWrapper contextThemeWrapper = (ContextThemeWrapper) cb; + final Configuration localOverrideConfig = + contextThemeWrapper.getOverrideConfiguration(); + if (localOverrideConfig != null) { + configToReport = new Configuration(newConfig); + configToReport.updateFrom(localOverrideConfig); + } + } + + cb.onConfigurationChanged(configToReport); } if (activity != null) { diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java index 3a51aff37921..1e2cc2662018 100644 --- a/core/java/android/app/BackStackRecord.java +++ b/core/java/android/app/BackStackRecord.java @@ -146,6 +146,10 @@ final class BackStackState implements Parcelable { op.removed.add(r); } } + bse.mEnterAnim = op.enterAnim; + bse.mExitAnim = op.exitAnim; + bse.mPopEnterAnim = op.popEnterAnim; + bse.mPopExitAnim = op.popExitAnim; bse.addOp(op); num++; } diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index c745644adf13..2a04c39f2c5a 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -1033,7 +1033,8 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene * false if it is not. */ public void setUserVisibleHint(boolean isVisibleToUser) { - if (!mUserVisibleHint && isVisibleToUser && mState < STARTED && isAdded()) { + if (!mUserVisibleHint && isVisibleToUser && mState < STARTED + && mFragmentManager != null && isAdded()) { mFragmentManager.performPendingDeferredStart(this); } mUserVisibleHint = isVisibleToUser; diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 8423de882782..2e4a8c6d82e9 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -174,6 +174,9 @@ public class Notification implements Parcelable * <li>Notification of an ongoing countdown timer should be stamped with the timer's end time. * </ul> * + * For apps targeting {@link android.os.Build.VERSION_CODES#N} and above, this time is not shown + * anymore by default and must be opted into by using + * {@link android.app.Notification.Builder#setShowWhen(boolean)} */ public long when; @@ -206,6 +209,8 @@ public class Notification implements Parcelable * {@link Notification.Builder} has displayed the number in the expanded notification view. * * If the number is 0 or negative, it is never shown. + * + * @deprecated this number is not shown anymore */ public int number; @@ -1205,6 +1210,7 @@ public class Notification implements Parcelable // Flags bitwise-ored to mFlags private static final int FLAG_AVAILABLE_OFFLINE = 0x1; + private static final int FLAG_HINT_LAUNCHES_ACTIVITY = 1 << 1; // Default value for flags integer private static final int DEFAULT_FLAGS = FLAG_AVAILABLE_OFFLINE; @@ -1367,6 +1373,30 @@ public class Notification implements Parcelable public CharSequence getCancelLabel() { return mCancelLabel; } + + /** + * Set a hint that this Action will launch an {@link Activity} directly, telling the + * platform that it can generate the appropriate transitions. + * @param hintLaunchesActivity {@code true} if the content intent will launch + * an activity and transitions should be generated, false otherwise. + * @return this object for method chaining + */ + public WearableExtender setHintContentIntentLaunchesActivity( + boolean hintLaunchesActivity) { + setFlag(FLAG_HINT_LAUNCHES_ACTIVITY, hintLaunchesActivity); + return this; + } + + /** + * Get a hint that this Action will launch an {@link Activity} directly, telling the + * platform that it can generate the appropriate transitions + * @return {@code true} if the content intent will launch an activity and transitions + * should be generated, false otherwise. The default value is {@code false} if this was + * never set. + */ + public boolean getHintContentIntentLaunchesActivity() { + return (mFlags & FLAG_HINT_LAUNCHES_ACTIVITY) != 0; + } } } @@ -2133,7 +2163,9 @@ public class Notification implements Parcelable if (toAdopt == null) { mN = new Notification(); - mN.extras.putBoolean(EXTRA_SHOW_WHEN, true); + if (context.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N) { + mN.extras.putBoolean(EXTRA_SHOW_WHEN, true); + } mN.priority = PRIORITY_DEFAULT; mN.visibility = VISIBILITY_PRIVATE; } else { @@ -2183,8 +2215,10 @@ public class Notification implements Parcelable /** * Add a timestamp pertaining to the notification (usually the time the event occurred). - * It will be shown in the notification content view by default; use - * {@link #setShowWhen(boolean) setShowWhen} to control this. + * + * For apps targeting {@link android.os.Build.VERSION_CODES#N} and above, this time is not + * shown anymore by default and must be opted into by using + * {@link android.app.Notification.Builder#setShowWhen(boolean)} * * @see Notification#when */ @@ -2196,6 +2230,8 @@ public class Notification implements Parcelable /** * Control whether the timestamp set with {@link #setWhen(long) setWhen} is shown * in the content view. + * For apps targeting {@link android.os.Build.VERSION_CODES#N} and above, this defaults to + * {@code false}. For earlier apps, the default is {@code true}. */ public Builder setShowWhen(boolean show) { mN.extras.putBoolean(EXTRA_SHOW_WHEN, show); @@ -2304,9 +2340,22 @@ public class Notification implements Parcelable } /** - * Set the third line of text in the platform notification template. - * Don't use if you're also using {@link #setProgress(int, int, boolean)}; they occupy the - * same location in the standard template. + * This provides some additional information that is displayed in the notification. No + * guarantees are given where exactly it is displayed. + * + * <p>This information should only be provided if it provides an essential + * benefit to the understanding of the notification. The more text you provide the + * less readable it becomes. For example, an email client should only provide the account + * name here if more than one email account has been added.</p> + * + * <p>As of {@link android.os.Build.VERSION_CODES#N} this information is displayed in the + * notification header area. + * + * On Android versions before {@link android.os.Build.VERSION_CODES#N} + * this will be shown in the third line of text in the platform notification template. + * You should not be using {@link #setProgress(int, int, boolean)} at the + * same time on those versions; they occupy the same place. + * </p> */ public Builder setSubText(CharSequence text) { mN.extras.putCharSequence(EXTRA_SUB_TEXT, safeCharSequence(text)); @@ -2345,6 +2394,8 @@ public class Notification implements Parcelable * Set the large number at the right-hand side of the notification. This is * equivalent to setContentInfo, although it might show the number in a different * font size for readability. + * + * @deprecated this number is not shown anywhere anymore */ public Builder setNumber(int number) { mN.number = number; @@ -2356,6 +2407,10 @@ public class Notification implements Parcelable * * The platform template will draw this on the last line of the notification, at the far * right (to the right of a smallIcon if it has been placed there). + * + * @deprecated use {@link #setSubText(CharSequence)} instead to set a text in the header. + * For legacy apps targeting a version below {@link android.os.Build.VERSION_CODES#N} this + * field will still show up, but the subtext will take precedence. */ public Builder setContentInfo(CharSequence info) { mN.extras.putCharSequence(EXTRA_INFO_TEXT, safeCharSequence(info)); @@ -3009,10 +3064,8 @@ public class Notification implements Parcelable contentView.setBoolean(R.id.notification_header, "setExpanded", false); contentView.setTextViewText(R.id.app_name_text, null); contentView.setViewVisibility(R.id.chronometer, View.GONE); - contentView.setViewVisibility(R.id.header_sub_text, View.GONE); - contentView.setViewVisibility(R.id.header_content_info, View.GONE); - contentView.setViewVisibility(R.id.sub_text_divider, View.GONE); - contentView.setViewVisibility(R.id.content_info_divider, View.GONE); + contentView.setViewVisibility(R.id.header_text, View.GONE); + contentView.setViewVisibility(R.id.header_text_divider, View.GONE); contentView.setViewVisibility(R.id.time_divider, View.GONE); contentView.setImageViewIcon(R.id.profile_badge, null); contentView.setViewVisibility(R.id.profile_badge, View.GONE); @@ -3112,39 +3165,12 @@ public class Notification implements Parcelable private void bindNotificationHeader(RemoteViews contentView) { bindSmallIcon(contentView); bindHeaderAppName(contentView); - bindHeaderSubText(contentView); - bindContentInfo(contentView); + bindHeaderText(contentView); bindHeaderChronometerAndTime(contentView); bindExpandButton(contentView); bindProfileBadge(contentView); } - private void bindContentInfo(RemoteViews contentView) { - boolean visible = false; - if (mN.extras.getCharSequence(EXTRA_INFO_TEXT) != null) { - contentView.setTextViewText(R.id.header_content_info, - processLegacyText(mN.extras.getCharSequence(EXTRA_INFO_TEXT))); - contentView.setViewVisibility(R.id.header_content_info, View.VISIBLE); - visible = true; - } else if (mN.number > 0) { - final int tooBig = mContext.getResources().getInteger( - R.integer.status_bar_notification_info_maxnum); - if (mN.number > tooBig) { - contentView.setTextViewText(R.id.header_content_info, processLegacyText( - mContext.getResources().getString( - R.string.status_bar_notification_info_overflow))); - } else { - contentView.setTextViewText(R.id.header_content_info, - processLegacyText(String.valueOf(mN.number))); - } - contentView.setViewVisibility(R.id.header_content_info, View.VISIBLE); - visible = true; - } - if (visible) { - contentView.setViewVisibility(R.id.content_info_divider, View.VISIBLE); - } - } - private void bindExpandButton(RemoteViews contentView) { contentView.setDrawableParameters(R.id.expand_button, false, -1, resolveContrastColor(), PorterDuff.Mode.SRC_ATOP, -1); @@ -3169,17 +3195,22 @@ public class Notification implements Parcelable } } - private void bindHeaderSubText(RemoteViews contentView) { - CharSequence subText = mN.extras.getCharSequence(EXTRA_SUB_TEXT); - if (subText == null && mStyle != null && mStyle.mSummaryTextSet + private void bindHeaderText(RemoteViews contentView) { + CharSequence headerText = mN.extras.getCharSequence(EXTRA_SUB_TEXT); + if (headerText == null && mStyle != null && mStyle.mSummaryTextSet && mStyle.hasSummaryInHeader()) { - subText = mStyle.mSummaryText; + headerText = mStyle.mSummaryText; } - if (subText != null) { + if (headerText == null + && mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N + && mN.extras.getCharSequence(EXTRA_INFO_TEXT) != null) { + headerText = mN.extras.getCharSequence(EXTRA_INFO_TEXT); + } + if (headerText != null) { // TODO: Remove the span entirely to only have the string with propper formating. - contentView.setTextViewText(R.id.header_sub_text, processLegacyText(subText)); - contentView.setViewVisibility(R.id.header_sub_text, View.VISIBLE); - contentView.setViewVisibility(R.id.sub_text_divider, View.VISIBLE); + contentView.setTextViewText(R.id.header_text, processLegacyText(headerText)); + contentView.setViewVisibility(R.id.header_text, View.VISIBLE); + contentView.setViewVisibility(R.id.header_text_divider, View.VISIBLE); } } @@ -4863,6 +4894,7 @@ public class Notification implements Parcelable private static final int FLAG_HINT_SHOW_BACKGROUND_ONLY = 1 << 2; private static final int FLAG_START_SCROLL_BOTTOM = 1 << 3; private static final int FLAG_HINT_AVOID_BACKGROUND_CLIPPING = 1 << 4; + private static final int FLAG_HINT_CONTENT_INTENT_LAUNCHES_ACTIVITY = 1 << 6; // Default value for flags integer private static final int DEFAULT_FLAGS = FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE; @@ -5429,6 +5461,29 @@ public class Notification implements Parcelable return mHintScreenTimeout; } + /** + * Set a hint that this notification's content intent will launch an {@link Activity} + * directly, telling the platform that it can generate the appropriate transitions. + * @param hintContentIntentLaunchesActivity {@code true} if the content intent will launch + * an activity and transitions should be generated, false otherwise. + * @return this object for method chaining + */ + public WearableExtender setHintContentIntentLaunchesActivity( + boolean hintContentIntentLaunchesActivity) { + setFlag(FLAG_HINT_CONTENT_INTENT_LAUNCHES_ACTIVITY, hintContentIntentLaunchesActivity); + return this; + } + + /** + * Get a hint that this notification's content intent will launch an {@link Activity} + * directly, telling the platform that it can generate the appropriate transitions + * @return {@code true} if the content intent will launch an activity and transitions should + * be generated, false otherwise. The default value is {@code false} if this was never set. + */ + public boolean getHintContentIntentLaunchesActivity() { + return (mFlags & FLAG_HINT_CONTENT_INTENT_LAUNCHES_ACTIVITY) != 0; + } + private void setFlag(int mask, boolean value) { if (value) { mFlags |= mask; diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 0d4729d8349f..47bff6440332 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -153,25 +153,31 @@ public class NotificationManager /** * {@link #getCurrentInterruptionFilter() Interruption filter} constant - - * Normal interruption filter. + * Normal interruption filter - no notifications are suppressed. */ public static final int INTERRUPTION_FILTER_ALL = 1; /** * {@link #getCurrentInterruptionFilter() Interruption filter} constant - - * Priority interruption filter. + * Priority interruption filter - all notifications are suppressed except those that match + * the priority criteria. Some audio streams are muted. See + * {@link Policy#priorityCallSenders}, {@link Policy#priorityCategories}, + * {@link Policy#priorityMessageSenders} to define or query this criteria. Users can + * additionally specify packages that can bypass this interruption filter. */ public static final int INTERRUPTION_FILTER_PRIORITY = 2; /** * {@link #getCurrentInterruptionFilter() Interruption filter} constant - - * No interruptions filter. + * No interruptions filter - all notifications are suppressed and all audio streams (except + * those used for phone calls) and vibrations are muted. */ public static final int INTERRUPTION_FILTER_NONE = 3; /** * {@link #getCurrentInterruptionFilter() Interruption filter} constant - - * Alarms only interruption filter. + * Alarms only interruption filter - all notifications except those of category + * {@link Notification#CATEGORY_ALARM} are suppressed. Some audio streams are muted. */ public static final int INTERRUPTION_FILTER_ALARMS = 4; diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java index 276f774a8f4e..2c1ee8e13624 100644 --- a/core/java/android/app/UiAutomationConnection.java +++ b/core/java/android/app/UiAutomationConnection.java @@ -36,6 +36,7 @@ import android.view.WindowAnimationFrameStats; import android.view.WindowContentFrameStats; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.IAccessibilityManager; + import libcore.io.IoUtils; import java.io.FileOutputStream; @@ -77,6 +78,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { private int mOwningUid; + @Override public void connect(IAccessibilityServiceClient client, int flags) { if (client == null) { throw new IllegalArgumentException("Client cannot be null!"); @@ -326,11 +328,12 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { int flags) { IAccessibilityManager manager = IAccessibilityManager.Stub.asInterface( ServiceManager.getService(Context.ACCESSIBILITY_SERVICE)); - AccessibilityServiceInfo info = new AccessibilityServiceInfo(); + final AccessibilityServiceInfo info = new AccessibilityServiceInfo(); info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK; info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC; info.flags |= AccessibilityServiceInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS - | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS; + | AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS + | AccessibilityServiceInfo.FLAG_FORCE_DIRECT_BOOT_AWARE; info.setCapabilities(AccessibilityServiceInfo.CAPABILITY_CAN_RETRIEVE_WINDOW_CONTENT | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_TOUCH_EXPLORATION | AccessibilityServiceInfo.CAPABILITY_CAN_REQUEST_ENHANCED_WEB_ACCESSIBILITY diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 45aa6b44a8f1..96757bba510d 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -2185,9 +2185,6 @@ public class DevicePolicyManager { * Force a new device unlock password (the password needed to access the entire device, not for * individual accounts) on the user. This takes effect immediately. * <p> - * Calling this from a managed profile that shares the password with the owner profile will - * throw a security exception. - * <p> * <em>Note: This API has been limited as of {@link android.os.Build.VERSION_CODES#N} for * device admins that are not device owner and not profile owner. * The password can now only be changed if there is currently no password set. Device owner @@ -2201,10 +2198,10 @@ public class DevicePolicyManager { * case the currently active quality will be increased to match. * <p> * Calling with a null or empty password will clear any existing PIN, pattern or password if the - * current password constraints allow it. <em>Note: This will not - * work in {@link android.os.Build.VERSION_CODES#N} and later for device admins that are not - * device owner and not profile owner. Once set, the password cannot be changed to null or - * empty, except by device owner or profile owner.</em> + * current password constraints allow it. <em>Note: This will not work in + * {@link android.os.Build.VERSION_CODES#N} and later for managed profiles, or for device admins + * that are not device owner or profile owner. Once set, the password cannot be changed to null + * or empty except by these admins.</em> * <p> * The calling device admin must have requested * {@link DeviceAdminInfo#USES_POLICY_RESET_PASSWORD} to be able to call this method; if it has @@ -2291,6 +2288,23 @@ public class DevicePolicyManager { } /** + * Returns maximum time to lock that applied by all profiles in this user. We do this because we + * do not have a separate timeout to lock for work challenge only. + * + * @hide + */ + public long getMaximumTimeToLockForUserAndProfiles(int userHandle) { + if (mService != null) { + try { + return mService.getMaximumTimeToLockForUserAndProfiles(userHandle); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + return 0; + } + + /** * Make the device lock immediately, as if the lock screen timeout has expired at the point of * this call. * <p> @@ -2980,17 +2994,21 @@ public class DevicePolicyManager { * @return {@code true} if the package is set as always-on VPN controller; {@code false} * otherwise. * @throws SecurityException if {@code admin} is not a device or a profile owner. + * @throws NameNotFoundException if {@code vpnPackage} is not installed. + * @throws UnsupportedOperationException if {@code vpnPackage} exists but does not support being + * set as always-on, or if always-on VPN is not available. */ - public boolean setAlwaysOnVpnPackage(@NonNull ComponentName admin, - @Nullable String vpnPackage) { + public void setAlwaysOnVpnPackage(@NonNull ComponentName admin, @Nullable String vpnPackage) + throws NameNotFoundException, UnsupportedOperationException { if (mService != null) { try { - return mService.setAlwaysOnVpnPackage(admin, vpnPackage); + if (!mService.setAlwaysOnVpnPackage(admin, vpnPackage)) { + throw new NameNotFoundException(vpnPackage); + } } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } } - return false; } /** @@ -4159,6 +4177,10 @@ public class DevicePolicyManager { * The calling device admin must have requested * {@link DeviceAdminInfo#USES_POLICY_DISABLE_KEYGUARD_FEATURES} to be able to call this method; * if not, a security exception will be thrown. + * <p> + * This method can be called on the {@link DevicePolicyManager} instance returned by + * {@link #getParentProfileInstance(ComponentName)} in order to set the configuration for + * the parent profile. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. * @param target Component name of the agent to be enabled. @@ -4179,7 +4201,7 @@ public class DevicePolicyManager { @NonNull ComponentName target, PersistableBundle configuration) { if (mService != null) { try { - mService.setTrustAgentConfiguration(admin, target, configuration); + mService.setTrustAgentConfiguration(admin, target, configuration, mParentInstance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -4190,6 +4212,10 @@ public class DevicePolicyManager { * Gets configuration for the given trust agent based on aggregating all calls to * {@link #setTrustAgentConfiguration(ComponentName, ComponentName, PersistableBundle)} for * all device admins. + * <p> + * This method can be called on the {@link DevicePolicyManager} instance returned by + * {@link #getParentProfileInstance(ComponentName)} in order to retrieve the configuration set + * on the parent profile. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with. If null, * this function returns a list of configurations for all admins that declare @@ -4210,7 +4236,8 @@ public class DevicePolicyManager { @NonNull ComponentName agent, int userHandle) { if (mService != null) { try { - return mService.getTrustAgentConfiguration(admin, agent, userHandle); + return mService.getTrustAgentConfiguration(admin, agent, userHandle, + mParentInstance); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } @@ -5852,8 +5879,43 @@ public class DevicePolicyManager { /** * Called by the profile owner of a managed profile to obtain a {@link DevicePolicyManager} * whose calls act on the parent profile. - * <p> - * Note only some methods will work on the parent Manager. + * + * <p>The following methods are supported for the parent instance, all other methods will + * throw a SecurityException when called on the parent instance: + * <ul> + * <li>{@link #getPasswordQuality}</li> + * <li>{@link #setPasswordQuality}</li> + * <li>{@link #getPasswordMinimumLength}</li> + * <li>{@link #setPasswordMinimumLength}</li> + * <li>{@link #getPasswordMinimumUpperCase}</li> + * <li>{@link #setPasswordMinimumUpperCase}</li> + * <li>{@link #getPasswordMinimumLowerCase}</li> + * <li>{@link #setPasswordMinimumLowerCase}</li> + * <li>{@link #getPasswordMinimumLetters}</li> + * <li>{@link #setPasswordMinimumLetters}</li> + * <li>{@link #getPasswordMinimumNumeric}</li> + * <li>{@link #setPasswordMinimumNumeric}</li> + * <li>{@link #getPasswordMinimumSymbols}</li> + * <li>{@link #setPasswordMinimumSymbols}</li> + * <li>{@link #getPasswordMinimumNonLetter}</li> + * <li>{@link #setPasswordMinimumNonLetter}</li> + * <li>{@link #getPasswordHistoryLength}</li> + * <li>{@link #setPasswordHistoryLength}</li> + * <li>{@link #getPasswordExpirationTimeout}</li> + * <li>{@link #setPasswordExpirationTimeout}</li> + * <li>{@link #getPasswordExpiration}</li> + * <li>{@link #isActivePasswordSufficient}</li> + * <li>{@link #getCurrentFailedPasswordAttempts}</li> + * <li>{@link #getMaximumFailedPasswordsForWipe}</li> + * <li>{@link #setMaximumFailedPasswordsForWipe}</li> + * <li>{@link #getMaximumTimeToLock}</li> + * <li>{@link #setMaximumTimeToLock}</li> + * <li>{@link #lockNow}</li> + * <li>{@link #getKeyguardDisabledFeatures}</li> + * <li>{@link #setKeyguardDisabledFeatures}</li> + * <li>{@link #getTrustAgentConfiguration}</li> + * <li>{@link #setTrustAgentConfiguration}</li> + * </ul> * * @return a new instance of {@link DevicePolicyManager} that acts on the parent profile. * @throws SecurityException if {@code admin} is not a profile owner. diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index 6ee56aa91296..6df10388b85e 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -80,6 +80,7 @@ interface IDevicePolicyManager { void setMaximumTimeToLock(in ComponentName who, long timeMs, boolean parent); long getMaximumTimeToLock(in ComponentName who, int userHandle, boolean parent); + long getMaximumTimeToLockForUserAndProfiles(int userHandle); void lockNow(boolean parent); @@ -228,9 +229,9 @@ interface IDevicePolicyManager { boolean getBluetoothContactSharingDisabledForUser(int userId); void setTrustAgentConfiguration(in ComponentName admin, in ComponentName agent, - in PersistableBundle args); + in PersistableBundle args, boolean parent); List<PersistableBundle> getTrustAgentConfiguration(in ComponentName admin, - in ComponentName agent, int userId); + in ComponentName agent, int userId, boolean parent); boolean addCrossProfileWidgetProvider(in ComponentName admin, String packageName); boolean removeCrossProfileWidgetProvider(in ComponentName admin, String packageName); diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java index 801c9517b64d..8e515e2b579c 100644 --- a/core/java/android/app/backup/BackupAgent.java +++ b/core/java/android/app/backup/BackupAgent.java @@ -427,23 +427,31 @@ public abstract class BackupAgent extends ContextWrapper { } /** - * Tells the application agent that the backup data size exceeded current transport quota. - * Later calls to {@link #onBackup(ParcelFileDescriptor, BackupDataOutput, ParcelFileDescriptor)} - * and {@link #onFullBackup(FullBackupDataOutput)} could use this information - * to reduce backup size under the limit. - * However, the quota can change, so do not assume that the value passed in here is absolute, - * similarly all subsequent backups should not be restricted to this size. - * This callback will be invoked before data has been put onto the wire in a preflight check, - * so it is relatively inexpensive to hit your quota. - * Apps that hit quota repeatedly without dealing with it can be subject to having their backup - * schedule reduced. - * The {@code quotaBytes} is a loose guideline b/c of metadata added by the backupmanager - * so apps should be more aggressive in trimming their backup set. + * Notification that the application's current backup operation causes it to exceed + * the maximum size permitted by the transport. The ongoing backup operation is + * halted and rolled back: any data that had been stored by a previous backup operation + * is still intact. Typically the quota-exceeded state will be detected before any data + * is actually transmitted over the network. * - * @param backupDataBytes Expected or already processed amount of data. - * Could be less than total backup size if backup process was interrupted - * before finish of processing all backup data. - * @param quotaBytes Current amount of backup data that is allowed for the app. + * <p>The {@code quotaBytes} value is the total data size currently permitted for this + * application. If desired, the application can use this as a hint for determining + * how much data to store. For example, a messaging application might choose to + * store only the newest messages, dropping enough older content to stay under + * the quota. + * + * <p class="note">Note that the maximum quota for the application can change over + * time. In particular, in the future the quota may grow. Applications that adapt + * to the quota when deciding what data to store should be aware of this and implement + * their data storage mechanisms in a way that can take advantage of additional + * quota. + * + * @param backupDataBytes The amount of data measured while initializing the backup + * operation, if the total exceeds the app's alloted quota. If initial measurement + * suggested that the data would fit but then too much data was actually submitted + * as part of the operation, then this value is the amount of data that had been + * streamed into the transport at the time the quota was reached. + * @param quotaBytes The maximum data size that the transport currently permits + * this application to store as a backup. */ public void onQuotaExceeded(long backupDataBytes, long quotaBytes) { } diff --git a/core/java/android/appwidget/AppWidgetHost.java b/core/java/android/appwidget/AppWidgetHost.java index 1af495365825..2d9f4a71b005 100644 --- a/core/java/android/appwidget/AppWidgetHost.java +++ b/core/java/android/appwidget/AppWidgetHost.java @@ -17,8 +17,7 @@ package android.appwidget; import java.lang.ref.WeakReference; -import java.util.ArrayList; -import java.util.HashMap; +import java.util.List; import android.annotation.NonNull; import android.annotation.Nullable; @@ -35,7 +34,9 @@ import android.os.Message; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.SystemClock; import android.util.DisplayMetrics; +import android.util.SparseArray; import android.util.TypedValue; import android.widget.RemoteViews; import android.widget.RemoteViews.OnClickHandler; @@ -62,7 +63,7 @@ public class AppWidgetHost { private final Handler mHandler; private final int mHostId; private final Callbacks mCallbacks; - private final HashMap<Integer,AppWidgetHostView> mViews = new HashMap<>(); + private final SparseArray<AppWidgetHostView> mViews = new SparseArray<>(); private OnClickHandler mOnClickHandler; static class Callbacks extends IAppWidgetHost.Stub { @@ -164,7 +165,6 @@ public class AppWidgetHost { bindService(); } - private static void bindService() { synchronized (sServiceLock) { if (sService == null) { @@ -179,17 +179,25 @@ public class AppWidgetHost { * becomes visible, i.e. from onStart() in your Activity. */ public void startListening() { - int[] updatedIds; - ArrayList<RemoteViews> updatedViews = new ArrayList<RemoteViews>(); + final int[] idsToUpdate; + synchronized (mViews) { + int N = mViews.size(); + idsToUpdate = new int[N]; + for (int i = 0; i < N; i++) { + idsToUpdate[i] = mViews.keyAt(i); + } + } + List<RemoteViews> updatedViews; + int[] updatedIds = new int[idsToUpdate.length]; try { - updatedIds = sService.startListening(mCallbacks, mContextOpPackageName, mHostId, - updatedViews); + updatedViews = sService.startListening( + mCallbacks, mContextOpPackageName, mHostId, idsToUpdate, updatedIds).getList(); } catch (RemoteException e) { throw new RuntimeException("system server dead?", e); } - final int N = updatedIds.length; + int N = updatedViews.size(); for (int i = 0; i < N; i++) { updateAppWidgetView(updatedIds[i], updatedViews.get(i)); } @@ -206,10 +214,6 @@ public class AppWidgetHost { catch (RemoteException e) { throw new RuntimeException("system server dead?", e); } - - // This is here because keyguard needs it since it'll be switching users after this call. - // If it turns out other apps need to call this often, we should re-think how this works. - clearViews(); } /** @@ -418,7 +422,9 @@ public class AppWidgetHost { * Clear the list of Views that have been created by this AppWidgetHost. */ protected void clearViews() { - mViews.clear(); + synchronized (mViews) { + mViews.clear(); + } } } diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java index d762a1727272..2a7eff883095 100644 --- a/core/java/android/bluetooth/BluetoothAdapter.java +++ b/core/java/android/bluetooth/BluetoothAdapter.java @@ -36,6 +36,7 @@ import android.os.IBinder; import android.os.ParcelUuid; import android.os.RemoteException; import android.os.ServiceManager; +import android.os.SystemProperties; import android.util.Log; import android.util.Pair; @@ -1015,6 +1016,8 @@ public final class BluetoothAdapter { try { if (mService != null) { return mService.factoryReset(); + } else { + SystemProperties.set("persist.bluetooth.factoryreset", "true"); } } catch (RemoteException e) {Log.e(TAG, "", e);} return false; diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index cd67b3ee8a3e..4db45670dd85 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -17,6 +17,7 @@ package android.content; import android.accounts.Account; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; @@ -60,6 +61,8 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; import java.util.Random; @@ -289,6 +292,31 @@ public abstract class ContentResolver { /** @hide */ public static final int SYNC_OBSERVER_TYPE_ALL = 0x7fffffff; + /** @hide */ + @IntDef(flag = true, + value = { + NOTIFY_SYNC_TO_NETWORK, + NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS + }) + @Retention(RetentionPolicy.SOURCE) + public @interface NotifyFlags {} + + /** + * Flag for {@link #notifyChange(Uri, ContentObserver, int)}: attempt to sync the change + * to the network. + */ + public static final int NOTIFY_SYNC_TO_NETWORK = 1<<0; + + /** + * Flag for {@link #notifyChange(Uri, ContentObserver, int)}: if set, this notification + * will be skipped if it is being delivered to the root URI of a ContentObserver that is + * using "notify for descendants." The purpose of this is to allow the provide to send + * a general notification of "something under X" changed that observers of that specific + * URI can receive, while also sending a specific URI under X. It would use this flag + * when sending the former, so that observers of "X and descendants" only see the latter. + */ + public static final int NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS = 1<<1; + // Always log queries which take 500ms+; shorter queries are // sampled accordingly. private static final boolean ENABLE_CONTENT_SAMPLE = false; @@ -1676,7 +1704,7 @@ public abstract class ContentResolver { * The observer that originated the change will only receive the notification if it * has requested to receive self-change notifications by implementing * {@link ContentObserver#deliverSelfNotifications()} to return true. - * @param syncToNetwork If true, attempt to sync the change to the network. + * @param syncToNetwork If true, same as {@link #NOTIFY_SYNC_TO_NETWORK}. * @see #requestSync(android.accounts.Account, String, android.os.Bundle) */ public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer, @@ -1690,6 +1718,32 @@ public abstract class ContentResolver { } /** + * Notify registered observers that a row was updated. + * To register, call {@link #registerContentObserver(android.net.Uri, boolean, android.database.ContentObserver) registerContentObserver()}. + * By default, CursorAdapter objects will get this notification. + * If syncToNetwork is true, this will attempt to schedule a local sync using the sync + * adapter that's registered for the authority of the provided uri. No account will be + * passed to the sync adapter, so all matching accounts will be synchronized. + * + * @param uri The uri of the content that was changed. + * @param observer The observer that originated the change, may be <code>null</null>. + * The observer that originated the change will only receive the notification if it + * has requested to receive self-change notifications by implementing + * {@link ContentObserver#deliverSelfNotifications()} to return true. + * @param flags Additional flags: {@link #NOTIFY_SYNC_TO_NETWORK}. + * @see #requestSync(android.accounts.Account, String, android.os.Bundle) + */ + public void notifyChange(@NonNull Uri uri, @Nullable ContentObserver observer, + @NotifyFlags int flags) { + Preconditions.checkNotNull(uri, "uri"); + notifyChange( + ContentProvider.getUriWithoutUserId(uri), + observer, + flags, + ContentProvider.getUserIdFromUri(uri, UserHandle.myUserId())); + } + + /** * Notify registered observers within the designated user(s) that a row was updated. * * @hide @@ -1699,7 +1753,24 @@ public abstract class ContentResolver { try { getContentService().notifyChange( uri, observer == null ? null : observer.getContentObserver(), - observer != null && observer.deliverSelfNotifications(), syncToNetwork, + observer != null && observer.deliverSelfNotifications(), + syncToNetwork ? NOTIFY_SYNC_TO_NETWORK : 0, + userHandle); + } catch (RemoteException e) { + } + } + + /** + * Notify registered observers within the designated user(s) that a row was updated. + * + * @hide + */ + public void notifyChange(Uri uri, ContentObserver observer, @NotifyFlags int flags, + @UserIdInt int userHandle) { + try { + getContentService().notifyChange( + uri, observer == null ? null : observer.getContentObserver(), + observer != null && observer.deliverSelfNotifications(), flags, userHandle); } catch (RemoteException e) { } diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl index d47e780fa4d2..3446e0315a1d 100644 --- a/core/java/android/content/IContentService.aidl +++ b/core/java/android/content/IContentService.aidl @@ -52,7 +52,7 @@ interface IContentService { * USER_CURRENT are properly interpreted. */ void notifyChange(in Uri uri, IContentObserver observer, - boolean observerWantsSelfNotifications, boolean syncToNetwork, + boolean observerWantsSelfNotifications, int flags, int userHandle); void requestSync(in Account account, String authority, in Bundle extras); diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index 10259be8d430..30f2c948df96 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -3056,15 +3056,29 @@ public class Intent implements Parcelable, Cloneable { public static final String ACTION_MANAGED_PROFILE_UNLOCKED = "android.intent.action.MANAGED_PROFILE_UNLOCKED"; + /** @hide */ + public static final String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = + "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED"; + /** - * Broadcast sent to the primary user when an associated managed profile's availability has - * changed. This includes when the user toggles the profile's quiet mode. Carries an extra + * Broadcast sent to the primary user when an associated managed profile has become available. + * Currently this includes when the user disables quiet mode for the profile. Carries an extra * {@link #EXTRA_USER} that specifies the UserHandle of the profile. When quiet mode is changed, * this broadcast will carry a boolean extra {@link #EXTRA_QUIET_MODE} indicating the new state * of quiet mode. This is only sent to registered receivers, not manifest receivers. */ - public static final String ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED = - "android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED"; + public static final String ACTION_MANAGED_PROFILE_AVAILABLE = + "android.intent.action.MANAGED_PROFILE_AVAILABLE"; + + /** + * Broadcast sent to the primary user when an associated managed profile has become unavailable. + * Currently this includes when the user enables quiet mode for the profile. Carries an extra + * {@link #EXTRA_USER} that specifies the UserHandle of the profile. When quiet mode is changed, + * this broadcast will carry a boolean extra {@link #EXTRA_QUIET_MODE} indicating the new state + * of quiet mode. This is only sent to registered receivers, not manifest receivers. + */ + public static final String ACTION_MANAGED_PROFILE_UNAVAILABLE = + "android.intent.action.MANAGED_PROFILE_UNAVAILABLE"; /** * Sent when the user taps on the clock widget in the system's "quick settings" area. @@ -4165,6 +4179,9 @@ public class Intent implements Parcelable, Cloneable { /** * Optional boolean extra indicating whether quiet mode has been switched on or off. + * When a profile goes into quiet mode, all apps in the profile are killed and the + * profile user is stopped. Widgets originating from the profile are masked, and app + * launcher icons are grayed out. */ public static final String EXTRA_QUIET_MODE = "android.intent.extra.QUIET_MODE"; diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java index 3a17e23b0547..22ab43bbb429 100644 --- a/core/java/android/content/IntentFilter.java +++ b/core/java/android/content/IntentFilter.java @@ -449,11 +449,12 @@ public class IntentFilter implements Parcelable { } /** - * Modify priority of this filter. The default priority is 0. Positive - * values will be before the default, lower values will be after it. - * Applications must use a value that is larger than - * {@link #SYSTEM_LOW_PRIORITY} and smaller than - * {@link #SYSTEM_HIGH_PRIORITY} . + * Modify priority of this filter. This only affects receiver filters. + * The priority of activity filters are set in XML and cannot be changed + * programatically. The default priority is 0. Positive values will be + * before the default, lower values will be after it. Applications should + * use a value that is larger than {@link #SYSTEM_LOW_PRIORITY} and + * smaller than {@link #SYSTEM_HIGH_PRIORITY} . * * @param priority The new priority value. * @@ -883,6 +884,15 @@ public class IntentFilter implements Parcelable { return true; } + @Override + public boolean equals(Object obj) { + if (obj instanceof AuthorityEntry) { + final AuthorityEntry other = (AuthorityEntry)obj; + return match(other); + } + return false; + } + /** * Determine whether this AuthorityEntry matches the given data Uri. * <em>Note that this comparison is case-sensitive, unlike formal @@ -917,7 +927,7 @@ public class IntentFilter implements Parcelable { } return MATCH_CATEGORY_HOST; } - }; + } /** * Add a new Intent data "scheme specific part" to match against. The filter must diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index ea251f648034..fe8db9f6ad37 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -1096,13 +1096,19 @@ public class PackageParser { pkg.mSignatures = null; pkg.mSigningKeys = null; - collectCertificates(pkg, new File(pkg.baseCodePath), pkg.applicationInfo.flags, parseFlags); + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); + try { + collectCertificates( + pkg, new File(pkg.baseCodePath), pkg.applicationInfo.flags, parseFlags); - if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { - for (int i = 0; i < pkg.splitCodePaths.length; i++) { - collectCertificates(pkg, new File(pkg.splitCodePaths[i]), pkg.splitFlags[i], - parseFlags); + if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) { + for (int i = 0; i < pkg.splitCodePaths.length; i++) { + collectCertificates( + pkg, new File(pkg.splitCodePaths[i]), pkg.splitFlags[i], parseFlags); + } } + } finally { + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } } @@ -1118,6 +1124,7 @@ public class PackageParser { Certificate[][] allSignersCerts = null; Signature[] signatures = null; try { + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "verifyV2"); allSignersCerts = ApkSignatureSchemeV2Verifier.verify(apkPath); signatures = convertToSignatures(allSignersCerts); // APK verified using APK Signature Scheme v2. @@ -1130,6 +1137,8 @@ public class PackageParser { "Failed to collect certificates from " + apkPath + " using APK Signature Scheme v2", e); + } finally { + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } if (verified) { @@ -1186,7 +1195,7 @@ public class PackageParser { } // APK's integrity needs to be verified using JAR signature scheme. - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "buildVerifyList"); + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "verifyV1"); final List<ZipEntry> toVerify = new ArrayList<>(); toVerify.add(manifestEntry); @@ -1208,7 +1217,6 @@ public class PackageParser { toVerify.add(entry); } } - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); if (!codeFound && requireCode) { throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED, @@ -1218,7 +1226,6 @@ public class PackageParser { // Verify that entries are signed consistently with the first entry // we encountered. Note that for splits, certificates may have // already been populated during an earlier parse of a base APK. - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "verifyEntries"); for (ZipEntry entry : toVerify) { final Certificate[][] entryCerts = loadCertificates(jarFile, entry); if (ArrayUtils.isEmpty(entryCerts)) { @@ -1300,7 +1307,12 @@ public class PackageParser { if ((flags & PARSE_COLLECT_CERTIFICATES) != 0) { // TODO: factor signature related items out of Package object final Package tempPkg = new Package(null); - collectCertificates(tempPkg, apkFile, 0 /*apkFlags*/, 0 /*flags*/); + Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); + try { + collectCertificates(tempPkg, apkFile, 0 /*apkFlags*/, 0 /*flags*/); + } finally { + Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); + } signatures = tempPkg.mSignatures; } else { signatures = null; @@ -5531,7 +5543,7 @@ public class PackageParser { return pi; } - public final static class Instrumentation extends Component { + public final static class Instrumentation extends Component<IntentInfo> { public final InstrumentationInfo info; public Instrumentation(final ParsePackageItemArgs args, final InstrumentationInfo _info) { diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index 387fda717e48..93fe73b06e89 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -714,12 +714,11 @@ public class Resources { * the resource ID passed here is an alias to another Drawable resource. * This means that if the density configuration of the alias resource * is different than the actual resource, the density of the returned - * Drawable would be incorrect, resulting in bad scaling. To work - * around this, you can instead retrieve the Drawable through - * {@link TypedArray#getDrawable TypedArray.getDrawable}. Use - * {@link android.content.Context#obtainStyledAttributes(int[]) - * Context.obtainStyledAttributes} with - * an array containing the resource ID of interest to create the TypedArray.</p> + * Drawable would be incorrect, resulting in bad scaling. To work + * around this, you can instead manually resolve the aliased reference + * by using {@link #getValue(int, TypedValue, boolean)} and passing + * {@code true} for {@code resolveRefs}. The resulting + * {@link TypedValue#resourceId} value may be passed to this method.</p> * * <p class="note"><strong>Note:</strong> To obtain a themed drawable, use * {@link android.content.Context#getDrawable(int) Context.getDrawable(int)} diff --git a/core/java/android/ddm/DdmHandleHello.java b/core/java/android/ddm/DdmHandleHello.java index 2dce4257da57..b2288fc4492d 100644 --- a/core/java/android/ddm/DdmHandleHello.java +++ b/core/java/android/ddm/DdmHandleHello.java @@ -136,12 +136,14 @@ public class DdmHandleHello extends ChunkHandler { } String vmFlags = "CheckJNI=" + (vmRuntime.isCheckJniEnabled() ? "true" : "false"); + boolean isNativeDebuggable = vmRuntime.isNativeDebuggable(); ByteBuffer out = ByteBuffer.allocate(28 + vmIdent.length() * 2 + appName.length() * 2 + instructionSetDescription.length() * 2 - + vmFlags.length() * 2); + + vmFlags.length() * 2 + + 1); out.order(ChunkHandler.CHUNK_ORDER); out.putInt(DdmServer.CLIENT_PROTOCOL_VERSION); out.putInt(android.os.Process.myPid()); @@ -154,6 +156,7 @@ public class DdmHandleHello extends ChunkHandler { putString(out, instructionSetDescription); out.putInt(vmFlags.length()); putString(out, vmFlags); + out.put((byte)(isNativeDebuggable ? 1 : 0)); Chunk reply = new Chunk(CHUNK_HELO, out); diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index 4add9626b24e..d06e08b70910 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -2025,11 +2025,20 @@ public abstract class CameraMetadata<TKey> { * produced in response to a capture request submitted * while in HDR mode.</p> * <p>Since substantial post-processing is generally needed to - * produce an HDR image, only YUV and JPEG outputs are - * supported for LIMITED/FULL device HDR captures, and only - * JPEG outputs are supported for LEGACY HDR - * captures. Using a RAW output for HDR capture is not + * produce an HDR image, only YUV, PRIVATE, and JPEG + * outputs are supported for LIMITED/FULL device HDR + * captures, and only JPEG outputs are supported for LEGACY + * HDR captures. Using a RAW output for HDR capture is not * supported.</p> + * <p>Some devices may also support always-on HDR, which + * applies HDR processing at full frame rate. For these + * devices, intents other than STILL_CAPTURE will also + * produce an HDR output with no frame rate impact compared + * to normal operation, though the quality may be lower + * than for STILL_CAPTURE intents.</p> + * <p>If SCENE_MODE_HDR is used with unsupported output types + * or capture intents, the images captured will be as if + * the SCENE_MODE was not enabled at all.</p> * * @see CaptureRequest#CONTROL_CAPTURE_INTENT * @see CaptureRequest#CONTROL_SCENE_MODE diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java index 5748726b4cad..4f41e1c60d86 100644 --- a/core/java/android/hardware/camera2/CaptureResult.java +++ b/core/java/android/hardware/camera2/CaptureResult.java @@ -3373,7 +3373,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { /** * <p>Maximum raw value output by sensor for this frame.</p> - * <p>Since the android.sensor.blackLevel may change for different + * <p>Since the {@link CameraCharacteristics#SENSOR_BLACK_LEVEL_PATTERN android.sensor.blackLevelPattern} may change for different * capture settings (e.g., {@link CaptureRequest#SENSOR_SENSITIVITY android.sensor.sensitivity}), the white * level will change accordingly. This key is similar to * {@link CameraCharacteristics#SENSOR_INFO_WHITE_LEVEL android.sensor.info.whiteLevel}, but specifies the camera device @@ -3385,6 +3385,7 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> { * >= 0</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * + * @see CameraCharacteristics#SENSOR_BLACK_LEVEL_PATTERN * @see CameraCharacteristics#SENSOR_INFO_WHITE_LEVEL * @see CameraCharacteristics#SENSOR_OPTICAL_BLACK_REGIONS * @see CaptureRequest#SENSOR_SENSITIVITY diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index d84a6fcbd16f..d2e820e17776 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -974,6 +974,7 @@ public class CameraDeviceImpl extends CameraDevice if (mRemoteDevice != null) { mRemoteDevice.disconnect(); + mRemoteDevice.unlinkToDeath(this, /*flags*/0); } // Only want to fire the onClosed callback once; diff --git a/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java b/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java index ddc3fd12b70d..ef5f6d71b8b6 100644 --- a/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java +++ b/core/java/android/hardware/camera2/impl/ICameraDeviceUserWrapper.java @@ -31,6 +31,7 @@ import android.hardware.camera2.ICameraDeviceUser; import android.hardware.camera2.impl.CameraMetadataNative; import android.hardware.camera2.params.OutputConfiguration; import android.hardware.camera2.utils.SubmitInfo; +import android.os.IBinder; import android.os.RemoteException; import android.view.Surface; @@ -53,6 +54,12 @@ public class ICameraDeviceUserWrapper { mRemoteDevice = remoteDevice; } + public void unlinkToDeath(IBinder.DeathRecipient recipient, int flags) { + if (mRemoteDevice.asBinder() != null) { + mRemoteDevice.asBinder().unlinkToDeath(recipient, flags); + } + } + public void disconnect() { try { mRemoteDevice.disconnect(); diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceState.java b/core/java/android/hardware/camera2/legacy/CameraDeviceState.java index 2c2ad1c23ce6..b0b94e3ac009 100644 --- a/core/java/android/hardware/camera2/legacy/CameraDeviceState.java +++ b/core/java/android/hardware/camera2/legacy/CameraDeviceState.java @@ -70,7 +70,7 @@ public class CameraDeviceState { * CameraDeviceStateListener callbacks to be called after state transitions. */ public interface CameraDeviceStateListener { - void onError(int errorCode, RequestHolder holder); + void onError(int errorCode, Object errorArg, RequestHolder holder); void onConfiguring(); void onIdle(); void onBusy(); @@ -162,11 +162,12 @@ public class CameraDeviceState { * @param captureError Report a recoverable error for a single buffer or result using a valid * error code for {@code ICameraDeviceCallbacks}, or * {@link #NO_CAPTURE_ERROR}. + * @param captureErrorArg An argument for some error captureError codes. * @return {@code false} if an error has occurred. */ public synchronized boolean setCaptureResult(final RequestHolder request, - final CameraMetadataNative result, - final int captureError) { + final CameraMetadataNative result, + final int captureError, final Object captureErrorArg) { if (mCurrentState != STATE_CAPTURING) { Log.e(TAG, "Cannot receive result while in state: " + mCurrentState); mCurrentError = CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_DEVICE; @@ -179,7 +180,7 @@ public class CameraDeviceState { mCurrentHandler.post(new Runnable() { @Override public void run() { - mCurrentListener.onError(captureError, request); + mCurrentListener.onError(captureError, captureErrorArg, request); } }); } else { @@ -194,6 +195,11 @@ public class CameraDeviceState { return mCurrentError == NO_CAPTURE_ERROR; } + public synchronized boolean setCaptureResult(final RequestHolder request, + final CameraMetadataNative result) { + return setCaptureResult(request, result, NO_CAPTURE_ERROR, /*errorArg*/null); + } + /** * Set the listener for state transition callbacks. * @@ -239,7 +245,7 @@ public class CameraDeviceState { mCurrentHandler.post(new Runnable() { @Override public void run() { - mCurrentListener.onError(mCurrentError, mCurrentRequest); + mCurrentListener.onError(mCurrentError, /*errorArg*/null, mCurrentRequest); } }); } @@ -299,7 +305,7 @@ public class CameraDeviceState { mCurrentHandler.post(new Runnable() { @Override public void run() { - mCurrentListener.onError(error, mCurrentRequest); + mCurrentListener.onError(error, /*errorArg*/null, mCurrentRequest); } }); } else { diff --git a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java index d01c275e74dc..f99928a884ee 100644 --- a/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java +++ b/core/java/android/hardware/camera2/legacy/CameraDeviceUserShim.java @@ -480,19 +480,15 @@ public class CameraDeviceUserShim implements ICameraDeviceUser { throw new ServiceSpecificException(ICameraService.ERROR_DISCONNECTED, err); } - ArrayList<Surface> surfaces = null; + SparseArray<Surface> surfaces = null; synchronized(mConfigureLock) { if (!mConfiguring) { String err = "Cannot end configure, no configuration change in progress."; Log.e(TAG, err); throw new ServiceSpecificException(ICameraService.ERROR_INVALID_OPERATION, err); } - int numSurfaces = mSurfaces.size(); - if (numSurfaces > 0) { - surfaces = new ArrayList<>(); - for (int i = 0; i < numSurfaces; ++i) { - surfaces.add(mSurfaces.valueAt(i)); - } + if (mSurfaces != null) { + surfaces = mSurfaces.clone(); } mConfiguring = false; } diff --git a/core/java/android/hardware/camera2/legacy/CaptureCollector.java b/core/java/android/hardware/camera2/legacy/CaptureCollector.java index eb48a01ac103..113927c4c4b2 100644 --- a/core/java/android/hardware/camera2/legacy/CaptureCollector.java +++ b/core/java/android/hardware/camera2/legacy/CaptureCollector.java @@ -19,7 +19,7 @@ import android.hardware.camera2.impl.CameraDeviceImpl; import android.util.Log; import android.util.MutableLong; import android.util.Pair; - +import android.view.Surface; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.TreeSet; @@ -95,22 +95,28 @@ public class CaptureCollector { } else { // Send buffer dropped errors for each pending buffer if the request has // started. - if (mFailedPreview) { - Log.w(TAG, "Preview buffers dropped for request: " + - mRequest.getRequestId()); - for (int i = 0; i < mRequest.numPreviewTargets(); i++) { - CaptureCollector.this.mDeviceState.setCaptureResult(mRequest, - /*result*/null, - CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_BUFFER); - } - } - if (mFailedJpeg) { - Log.w(TAG, "Jpeg buffers dropped for request: " + - mRequest.getRequestId()); - for (int i = 0; i < mRequest.numJpegTargets(); i++) { - CaptureCollector.this.mDeviceState.setCaptureResult(mRequest, - /*result*/null, - CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_BUFFER); + for (Surface targetSurface : mRequest.getRequest().getTargets() ) { + try { + if (mRequest.jpegType(targetSurface)) { + if (mFailedJpeg) { + CaptureCollector.this.mDeviceState.setCaptureResult(mRequest, + /*result*/null, + CameraDeviceImpl.CameraDeviceCallbacks. + ERROR_CAMERA_BUFFER, + targetSurface); + } + } else { + // preview buffer + if (mFailedPreview) { + CaptureCollector.this.mDeviceState.setCaptureResult(mRequest, + /*result*/null, + CameraDeviceImpl.CameraDeviceCallbacks. + ERROR_CAMERA_BUFFER, + targetSurface); + } + } + } catch (LegacyExceptionUtils.BufferQueueAbandonedException e) { + Log.e(TAG, "Unexpected exception when querying Surface: " + e); } } } diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java index 661edd734a71..6c9586986b97 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java @@ -36,6 +36,7 @@ import android.os.ServiceSpecificException; import android.util.Log; import android.util.Pair; import android.util.Size; +import android.util.SparseArray; import android.view.Surface; import java.util.ArrayList; @@ -64,7 +65,7 @@ public class LegacyCameraDevice implements AutoCloseable { private final CameraCharacteristics mStaticCharacteristics; private final ICameraDeviceCallbacks mDeviceCallbacks; private final CameraDeviceState mDeviceState = new CameraDeviceState(); - private List<Surface> mConfiguredSurfaces; + private SparseArray<Surface> mConfiguredSurfaces; private boolean mClosed = false; private final ConditionVariable mIdle = new ConditionVariable(/*open*/true); @@ -89,13 +90,29 @@ public class LegacyCameraDevice implements AutoCloseable { public static final int NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW = 1; private CaptureResultExtras getExtrasFromRequest(RequestHolder holder) { + return getExtrasFromRequest(holder, + /*errorCode*/CameraDeviceState.NO_CAPTURE_ERROR, /*errorArg*/null); + } + + private CaptureResultExtras getExtrasFromRequest(RequestHolder holder, + int errorCode, Object errorArg) { + int errorStreamId = -1; + if (errorCode == CameraDeviceImpl.CameraDeviceCallbacks.ERROR_CAMERA_BUFFER) { + Surface errorTarget = (Surface) errorArg; + int indexOfTarget = mConfiguredSurfaces.indexOfValue(errorTarget); + if (indexOfTarget < 0) { + Log.e(TAG, "Buffer drop error reported for unknown Surface"); + } else { + errorStreamId = mConfiguredSurfaces.keyAt(indexOfTarget); + } + } if (holder == null) { return new CaptureResultExtras(ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE); } return new CaptureResultExtras(holder.getRequestId(), holder.getSubsequeceId(), /*afTriggerId*/0, /*precaptureTriggerId*/0, holder.getFrameNumber(), - /*partialResultCount*/1, /*errorStreamId*/-1); + /*partialResultCount*/1, errorStreamId); } /** @@ -105,9 +122,9 @@ public class LegacyCameraDevice implements AutoCloseable { private final CameraDeviceState.CameraDeviceStateListener mStateListener = new CameraDeviceState.CameraDeviceStateListener() { @Override - public void onError(final int errorCode, final RequestHolder holder) { + public void onError(final int errorCode, final Object errorArg, final RequestHolder holder) { if (DEBUG) { - Log.d(TAG, "onError called, errorCode = " + errorCode); + Log.d(TAG, "onError called, errorCode = " + errorCode + ", errorArg = " + errorArg); } switch (errorCode) { /* @@ -125,7 +142,7 @@ public class LegacyCameraDevice implements AutoCloseable { } } - final CaptureResultExtras extras = getExtrasFromRequest(holder); + final CaptureResultExtras extras = getExtrasFromRequest(holder, errorCode, errorArg); mResultHandler.post(new Runnable() { @Override public void run() { @@ -281,14 +298,17 @@ public class LegacyCameraDevice implements AutoCloseable { * * <p>Every surface in {@code outputs} must be non-{@code null}.</p> * - * @param outputs a list of surfaces to set. + * @param outputs a list of surfaces to set. LegacyCameraDevice will take ownership of this + * list; it must not be modified by the caller once it's passed in. * @return an error code for this binder operation, or {@link NO_ERROR} * on success. */ - public int configureOutputs(List<Surface> outputs) { + public int configureOutputs(SparseArray<Surface> outputs) { List<Pair<Surface, Size>> sizedSurfaces = new ArrayList<>(); if (outputs != null) { - for (Surface output : outputs) { + int count = outputs.size(); + for (int i = 0; i < count; i++) { + Surface output = outputs.valueAt(i); if (output == null) { Log.e(TAG, "configureOutputs - null outputs are not allowed"); return BAD_VALUE; @@ -353,7 +373,7 @@ public class LegacyCameraDevice implements AutoCloseable { } if (success) { - mConfiguredSurfaces = outputs != null ? new ArrayList<>(outputs) : null; + mConfiguredSurfaces = outputs; } else { return LegacyExceptionUtils.INVALID_OPERATION; } @@ -659,6 +679,23 @@ public class LegacyCameraDevice implements AutoCloseable { return nativeGetSurfaceId(surface); } + static List<Long> getSurfaceIds(SparseArray<Surface> surfaces) { + if (surfaces == null) { + throw new NullPointerException("Null argument surfaces"); + } + List<Long> surfaceIds = new ArrayList<>(); + int count = surfaces.size(); + for (int i = 0; i < count; i++) { + long id = getSurfaceId(surfaces.valueAt(i)); + if (id == 0) { + throw new IllegalStateException( + "Configured surface had null native GraphicBufferProducer pointer!"); + } + surfaceIds.add(id); + } + return surfaceIds; + } + static List<Long> getSurfaceIds(Collection<Surface> surfaces) { if (surfaces == null) { throw new NullPointerException("Null argument surfaces"); diff --git a/core/java/android/hardware/camera2/legacy/RequestHolder.java b/core/java/android/hardware/camera2/legacy/RequestHolder.java index 9b628fb72490..476c3debc571 100644 --- a/core/java/android/hardware/camera2/legacy/RequestHolder.java +++ b/core/java/android/hardware/camera2/legacy/RequestHolder.java @@ -41,6 +41,8 @@ public class RequestHolder { private final int mNumPreviewTargets; private volatile boolean mFailed = false; + private final Collection<Long> mJpegSurfaceIds; + /** * A builder class for {@link RequestHolder} objects. * @@ -150,13 +152,13 @@ public class RequestHolder { */ public RequestHolder build(long frameNumber) { return new RequestHolder(mRequestId, mSubsequenceId, mRequest, mRepeating, frameNumber, - mNumJpegTargets, mNumPreviewTargets); + mNumJpegTargets, mNumPreviewTargets, mJpegSurfaceIds); } } private RequestHolder(int requestId, int subsequenceId, CaptureRequest request, boolean repeating, long frameNumber, int numJpegTargets, - int numPreviewTargets) { + int numPreviewTargets, Collection<Long> jpegSurfaceIds) { mRepeating = repeating; mRequest = request; mRequestId = requestId; @@ -164,6 +166,7 @@ public class RequestHolder { mFrameNumber = frameNumber; mNumJpegTargets = numJpegTargets; mNumPreviewTargets = numPreviewTargets; + mJpegSurfaceIds = jpegSurfaceIds; } /** @@ -238,6 +241,17 @@ public class RequestHolder { } /** + * Returns true if the given surface requires jpeg buffers. + * + * @param s a {@link android.view.Surface} to check. + * @return true if the surface requires a jpeg buffer. + */ + public boolean jpegType(Surface s) + throws LegacyExceptionUtils.BufferQueueAbandonedException { + return LegacyCameraDevice.containsSurfaceId(s, mJpegSurfaceIds); + } + + /** * Mark this request as failed. */ public void failRequest() { diff --git a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java index e8ce3ec7aaa9..a3fdd56cc65c 100644 --- a/core/java/android/hardware/camera2/legacy/RequestThreadManager.java +++ b/core/java/android/hardware/camera2/legacy/RequestThreadManager.java @@ -908,8 +908,7 @@ public class RequestThreadManager { mFaceDetectMapper.mapResultFaces(result, mLastRequest); if (!holder.requestFailed()) { - mDeviceState.setCaptureResult(holder, result, - CameraDeviceState.NO_CAPTURE_ERROR); + mDeviceState.setCaptureResult(holder, result); } } if (DEBUG) { diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java index b8088f32ecaf..4756b3728009 100644 --- a/core/java/android/hardware/fingerprint/FingerprintManager.java +++ b/core/java/android/hardware/fingerprint/FingerprintManager.java @@ -815,7 +815,8 @@ public class FingerprintManager { if (groupId != reqGroupId) { Log.w(TAG, "Group id didn't match: " + groupId + " != " + reqGroupId); } - mRemovalCallback.onRemovalSucceeded(mRemovalFingerprint); + mRemovalCallback.onRemovalSucceeded(new Fingerprint(null, groupId, fingerId, + deviceId)); } } diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java index fbac58c039c6..47440de62827 100644 --- a/core/java/android/hardware/input/InputManager.java +++ b/core/java/android/hardware/input/InputManager.java @@ -16,9 +16,7 @@ package android.hardware.input; -import com.android.internal.inputmethod.InputMethodSubtypeHandle; import com.android.internal.os.SomeArgs; -import com.android.internal.util.ArrayUtils; import android.annotation.IntDef; import android.annotation.SdkConstant; diff --git a/core/java/android/hardware/input/InputManagerInternal.java b/core/java/android/hardware/input/InputManagerInternal.java index 014e73fd8aeb..10fc8e6e366a 100644 --- a/core/java/android/hardware/input/InputManagerInternal.java +++ b/core/java/android/hardware/input/InputManagerInternal.java @@ -52,4 +52,11 @@ public abstract class InputManagerInternal { */ public abstract void onInputMethodSubtypeChanged(int userId, @Nullable InputMethodInfo inputMethodInfo, @Nullable InputMethodSubtype subtype); + + /** + * Toggles Caps Lock state for input device with specific id. + * + * @param deviceId The id of input device. + */ + public abstract void toggleCapsLock(int deviceId); } diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java index ae44f1d68c3c..194b9ee58780 100644 --- a/core/java/android/hardware/location/ContextHubInfo.java +++ b/core/java/android/hardware/location/ContextHubInfo.java @@ -345,6 +345,24 @@ public class ContextHubInfo { mMemoryRegions = Arrays.copyOf(memoryRegions, memoryRegions.length); } + @Override + public String toString() { + String retVal = ""; + retVal += "Id : " + mId; + retVal += ", Name : " + mName; + retVal += "\n\tVendor : " + mVendor; + retVal += ", ToolChain : " + mToolchain; + retVal += "\n\tPlatformVersion : " + mPlatformVersion; + retVal += ", StaticSwVersion : " + mStaticSwVersion; + retVal += "\n\tPeakMips : " + mPeakMips; + retVal += ", StoppedPowerDraw : " + mStoppedPowerDrawMw + " mW"; + retVal += ", PeakPowerDraw : " + mPeakPowerDrawMw + " mW"; + retVal += "\n\tSupported sensors : " + Arrays.toString(mSupportedSensors); + retVal += "\n\tMemory Regions : " + Arrays.toString(mMemoryRegions); + + return retVal; + } + private ContextHubInfo(Parcel in) { mId = in.readInt(); mName = in.readString(); diff --git a/core/java/android/hardware/location/ContextHubService.java b/core/java/android/hardware/location/ContextHubService.java index b65e24e3b81e..2b9b97463888 100644 --- a/core/java/android/hardware/location/ContextHubService.java +++ b/core/java/android/hardware/location/ContextHubService.java @@ -18,9 +18,12 @@ package android.hardware.location; import android.Manifest; import android.content.Context; +import android.content.pm.PackageManager; import android.os.RemoteException; import android.util.Log; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; @@ -28,18 +31,17 @@ import java.util.HashMap; * @hide */ public class ContextHubService extends IContextHubService.Stub { - public static final String CONTEXTHUB_SERVICE = "contexthub_service"; private static final String TAG = "ContextHubService"; private static final String HARDWARE_PERMISSION = Manifest.permission.LOCATION_HARDWARE; private static final String ENFORCE_HW_PERMISSION_MESSAGE = "Permission '" - + HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware"; + + HARDWARE_PERMISSION + "' not granted to access ContextHub Hardware"; public static final int ANY_HUB = -1; - public static final int MSG_LOAD_NANO_APP = 5; - public static final int MSG_UNLOAD_NANO_APP = 2; + public static final int MSG_LOAD_NANO_APP = 3; + public static final int MSG_UNLOAD_NANO_APP = 4; private static final String PRE_LOADED_GENERIC_UNKNOWN = "Preloaded app, unknown"; private static final String PRE_LOADED_APP_NAME = PRE_LOADED_GENERIC_UNKNOWN; @@ -78,8 +80,8 @@ public class ContextHubService extends IContextHubService.Stub { @Override public int registerCallback(IContextHubCallback callback) throws RemoteException { checkPermissions(); - synchronized(this) { - mCallback = callback; + synchronized (this) { + mCallback = callback; } return 0; } @@ -87,10 +89,10 @@ public class ContextHubService extends IContextHubService.Stub { @Override public int[] getContextHubHandles() throws RemoteException { checkPermissions(); - int [] returnArray = new int[mContextHubInfo.length]; + int[] returnArray = new int[mContextHubInfo.length]; for (int i = 0; i < returnArray.length; ++i) { - returnArray[i] = i + 1; //valid handles from 1...n + returnArray[i] = i; Log.d(TAG, String.format("Hub %s is mapped to %d", mContextHubInfo[i].getName(), returnArray[i])); } @@ -101,7 +103,6 @@ public class ContextHubService extends IContextHubService.Stub { @Override public ContextHubInfo getContextHubInfo(int contextHubHandle) throws RemoteException { checkPermissions(); - contextHubHandle -= 1; if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) { return null; // null means fail } @@ -112,13 +113,12 @@ public class ContextHubService extends IContextHubService.Stub { @Override public int loadNanoApp(int contextHubHandle, NanoApp app) throws RemoteException { checkPermissions(); - contextHubHandle -= 1; if (!(contextHubHandle >= 0 && contextHubHandle < mContextHubInfo.length)) { - return -1; // negative handle are invalid, means failed + Log.e(TAG, "Invalid contextHubhandle " + contextHubHandle); + return -1; } - // Call Native interface here int[] msgHeader = new int[MSG_HEADER_SIZE]; msgHeader[MSG_FIELD_HUB_HANDLE] = contextHubHandle; msgHeader[MSG_FIELD_APP_INSTANCE] = OS_APP_INSTANCE; @@ -147,7 +147,7 @@ public class ContextHubService extends IContextHubService.Stub { msgHeader[MSG_FIELD_VERSION] = 0; msgHeader[MSG_FIELD_TYPE] = MSG_UNLOAD_NANO_APP; - if(nativeSendMessage(msgHeader, null) != 0) { + if (nativeSendMessage(msgHeader, null) != 0) { return -1; } @@ -157,7 +157,7 @@ public class ContextHubService extends IContextHubService.Stub { @Override public NanoAppInstanceInfo getNanoAppInstanceInfo(int nanoAppInstanceHandle) - throws RemoteException { + throws RemoteException { checkPermissions(); // This assumes that all the nanoAppInfo is current. This is reasonable // for the use cases for tightly controlled nanoApps. @@ -173,10 +173,10 @@ public class ContextHubService extends IContextHubService.Stub { checkPermissions(); ArrayList<Integer> foundInstances = new ArrayList<Integer>(); - for(Integer nanoAppInstance : mNanoAppHash.keySet()) { + for (Integer nanoAppInstance: mNanoAppHash.keySet()) { NanoAppInstanceInfo info = mNanoAppHash.get(nanoAppInstance); - if (filter.testMatch(info)){ + if (filter.testMatch(info)) { foundInstances.add(nanoAppInstance); } } @@ -191,7 +191,7 @@ public class ContextHubService extends IContextHubService.Stub { @Override public int sendMessage(int hubHandle, int nanoAppHandle, ContextHubMessage msg) - throws RemoteException { + throws RemoteException { checkPermissions(); int[] msgHeader = new int[MSG_HEADER_SIZE]; @@ -203,6 +203,32 @@ public class ContextHubService extends IContextHubService.Stub { return nativeSendMessage(msgHeader, msg.getData()); } + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (mContext.checkCallingOrSelfPermission("android.permission.DUMP") + != PackageManager.PERMISSION_GRANTED) { + pw.println("Permission Denial: can't dump contexthub_service"); + return; + } + + pw.println("Dumping ContextHub Service"); + + pw.println(""); + // dump ContextHubInfo + pw.println("=================== CONTEXT HUBS ===================="); + for (int i = 0; i < mContextHubInfo.length; i++) { + pw.println("Handle " + i + " : " + mContextHubInfo[i].toString()); + } + pw.println(""); + pw.println("=================== NANOAPPS ===================="); + // Dump nanoAppHash + for (Integer nanoAppInstance: mNanoAppHash.keySet()) { + pw.println(nanoAppInstance + " : " + mNanoAppHash.get(nanoAppInstance).toString()); + } + + // dump eventLog + } + private void checkPermissions() { mContext.enforceCallingPermission(HARDWARE_PERMISSION, ENFORCE_HW_PERMISSION_MESSAGE); } @@ -212,16 +238,16 @@ public class ContextHubService extends IContextHubService.Stub { return -1; } - synchronized(this) { + synchronized (this) { if (mCallback != null) { ContextHubMessage msg = new ContextHubMessage(header[MSG_FIELD_TYPE], - header[MSG_FIELD_VERSION], - data); + header[MSG_FIELD_VERSION], + data); try { mCallback.onMessageReceipt(header[MSG_FIELD_HUB_HANDLE], - header[MSG_FIELD_APP_INSTANCE], - msg); + header[MSG_FIELD_APP_INSTANCE], + msg); } catch (Exception e) { Log.w(TAG, "Exception " + e + " when calling remote callback"); return -1; diff --git a/core/java/android/hardware/location/MemoryRegion.java b/core/java/android/hardware/location/MemoryRegion.java index d100de257549..857434ea75b9 100644 --- a/core/java/android/hardware/location/MemoryRegion.java +++ b/core/java/android/hardware/location/MemoryRegion.java @@ -79,6 +79,33 @@ public class MemoryRegion implements Parcelable{ } @Override + public String toString() { + String mask = ""; + + if (isReadable()) { + mask += "r"; + } else { + mask += "-"; + } + + if (isWritable()) { + mask += "w"; + } else { + mask += "-"; + } + + if (isExecutable()) { + mask += "x"; + } else { + mask += "-"; + } + + String retVal = "[ " + mSizeBytesFree + "/ " + mSizeBytes + " ] : " + mask; + + return retVal; + } + + @Override public int describeContents() { return 0; } diff --git a/core/java/android/hardware/location/NanoApp.java b/core/java/android/hardware/location/NanoApp.java index b447b6245712..c8f3439aee70 100644 --- a/core/java/android/hardware/location/NanoApp.java +++ b/core/java/android/hardware/location/NanoApp.java @@ -284,4 +284,14 @@ public class NanoApp { return new NanoApp[size]; } }; + + @Override + public String toString() { + String retVal = "Id : " + mAppId; + retVal += ", Version : " + mAppVersion; + retVal += ", Name : " + mName; + retVal += ", Publisher : " + mPublisher; + + return retVal; + } } diff --git a/core/java/android/hardware/location/NanoAppInstanceInfo.java b/core/java/android/hardware/location/NanoAppInstanceInfo.java index 977f645db199..e842ec65a3e7 100644 --- a/core/java/android/hardware/location/NanoAppInstanceInfo.java +++ b/core/java/android/hardware/location/NanoAppInstanceInfo.java @@ -320,4 +320,15 @@ public class NanoAppInstanceInfo { return new NanoAppInstanceInfo[size]; } }; + + @Override + public String toString() { + String retVal = "handle : " + mHandle; + retVal += ", Id : 0x" + Long.toHexString(mAppId); + retVal += ", Version : " + mAppVersion; + retVal += ", Name : " + mName; + retVal += ", Publisher : " + mPublisher; + + return retVal; + } } diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java index 6b79a8ac438a..cc201bc78bb5 100644 --- a/core/java/android/inputmethodservice/InputMethodService.java +++ b/core/java/android/inputmethodservice/InputMethodService.java @@ -295,9 +295,7 @@ public class InputMethodService extends AbstractInputMethodService { boolean mLastShowInputRequested; int mCandidatesVisibility; CompletionInfo[] mCurCompletions; - - boolean mShowInputForced; - + boolean mFullscreenApplied; boolean mIsFullscreen; View mExtractView; @@ -422,7 +420,6 @@ public class InputMethodService extends AbstractInputMethodService { boolean wasVis = isInputViewShown(); mShowInputFlags = 0; mShowInputRequested = false; - mShowInputForced = false; doHideWindow(); clearInsetOfPreviousIme(); if (resultReceiver != null) { @@ -439,8 +436,7 @@ public class InputMethodService extends AbstractInputMethodService { public void showSoftInput(int flags, ResultReceiver resultReceiver) { if (DEBUG) Log.v(TAG, "showSoftInput()"); boolean wasVis = isInputViewShown(); - mShowInputFlags = 0; - if (onShowInputRequested(flags, false)) { + if (dispatchOnShowInputRequested(flags, false)) { try { showWindow(true); } catch (BadTokenException e) { @@ -721,7 +717,11 @@ public class InputMethodService extends AbstractInputMethodService { mShowImeWithHardKeyboard = Settings.Secure.getInt(mService.getContentResolver(), Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD, 0) != 0 ? ShowImeWithHardKeyboardType.TRUE : ShowImeWithHardKeyboardType.FALSE; - mService.updateInputViewShown(); + // In Android M and prior, state change of + // Settings.Secure.SHOW_IME_WITH_HARD_KEYBOARD has triggered + // #onConfigurationChanged(). For compatibility reasons, we reset the internal + // state as if configuration was changed. + mService.resetStateForNewConfiguration(); } } @@ -817,8 +817,8 @@ public class InputMethodService extends AbstractInputMethodService { mInitialized = false; mWindowCreated = false; mShowInputRequested = false; - mShowInputForced = false; - + mShowInputFlags = 0; + mThemeAttrs = obtainStyledAttributes(android.R.styleable.InputMethodService); mRootView = mInflater.inflate( com.android.internal.R.layout.input_method, null); @@ -888,7 +888,10 @@ public class InputMethodService extends AbstractInputMethodService { */ @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); - + resetStateForNewConfiguration(); + } + + private void resetStateForNewConfiguration() { boolean visible = mWindowVisible; int showFlags = mShowInputFlags; boolean showingInput = mShowInputRequested; @@ -903,7 +906,7 @@ public class InputMethodService extends AbstractInputMethodService { if (visible) { if (showingInput) { // If we were last showing the soft keyboard, try to do so again. - if (onShowInputRequested(showFlags, true)) { + if (dispatchOnShowInputRequested(showFlags, true)) { showWindow(true); if (completions != null) { mCurCompletions = completions; @@ -1540,20 +1543,41 @@ public class InputMethodService extends AbstractInputMethodService { return false; } } - if ((flags&InputMethod.SHOW_FORCED) != 0) { - mShowInputForced = true; - } return true; } - + + /** + * A utility method to call {{@link #onShowInputRequested(int, boolean)}} and update internal + * states depending on its result. Since {@link #onShowInputRequested(int, boolean)} is + * exposed to IME authors as an overridable public method without {@code @CallSuper}, we have + * to have this method to ensure that those internal states are always updated no matter how + * {@link #onShowInputRequested(int, boolean)} is overridden by the IME author. + * @param flags Provides additional information about the show request, + * as per {@link InputMethod#showSoftInput InputMethod.showSoftInput()}. + * @param configChange This is true if we are re-showing due to a + * configuration change. + * @return Returns true to indicate that the window should be shown. + * @see #onShowInputRequested(int, boolean) + */ + private boolean dispatchOnShowInputRequested(int flags, boolean configChange) { + final boolean result = onShowInputRequested(flags, configChange); + if (result) { + mShowInputFlags = flags; + } else { + mShowInputFlags = 0; + } + return result; + } + public void showWindow(boolean showInput) { if (DEBUG) Log.v(TAG, "Showing window: showInput=" + showInput + " mShowInputRequested=" + mShowInputRequested + " mWindowAdded=" + mWindowAdded + " mWindowCreated=" + mWindowCreated + " mWindowVisible=" + mWindowVisible - + " mInputStarted=" + mInputStarted); - + + " mInputStarted=" + mInputStarted + + " mShowInputFlags=" + mShowInputFlags); + if (mInShowWindow) { Log.w(TAG, "Re-entrance in to showWindow"); return; @@ -2573,7 +2597,6 @@ public class InputMethodService extends AbstractInputMethodService { p.println(" mShowInputRequested=" + mShowInputRequested + " mLastShowInputRequested=" + mLastShowInputRequested - + " mShowInputForced=" + mShowInputForced + " mShowInputFlags=0x" + Integer.toHexString(mShowInputFlags)); p.println(" mCandidatesVisibility=" + mCandidatesVisibility + " mFullscreenApplied=" + mFullscreenApplied diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java index f0673fffc0d8..b4523412aa83 100644 --- a/core/java/android/net/ConnectivityManager.java +++ b/core/java/android/net/ConnectivityManager.java @@ -3021,7 +3021,6 @@ public class ConnectivityManager { * * @param networkCallback The {@link NetworkCallback} that the system will call as the * system default network changes. - * @hide */ public void registerDefaultNetworkCallback(NetworkCallback networkCallback) { // This works because if the NetworkCapabilities are null, diff --git a/core/java/android/net/ConnectivityMetricsEvent.aidl b/core/java/android/net/ConnectivityMetricsEvent.aidl index da175614b588..a027d7c38140 100644 --- a/core/java/android/net/ConnectivityMetricsEvent.aidl +++ b/core/java/android/net/ConnectivityMetricsEvent.aidl @@ -17,3 +17,4 @@ package android.net; parcelable ConnectivityMetricsEvent; +parcelable ConnectivityMetricsEvent.Reference; diff --git a/core/java/android/net/ConnectivityMetricsEvent.java b/core/java/android/net/ConnectivityMetricsEvent.java index 098f1e6947a3..b5d67d38455d 100644 --- a/core/java/android/net/ConnectivityMetricsEvent.java +++ b/core/java/android/net/ConnectivityMetricsEvent.java @@ -78,4 +78,42 @@ public final class ConnectivityMetricsEvent implements Parcelable { return String.format("ConnectivityMetricsEvent(%d, %d, %d)", timestamp, componentTag, eventTag); } + + /** {@hide} */ + public static class Reference implements Parcelable { + + public long value; + + public Reference(long ref) { + this.value = ref; + } + + /** Implement the Parcelable interface */ + public static final Parcelable.Creator<Reference> CREATOR + = new Parcelable.Creator<Reference> (){ + public Reference createFromParcel(Parcel source) { + return new Reference(source.readLong()); + } + + public Reference[] newArray(int size) { + return new Reference[size]; + } + }; + + /** Implement the Parcelable interface */ + @Override + public int describeContents() { + return 0; + } + + /** Implement the Parcelable interface */ + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeLong(value); + } + + public void readFromParcel(Parcel in) { + value = in.readLong(); + } + } } diff --git a/core/java/android/net/ConnectivityMetricsLogger.java b/core/java/android/net/ConnectivityMetricsLogger.java index 3ef805017f14..eafb8acb8aeb 100644 --- a/core/java/android/net/ConnectivityMetricsLogger.java +++ b/core/java/android/net/ConnectivityMetricsLogger.java @@ -15,6 +15,7 @@ */ package android.net; +import android.os.Bundle; import android.os.Parcelable; import android.os.RemoteException; import android.os.ServiceManager; @@ -28,14 +29,24 @@ public class ConnectivityMetricsLogger { public static final String CONNECTIVITY_METRICS_LOGGER_SERVICE = "connectivity_metrics_logger"; // Component Tags - public static final int COMPONENT_TAG_CONNECTIVITY = 1; - public static final int COMPONENT_TAG_BLUETOOTH = 2; - public static final int COMPONENT_TAG_WIFI = 3; - public static final int COMPONENT_TAG_TELECOM = 4; - public static final int COMPONENT_TAG_TELEPHONY = 5; + public static final int COMPONENT_TAG_CONNECTIVITY = 0; + public static final int COMPONENT_TAG_BLUETOOTH = 1; + public static final int COMPONENT_TAG_WIFI = 2; + public static final int COMPONENT_TAG_TELECOM = 3; + public static final int COMPONENT_TAG_TELEPHONY = 4; + + public static final int NUMBER_OF_COMPONENTS = 5; + + // Event Tag + public static final int TAG_SKIPPED_EVENTS = -1; + + public static final String DATA_KEY_EVENTS_COUNT = "count"; private IConnectivityMetricsLogger mService; + private long mServiceUnblockedTimestampMillis = 0; + private int mNumSkippedEvents = 0; + public ConnectivityMetricsLogger() { mService = IConnectivityMetricsLogger.Stub.asInterface(ServiceManager.getService( CONNECTIVITY_METRICS_LOGGER_SERVICE)); @@ -46,12 +57,51 @@ public class ConnectivityMetricsLogger { if (DBG) { Log.d(TAG, "logEvent(" + componentTag + "," + eventTag + ") Service not ready"); } - } else { - try { - mService.logEvent(new ConnectivityMetricsEvent(timestamp, componentTag, eventTag, data)); - } catch (RemoteException e) { - Log.e(TAG, "Error logging event " + e.getMessage()); + return; + } + + if (mServiceUnblockedTimestampMillis > 0) { + if (System.currentTimeMillis() < mServiceUnblockedTimestampMillis) { + // Service is throttling events. + // Don't send new events because they will be dropped. + mNumSkippedEvents++; + return; + } + } + + ConnectivityMetricsEvent skippedEventsEvent = null; + if (mNumSkippedEvents > 0) { + // Log number of skipped events + Bundle b = new Bundle(); + b.putInt(DATA_KEY_EVENTS_COUNT, mNumSkippedEvents); + skippedEventsEvent = new ConnectivityMetricsEvent(mServiceUnblockedTimestampMillis, + componentTag, TAG_SKIPPED_EVENTS, b); + + mServiceUnblockedTimestampMillis = 0; + } + + ConnectivityMetricsEvent event = new ConnectivityMetricsEvent(timestamp, componentTag, + eventTag, data); + + try { + long result; + if (skippedEventsEvent == null) { + result = mService.logEvent(event); + } else { + result = mService.logEvents(new ConnectivityMetricsEvent[] + {skippedEventsEvent, event}); + } + + if (result == 0) { + mNumSkippedEvents = 0; + } else { + mNumSkippedEvents++; + if (result > 0) { // events are throttled + mServiceUnblockedTimestampMillis = result; + } } + } catch (RemoteException e) { + Log.e(TAG, "Error logging event " + e.getMessage()); } } } diff --git a/core/java/android/net/DnsPinger.java b/core/java/android/net/DnsPinger.java deleted file mode 100644 index 7acf3f556595..000000000000 --- a/core/java/android/net/DnsPinger.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net; - -import android.content.Context; -import android.os.Handler; -import android.os.Looper; -import android.os.Message; -import android.os.SystemClock; -import android.provider.Settings; -import android.util.Log; - -import com.android.internal.util.Protocol; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.DatagramSocket; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.SocketTimeoutException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; -import java.util.Random; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * Performs a simple DNS "ping" by sending a "server status" query packet to the - * DNS server. As long as the server replies, we consider it a success. - * <p> - * We do not use a simple hostname lookup because that could be cached and the - * API may not differentiate between a time out and a failure lookup (which we - * really care about). - * <p> - * - * @hide - */ -public final class DnsPinger extends Handler { - private static final boolean DBG = false; - - private static final int RECEIVE_POLL_INTERVAL_MS = 200; - private static final int DNS_PORT = 53; - - /** Short socket timeout so we don't block one any 'receive' call */ - private static final int SOCKET_TIMEOUT_MS = 1; - - /** Used to generate IDs */ - private static final Random sRandom = new Random(); - private static final AtomicInteger sCounter = new AtomicInteger(); - - private ConnectivityManager mConnectivityManager = null; - private final Context mContext; - private final int mConnectionType; - private final Handler mTarget; - private final ArrayList<InetAddress> mDefaultDns; - private String TAG; - - //Invalidates old dns requests upon a cancel - private AtomicInteger mCurrentToken = new AtomicInteger(); - - private static final int BASE = Protocol.BASE_DNS_PINGER; - - /** - * Async response packet for dns pings. - * arg1 is the ID of the ping, also returned by {@link #pingDnsAsync(InetAddress, int, int)} - * arg2 is the delay, or is negative on error. - */ - public static final int DNS_PING_RESULT = BASE; - /** An error code for a {@link #DNS_PING_RESULT} packet */ - public static final int TIMEOUT = -1; - /** An error code for a {@link #DNS_PING_RESULT} packet */ - public static final int SOCKET_EXCEPTION = -2; - - /** - * Send a new ping via a socket. arg1 is ID, arg2 is timeout, obj is InetAddress to ping - */ - private static final int ACTION_PING_DNS = BASE + 1; - private static final int ACTION_LISTEN_FOR_RESPONSE = BASE + 2; - private static final int ACTION_CANCEL_ALL_PINGS = BASE + 3; - - private List<ActivePing> mActivePings = new ArrayList<ActivePing>(); - private int mEventCounter; - - private class ActivePing { - DatagramSocket socket; - int internalId; - short packetId; - int timeout; - Integer result; - long start = SystemClock.elapsedRealtime(); - } - - /* Message argument for ACTION_PING_DNS */ - private class DnsArg { - InetAddress dns; - int seq; - - DnsArg(InetAddress d, int s) { - dns = d; - seq = s; - } - } - - public DnsPinger(Context context, String TAG, Looper looper, - Handler target, int connectionType) { - super(looper); - this.TAG = TAG; - mContext = context; - mTarget = target; - mConnectionType = connectionType; - if (!ConnectivityManager.isNetworkTypeValid(connectionType)) { - throw new IllegalArgumentException("Invalid connectionType in constructor: " - + connectionType); - } - mDefaultDns = new ArrayList<InetAddress>(); - mDefaultDns.add(getDefaultDns()); - mEventCounter = 0; - } - - @Override - public void handleMessage(Message msg) { - switch (msg.what) { - case ACTION_PING_DNS: - DnsArg dnsArg = (DnsArg) msg.obj; - if (dnsArg.seq != mCurrentToken.get()) { - break; - } - try { - ActivePing newActivePing = new ActivePing(); - InetAddress dnsAddress = dnsArg.dns; - newActivePing.internalId = msg.arg1; - newActivePing.timeout = msg.arg2; - newActivePing.socket = new DatagramSocket(); - // Set some socket properties - newActivePing.socket.setSoTimeout(SOCKET_TIMEOUT_MS); - - // Try to bind but continue ping if bind fails - try { - newActivePing.socket.setNetworkInterface(NetworkInterface.getByName( - getCurrentLinkProperties().getInterfaceName())); - } catch (Exception e) { - loge("sendDnsPing::Error binding to socket " + e); - } - - newActivePing.packetId = (short) sRandom.nextInt(); - byte[] buf = mDnsQuery.clone(); - buf[0] = (byte) (newActivePing.packetId >> 8); - buf[1] = (byte) newActivePing.packetId; - - // Send the DNS query - DatagramPacket packet = new DatagramPacket(buf, - buf.length, dnsAddress, DNS_PORT); - if (DBG) { - log("Sending a ping " + newActivePing.internalId + - " to " + dnsAddress.getHostAddress() - + " with packetId " + newActivePing.packetId + "."); - } - - newActivePing.socket.send(packet); - mActivePings.add(newActivePing); - mEventCounter++; - sendMessageDelayed(obtainMessage(ACTION_LISTEN_FOR_RESPONSE, mEventCounter, 0), - RECEIVE_POLL_INTERVAL_MS); - } catch (IOException e) { - sendResponse(msg.arg1, -9999, SOCKET_EXCEPTION); - } - break; - case ACTION_LISTEN_FOR_RESPONSE: - if (msg.arg1 != mEventCounter) { - break; - } - for (ActivePing curPing : mActivePings) { - try { - /** Each socket will block for {@link #SOCKET_TIMEOUT_MS} in receive() */ - byte[] responseBuf = new byte[2]; - DatagramPacket replyPacket = new DatagramPacket(responseBuf, 2); - curPing.socket.receive(replyPacket); - // Check that ID field matches (we're throwing out the rest of the packet) - if (responseBuf[0] == (byte) (curPing.packetId >> 8) && - responseBuf[1] == (byte) curPing.packetId) { - curPing.result = - (int) (SystemClock.elapsedRealtime() - curPing.start); - } else { - if (DBG) { - log("response ID didn't match, ignoring packet"); - } - } - } catch (SocketTimeoutException e) { - // A timeout here doesn't mean anything - squelsh this exception - } catch (Exception e) { - if (DBG) { - log("DnsPinger.pingDns got socket exception: " + e); - } - curPing.result = SOCKET_EXCEPTION; - } - } - Iterator<ActivePing> iter = mActivePings.iterator(); - while (iter.hasNext()) { - ActivePing curPing = iter.next(); - if (curPing.result != null) { - sendResponse(curPing.internalId, curPing.packetId, curPing.result); - curPing.socket.close(); - iter.remove(); - } else if (SystemClock.elapsedRealtime() > - curPing.start + curPing.timeout) { - sendResponse(curPing.internalId, curPing.packetId, TIMEOUT); - curPing.socket.close(); - iter.remove(); - } - } - if (!mActivePings.isEmpty()) { - sendMessageDelayed(obtainMessage(ACTION_LISTEN_FOR_RESPONSE, mEventCounter, 0), - RECEIVE_POLL_INTERVAL_MS); - } - break; - case ACTION_CANCEL_ALL_PINGS: - for (ActivePing activePing : mActivePings) - activePing.socket.close(); - mActivePings.clear(); - break; - } - } - - /** - * Returns a list of DNS addresses, coming from either the link properties of the - * specified connection or the default system DNS if the link properties has no dnses. - * @return a non-empty non-null list - */ - public List<InetAddress> getDnsList() { - LinkProperties curLinkProps = getCurrentLinkProperties(); - if (curLinkProps == null) { - loge("getCurLinkProperties:: LP for type" + mConnectionType + " is null!"); - return mDefaultDns; - } - - Collection<InetAddress> dnses = curLinkProps.getDnsServers(); - if (dnses == null || dnses.size() == 0) { - loge("getDns::LinkProps has null dns - returning default"); - return mDefaultDns; - } - - return new ArrayList<InetAddress>(dnses); - } - - /** - * Send a ping. The response will come via a {@link #DNS_PING_RESULT} to the handler - * specified at creation. - * @param dns address of dns server to ping - * @param timeout timeout for ping - * @return an ID field, which will also be included in the {@link #DNS_PING_RESULT} message. - */ - public int pingDnsAsync(InetAddress dns, int timeout, int delay) { - int id = sCounter.incrementAndGet(); - sendMessageDelayed(obtainMessage(ACTION_PING_DNS, id, timeout, - new DnsArg(dns, mCurrentToken.get())), delay); - return id; - } - - public void cancelPings() { - mCurrentToken.incrementAndGet(); - obtainMessage(ACTION_CANCEL_ALL_PINGS).sendToTarget(); - } - - private void sendResponse(int internalId, int externalId, int responseVal) { - if(DBG) { - log("Responding to packet " + internalId + - " externalId " + externalId + - " and val " + responseVal); - } - mTarget.sendMessage(obtainMessage(DNS_PING_RESULT, internalId, responseVal)); - } - - private LinkProperties getCurrentLinkProperties() { - if (mConnectivityManager == null) { - mConnectivityManager = (ConnectivityManager) mContext.getSystemService( - Context.CONNECTIVITY_SERVICE); - } - - return mConnectivityManager.getLinkProperties(mConnectionType); - } - - private InetAddress getDefaultDns() { - String dns = Settings.Global.getString(mContext.getContentResolver(), - Settings.Global.DEFAULT_DNS_SERVER); - if (dns == null || dns.length() == 0) { - dns = mContext.getResources().getString( - com.android.internal.R.string.config_default_dns_server); - } - try { - return NetworkUtils.numericToInetAddress(dns); - } catch (IllegalArgumentException e) { - loge("getDefaultDns::malformed default dns address"); - return null; - } - } - - private static final byte[] mDnsQuery = new byte[] { - 0, 0, // [0-1] is for ID (will set each time) - 1, 0, // [2-3] are flags. Set byte[2] = 1 for recursion desired (RD) on. Currently on. - 0, 1, // [4-5] bytes are for number of queries (QCOUNT) - 0, 0, // [6-7] unused count field for dns response packets - 0, 0, // [8-9] unused count field for dns response packets - 0, 0, // [10-11] unused count field for dns response packets - 3, 'w', 'w', 'w', - 6, 'g', 'o', 'o', 'g', 'l', 'e', - 3, 'c', 'o', 'm', - 0, // null terminator of address (also called empty TLD) - 0, 1, // QTYPE, set to 1 = A (host address) - 0, 1 // QCLASS, set to 1 = IN (internet) - }; - - private void log(String s) { - Log.d(TAG, s); - } - - private void loge(String s) { - Log.e(TAG, s); - } -} diff --git a/core/java/android/net/IConnectivityMetricsLogger.aidl b/core/java/android/net/IConnectivityMetricsLogger.aidl index 27786712a5c5..a83a01935253 100644 --- a/core/java/android/net/IConnectivityMetricsLogger.aidl +++ b/core/java/android/net/IConnectivityMetricsLogger.aidl @@ -16,15 +16,28 @@ package android.net; +import android.app.PendingIntent; import android.net.ConnectivityMetricsEvent; -import android.net.IConnectivityMetricsLoggerSubscriber; /** {@hide} */ interface IConnectivityMetricsLogger { - void logEvent(in ConnectivityMetricsEvent event); - void logEvents(in ConnectivityMetricsEvent[] events); + /** + * @return 0 on success + * <0 if error happened + * >0 timestamp after which new events will be accepted + */ + long logEvent(in ConnectivityMetricsEvent event); + long logEvents(in ConnectivityMetricsEvent[] events); - boolean subscribe(in IConnectivityMetricsLoggerSubscriber subscriber); - void unsubscribe(in IConnectivityMetricsLoggerSubscriber subscriber); + /** + * @param reference of the last event previously returned. The function will return + * events following it. + * If 0 then all events will be returned. + * After the function call it will contain reference of the last event. + */ + ConnectivityMetricsEvent[] getEvents(inout ConnectivityMetricsEvent.Reference reference); + + boolean register(in PendingIntent newEventsIntent); + void unregister(in PendingIntent newEventsIntent); } diff --git a/core/java/android/net/NetworkScorerAppManager.java b/core/java/android/net/NetworkScorerAppManager.java index e555fa412a5b..29291ca90467 100644 --- a/core/java/android/net/NetworkScorerAppManager.java +++ b/core/java/android/net/NetworkScorerAppManager.java @@ -19,11 +19,9 @@ package android.net; import android.Manifest; import android.Manifest.permission; import android.annotation.Nullable; -import android.app.AppOpsManager; import android.content.Context; import android.content.Intent; import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.UserHandle; @@ -69,12 +67,32 @@ public final class NetworkScorerAppManager { */ public final String mConfigurationActivityClassName; + /** + * Optional class name of the scoring service we can bind to. Null if none is set. + */ + public final String mScoringServiceClassName; + public NetworkScorerAppData(String packageName, int packageUid, CharSequence scorerName, - @Nullable String configurationActivityClassName) { + @Nullable String configurationActivityClassName, + @Nullable String scoringServiceClassName) { mScorerName = scorerName; mPackageName = packageName; mPackageUid = packageUid; mConfigurationActivityClassName = configurationActivityClassName; + mScoringServiceClassName = scoringServiceClassName; + } + + @Override + public String toString() { + final StringBuilder sb = new StringBuilder("NetworkScorerAppData{"); + sb.append("mPackageName='").append(mPackageName).append('\''); + sb.append(", mPackageUid=").append(mPackageUid); + sb.append(", mScorerName=").append(mScorerName); + sb.append(", mConfigurationActivityClassName='").append(mConfigurationActivityClassName) + .append('\''); + sb.append(", mScoringServiceClassName='").append(mScoringServiceClassName).append('\''); + sb.append('}'); + return sb.toString(); } } @@ -128,18 +146,27 @@ public final class NetworkScorerAppManager { Intent intent = new Intent(NetworkScoreManager.ACTION_CUSTOM_ENABLE); intent.setPackage(receiverInfo.packageName); List<ResolveInfo> configActivities = pm.queryIntentActivities(intent, 0 /* flags */); - if (!configActivities.isEmpty()) { + if (configActivities != null && !configActivities.isEmpty()) { ActivityInfo activityInfo = configActivities.get(0).activityInfo; if (activityInfo != null) { configurationActivityClassName = activityInfo.name; } } + // Find the scoring service class we can bind to, if any. + String scoringServiceClassName = null; + Intent serviceIntent = new Intent(NetworkScoreManager.ACTION_SCORE_NETWORKS); + serviceIntent.setPackage(receiverInfo.packageName); + ResolveInfo resolveServiceInfo = pm.resolveService(serviceIntent, 0 /* flags */); + if (resolveServiceInfo != null && resolveServiceInfo.serviceInfo != null) { + scoringServiceClassName = resolveServiceInfo.serviceInfo.name; + } + // NOTE: loadLabel will attempt to load the receiver's label and fall back to the // app label if none is present. scorers.add(new NetworkScorerAppData(receiverInfo.packageName, receiverInfo.applicationInfo.uid, receiverInfo.loadLabel(pm), - configurationActivityClassName)); + configurationActivityClassName, scoringServiceClassName)); } return scorers; diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 8e2dd6b85c00..c4528372987f 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -448,19 +448,41 @@ public abstract class BatteryStats implements Parcelable { public abstract Timer getForegroundActivityTimer(); public abstract Timer getBluetoothScanTimer(); - // Time this uid has any processes in the top state. + // Note: the following times are disjoint. They can be added together to find the + // total time a uid has had any processes running at all. + + /** + * Time this uid has any processes in the top state (or above such as persistent). + */ public static final int PROCESS_STATE_TOP = 0; - // Time this uid has any process with a started out bound foreground service. + /** + * Time this uid has any process with a started out bound foreground service, but + * none in the "top" state. + */ public static final int PROCESS_STATE_FOREGROUND_SERVICE = 1; - // Time this uid has any process that is top while the device is sleeping. + /** + * Time this uid has any process that is top while the device is sleeping, but none + * in the "foreground service" or better state. + */ public static final int PROCESS_STATE_TOP_SLEEPING = 2; - // Time this uid has any process in an active foreground state. + /** + * Time this uid has any process in an active foreground state, but none in the + * "top sleeping" or better state. + */ public static final int PROCESS_STATE_FOREGROUND = 3; - // Time this uid has any process in an active background state. + /** + * Time this uid has any process in an active background state, but none in the + * "foreground" or better state. + */ public static final int PROCESS_STATE_BACKGROUND = 4; - // Time this uid has any processes running at all. + /** + * Time this uid has any processes that are sitting around cached, not in one of the + * other active states. + */ public static final int PROCESS_STATE_CACHED = 5; - // Total number of process states we track. + /** + * Total number of process states we track. + */ public static final int NUM_PROCESS_STATE = 6; static final String[] PROCESS_STATE_NAMES = { diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java index 878b7a0e8e10..3c7c962eaa12 100644 --- a/core/java/android/os/Handler.java +++ b/core/java/android/os/Handler.java @@ -231,6 +231,18 @@ public class Handler { mAsynchronous = async; } + /** {@hide} */ + public String getTraceName(Message message) { + final StringBuilder sb = new StringBuilder(); + sb.append(getClass().getName()).append(": "); + if (message.callback != null) { + sb.append(message.callback.getClass().getName()); + } else { + sb.append("#").append(message.what); + } + return sb.toString(); + } + /** * Returns a string representing the name of the specified message. * The default implementation will either return the class name of the @@ -739,8 +751,8 @@ public class Handler { message.callback.run(); } - final MessageQueue mQueue; final Looper mLooper; + final MessageQueue mQueue; final Callback mCallback; final boolean mAsynchronous; IMessenger mMessenger; diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl index 24a6cdf83b7a..68b0a9fb2969 100644 --- a/core/java/android/os/INetworkManagementService.aidl +++ b/core/java/android/os/INetworkManagementService.aidl @@ -328,11 +328,6 @@ interface INetworkManagementService */ void setDnsServersForNetwork(int netId, in String[] servers, String domains); - /** - * Flush the DNS cache associated with the specified network. - */ - void flushNetworkDnsCache(int netId); - void setFirewallEnabled(boolean enabled); boolean isFirewallEnabled(); void setFirewallInterfaceRule(String iface, boolean allow); diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java index 34c880f60520..b58ff1fd4755 100644 --- a/core/java/android/os/Looper.java +++ b/core/java/android/os/Looper.java @@ -72,6 +72,7 @@ public final class Looper { final Thread mThread; private Printer mLogging; + private long mTraceTag; /** Initialize the current thread as a looper. * This gives you a chance to create handlers that then reference @@ -139,13 +140,23 @@ public final class Looper { } // This must be in a local variable, in case a UI event sets the logger - Printer logging = me.mLogging; + final Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } - msg.target.dispatchMessage(msg); + final long traceTag = me.mTraceTag; + if (traceTag != 0) { + Trace.traceBegin(traceTag, msg.target.getTraceName(msg)); + } + try { + msg.target.dispatchMessage(msg); + } finally { + if (traceTag != 0) { + Trace.traceEnd(traceTag); + } + } if (logging != null) { logging.println("<<<<< Finished to " + msg.target + " " + msg.callback); @@ -208,6 +219,11 @@ public final class Looper { mLogging = printer; } + /** {@hide} */ + public void setTraceTag(long traceTag) { + mTraceTag = traceTag; + } + /** * Quits the looper. * <p> diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java index a0a16f1a8930..92edc62617cb 100644 --- a/core/java/android/os/PowerManager.java +++ b/core/java/android/os/PowerManager.java @@ -221,7 +221,7 @@ public final class PowerManager { /** * Wake lock level: Enables Sustained Performance Mode. * <p> - * This is used by Gaming and VR applications to ensure the device provides + * This is used by Gaming and VR applications to ensure the device * will provide consistent performance over a large amount of time. * </p> */ @@ -1031,6 +1031,16 @@ public final class PowerManager { } /** + * Returns True if the device supports Sustained Performance Mode. + * Applications Should check if the device supports this mode, before + * using {@link #SUSTAINED_PERFORMANCE_WAKE_LOCK}. + */ + public boolean isSustainedPerformanceModeSupported() { + return mContext.getResources().getBoolean( + com.android.internal.R.bool.config_sustainedPerformanceModeSupported); + } + + /** * Intent that is broadcast when the state of {@link #isPowerSaveMode()} changes. * This broadcast is only sent to registered receivers. */ diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 720d3f7b860a..f2e316cf214f 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -1178,23 +1178,7 @@ public class StorageManager { /** {@hide} */ public static File maybeTranslateEmulatedPathToInternal(File path) { - final IMountService mountService = IMountService.Stub.asInterface( - ServiceManager.getService("mount")); - try { - final VolumeInfo[] vols = mountService.getVolumes(0); - for (VolumeInfo vol : vols) { - if ((vol.getType() == VolumeInfo.TYPE_EMULATED - || vol.getType() == VolumeInfo.TYPE_PUBLIC) && vol.isMountedReadable()) { - final File internalPath = FileUtils.rewriteAfterRename(vol.getPath(), - vol.getInternalPath(), path); - if (internalPath != null && internalPath.exists()) { - return internalPath; - } - } - } - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } + // Disabled now that FUSE has been replaced by sdcardfs return path; } diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java index d41bc070d6c1..b1cad0538d31 100644 --- a/core/java/android/preference/Preference.java +++ b/core/java/android/preference/Preference.java @@ -1184,10 +1184,9 @@ public class Preference implements Comparable<Preference> { /** * Called when the Preference hierarchy has been attached to the - * {@link PreferenceActivity} or {@link PreferenceFragment}. This can - * also be called when this Preference has been attached to a group - * that was already attached to the {@link PreferenceActivity} or - * {@link PreferenceFragment}. + * {@link PreferenceActivity}. This can also be called when this + * Preference has been attached to a group that was already attached + * to the {@link PreferenceActivity}. */ protected void onAttachedToActivity() { // At this point, the hierarchy that this preference is in is connected @@ -1195,16 +1194,6 @@ public class Preference implements Comparable<Preference> { registerDependency(); } - /** - * Called when the Preference hierarchy has been detached from the - * {@link PreferenceActivity} or {@link PreferenceFragment}. This can - * also be called when this Preference has been removed from a group - * that was already attached to the {@link PreferenceActivity} or - * {@link PreferenceFragment}. - */ - protected void onDetachedFromActivity() { - } - private void registerDependency() { if (TextUtils.isEmpty(mDependencyKey)) return; diff --git a/core/java/android/preference/PreferenceGroup.java b/core/java/android/preference/PreferenceGroup.java index 13c36614729e..f17506b98a2b 100644 --- a/core/java/android/preference/PreferenceGroup.java +++ b/core/java/android/preference/PreferenceGroup.java @@ -186,11 +186,7 @@ public abstract class PreferenceGroup extends Preference implements GenericInfla private boolean removePreferenceInt(Preference preference) { synchronized(this) { preference.onPrepareForRemoval(); - boolean success = mPreferenceList.remove(preference); - if (mAttachedToActivity) { - preference.onDetachedFromActivity(); - } - return success; + return mPreferenceList.remove(preference); } } @@ -266,7 +262,7 @@ public abstract class PreferenceGroup extends Preference implements GenericInfla protected boolean isOnSameScreenAsChildren() { return true; } - + @Override protected void onAttachedToActivity() { super.onAttachedToActivity(); @@ -283,17 +279,11 @@ public abstract class PreferenceGroup extends Preference implements GenericInfla } @Override - protected void onDetachedFromActivity() { - super.onDetachedFromActivity(); - + protected void onPrepareForRemoval() { + super.onPrepareForRemoval(); + // We won't be attached to the activity anymore mAttachedToActivity = false; - - // Dispatch to all contained preferences - final int preferenceCount = getPreferenceCount(); - for (int i = 0; i < preferenceCount; i++) { - getPreference(i).onDetachedFromActivity(); - } } @Override diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java index 73174e310e11..1a6b06f33199 100644 --- a/core/java/android/preference/PreferenceManager.java +++ b/core/java/android/preference/PreferenceManager.java @@ -519,9 +519,6 @@ public class PreferenceManager { */ boolean setPreferences(PreferenceScreen preferenceScreen) { if (preferenceScreen != mPreferenceScreen) { - if (mPreferenceScreen != null) { - mPreferenceScreen.onDetachedFromActivity(); - } mPreferenceScreen = preferenceScreen; return true; } @@ -830,11 +827,7 @@ public class PreferenceManager { */ void dispatchActivityDestroy() { List<OnActivityDestroyListener> list = null; - - if (mPreferenceScreen != null) { - mPreferenceScreen.onDetachedFromActivity(); - mPreferenceScreen = null; - } + synchronized (this) { if (mActivityDestroyListeners != null) { list = new ArrayList<OnActivityDestroyListener>(mActivityDestroyListeners); diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 69dd9e5abe69..2a3c3fe2e5c1 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -1569,9 +1569,8 @@ public final class Settings { * @return true if the calling app can draw on top of other apps, false otherwise. */ public static boolean canDrawOverlays(Context context) { - int uid = Binder.getCallingUid(); - return Settings.isCallingPackageAllowedToDrawOverlays(context, uid, Settings - .getPackageNameForUid(context, uid), false); + return Settings.isCallingPackageAllowedToDrawOverlays(context, Process.myUid(), + context.getOpPackageName(), false); } /** @@ -3885,9 +3884,8 @@ public final class Settings { * @return true if the calling app can write to system settings, false otherwise */ public static boolean canWrite(Context context) { - int uid = Binder.getCallingUid(); - return isCallingPackageAllowedToWriteSettings(context, uid, getPackageNameForUid( - context, uid), false); + return isCallingPackageAllowedToWriteSettings(context, Process.myUid(), + context.getOpPackageName(), false); } } @@ -8308,6 +8306,16 @@ public final class Settings { public static final String BOOT_COUNT = "boot_count"; /** + * Whether the safe boot is disallowed. + * + * <p>This setting should have the identical value as the corresponding user restriction. + * The purpose of the setting is to make the restriction available in early boot stages + * before the user restrictions are loaded. + * @hide + */ + public static final String SAFE_BOOT_DISALLOWED = "safe_boot_disallowed"; + + /** * Settings to backup. This is here so that it's in the same place as the settings * keys and easy to update. * diff --git a/core/java/android/service/vr/IVrManager.aidl b/core/java/android/service/vr/IVrManager.aidl new file mode 100644 index 000000000000..62ecab3583cd --- /dev/null +++ b/core/java/android/service/vr/IVrManager.aidl @@ -0,0 +1,46 @@ +/** + * Copyright (c) 2016, 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.service.vr; + +import android.service.vr.IVrStateCallbacks; + +/** @hide */ +interface IVrManager { + + /** + * Add a callback to be notified when VR mode state changes. + * + * @param cb the callback instance to add. + */ + void registerListener(in IVrStateCallbacks cb); + + /** + * Remove the callack from the current set of registered callbacks. + * + * @param cb the callback to remove. + */ + void unregisterListener(in IVrStateCallbacks cb); + + /** + * Return current VR mode state. + * + * @return {@code true} if VR mode is enabled. + */ + boolean getVrModeState(); + +} + diff --git a/core/java/android/net/IConnectivityMetricsLoggerSubscriber.aidl b/core/java/android/service/vr/IVrStateCallbacks.aidl index a2c62cdaee97..c4fdcd071fe5 100644 --- a/core/java/android/net/IConnectivityMetricsLoggerSubscriber.aidl +++ b/core/java/android/service/vr/IVrStateCallbacks.aidl @@ -1,11 +1,11 @@ -/* - * Copyright (C) 2016 The Android Open Source Project +/** + * Copyright (c) 2016, 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 + * 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, @@ -14,12 +14,11 @@ * limitations under the License. */ -package android.net; +package android.service.vr; -import android.net.ConnectivityMetricsEvent; +/** @hide */ +oneway interface IVrStateCallbacks { -/** {@hide} */ -oneway interface IConnectivityMetricsLoggerSubscriber { + void onVrStateChanged(in boolean enabled); - void onEvents(in ConnectivityMetricsEvent[] events); } diff --git a/core/java/android/text/BoringLayout.java b/core/java/android/text/BoringLayout.java index 328fe99a7f93..7f0021d729d0 100644 --- a/core/java/android/text/BoringLayout.java +++ b/core/java/android/text/BoringLayout.java @@ -183,8 +183,10 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback if (includepad) { spacing = metrics.bottom - metrics.top; + mDesc = metrics.bottom; } else { spacing = metrics.descent - metrics.ascent; + mDesc = metrics.descent; } mBottom = spacing; @@ -208,8 +210,6 @@ public class BoringLayout extends Layout implements TextUtils.EllipsizeCallback mTopPadding = metrics.top - metrics.ascent; mBottomPadding = metrics.bottom - metrics.descent; } - - mDesc = spacing + mBottomPadding + (includepad ? metrics.top : metrics.ascent); } /** diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index 6a33579153bc..94ce57ac7cb9 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -1132,22 +1132,12 @@ public class StaticLayout extends Layout { @Override public int getLineTop(int line) { - int top = mLines[mColumns * line + TOP]; - if (mMaximumVisibleLineCount > 0 && line >= mMaximumVisibleLineCount && - line != mLineCount) { - top += getBottomPadding(); - } - return top; + return mLines[mColumns * line + TOP]; } @Override public int getLineDescent(int line) { - int descent = mLines[mColumns * line + DESCENT]; - if (mMaximumVisibleLineCount > 0 && line >= mMaximumVisibleLineCount - 1 && // -1 intended - line != mLineCount) { - descent += getBottomPadding(); - } - return descent; + return mLines[mColumns * line + DESCENT]; } @Override diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java index 4888877cb28b..86318e91b885 100644 --- a/core/java/android/view/ContextThemeWrapper.java +++ b/core/java/android/view/ContextThemeWrapper.java @@ -101,6 +101,15 @@ public class ContextThemeWrapper extends ContextWrapper { mOverrideConfiguration = new Configuration(overrideConfiguration); } + /** + * Used by ActivityThread to apply the overridden configuration to onConfigurationChange + * callbacks. + * @hide + */ + public Configuration getOverrideConfiguration() { + return mOverrideConfiguration; + } + @Override public AssetManager getAssets() { // Ensure we're returning assets with the correct configuration. diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java index e0c6770ecb38..636384c616e0 100644 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -1870,6 +1870,11 @@ public class KeyEvent extends InputEvent implements Parcelable { return keyCode == KeyEvent.KEYCODE_META_LEFT || keyCode == KeyEvent.KEYCODE_META_RIGHT; } + /** @hide */ + public static final boolean isAltKey(int keyCode) { + return keyCode == KeyEvent.KEYCODE_ALT_LEFT || keyCode == KeyEvent.KEYCODE_ALT_RIGHT; + } + /** {@inheritDoc} */ @Override public final int getDeviceId() { diff --git a/core/java/android/view/NotificationHeaderView.java b/core/java/android/view/NotificationHeaderView.java index cff9d8e93c98..37da8695a1ad 100644 --- a/core/java/android/view/NotificationHeaderView.java +++ b/core/java/android/view/NotificationHeaderView.java @@ -22,7 +22,6 @@ import android.graphics.Rect; import android.util.AttributeSet; import android.widget.ImageView; import android.widget.RemoteViews; -import android.widget.TextView; import java.util.ArrayList; @@ -37,7 +36,7 @@ public class NotificationHeaderView extends ViewGroup { private final int mChildMinWidth; private final int mContentEndMargin; private View mAppName; - private View mSubTextView; + private View mHeaderText; private OnClickListener mExpandClickListener; private HeaderTouchListener mTouchListener = new HeaderTouchListener(); private ImageView mExpandButton; @@ -73,11 +72,10 @@ public class NotificationHeaderView extends ViewGroup { protected void onFinishInflate() { super.onFinishInflate(); mAppName = findViewById(com.android.internal.R.id.app_name_text); - mSubTextView = findViewById(com.android.internal.R.id.header_sub_text); + mHeaderText = findViewById(com.android.internal.R.id.header_text); mExpandButton = (ImageView) findViewById(com.android.internal.R.id.expand_button); mIcon = findViewById(com.android.internal.R.id.icon); mProfileBadge = findViewById(com.android.internal.R.id.profile_badge); - mInfo = findViewById(com.android.internal.R.id.header_content_info); } @Override @@ -105,15 +103,7 @@ public class NotificationHeaderView extends ViewGroup { } if (totalWidth > givenWidth) { int overFlow = totalWidth - givenWidth; - // We are overflowing, lets shrink the info first - final int infoWidth = mInfo.getMeasuredWidth(); - if (mInfo.getVisibility() != GONE && infoWidth > mChildMinWidth) { - int newSize = infoWidth - Math.min(infoWidth - mChildMinWidth, overFlow); - int childWidthSpec = MeasureSpec.makeMeasureSpec(newSize, MeasureSpec.AT_MOST); - mInfo.measure(childWidthSpec, wrapContentHeightSpec); - overFlow -= infoWidth - newSize; - } - // still overflowing, lets shrink the app name now + // We are overflowing, lets shrink the app name first final int appWidth = mAppName.getMeasuredWidth(); if (overFlow > 0 && mAppName.getVisibility() != GONE && appWidth > mChildMinWidth) { int newSize = appWidth - Math.min(appWidth - mChildMinWidth, overFlow); @@ -121,13 +111,13 @@ public class NotificationHeaderView extends ViewGroup { mAppName.measure(childWidthSpec, wrapContentHeightSpec); overFlow -= appWidth - newSize; } - // still overflowing, finaly we shrink the subtext - if (overFlow > 0 && mSubTextView.getVisibility() != GONE) { + // still overflowing, finaly we shrink the header text + if (overFlow > 0 && mHeaderText.getVisibility() != GONE) { // we're still too big - final int subTextWidth = mSubTextView.getMeasuredWidth(); - int newSize = Math.max(0, subTextWidth - overFlow); + final int textWidth = mHeaderText.getMeasuredWidth(); + int newSize = Math.max(0, textWidth - overFlow); int childWidthSpec = MeasureSpec.makeMeasureSpec(newSize, MeasureSpec.AT_MOST); - mSubTextView.measure(childWidthSpec, wrapContentHeightSpec); + mHeaderText.measure(childWidthSpec, wrapContentHeightSpec); } } setMeasuredDimension(givenWidth, givenHeight); diff --git a/core/java/android/view/RenderNode.java b/core/java/android/view/RenderNode.java index 4ffb3d3b64bf..ab4cbcf21bed 100644 --- a/core/java/android/view/RenderNode.java +++ b/core/java/android/view/RenderNode.java @@ -307,18 +307,22 @@ public class RenderNode { * * Deep copies the data into native to simplify reference ownership. */ - public boolean setOutline(Outline outline) { + public boolean setOutline(@Nullable Outline outline) { if (outline == null) { return nSetOutlineNone(mNativeRenderNode); - } else if (outline.isEmpty()) { - return nSetOutlineEmpty(mNativeRenderNode); - } else if (outline.mRect != null) { - return nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top, - outline.mRect.right, outline.mRect.bottom, outline.mRadius, outline.mAlpha); - } else if (outline.mPath != null) { - return nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath, - outline.mAlpha); } + + switch(outline.mMode) { + case Outline.MODE_EMPTY: + return nSetOutlineEmpty(mNativeRenderNode); + case Outline.MODE_ROUND_RECT: + return nSetOutlineRoundRect(mNativeRenderNode, outline.mRect.left, outline.mRect.top, + outline.mRect.right, outline.mRect.bottom, outline.mRadius, outline.mAlpha); + case Outline.MODE_CONVEX_PATH: + return nSetOutlineConvexPath(mNativeRenderNode, outline.mPath.mNativePath, + outline.mAlpha); + } + throw new IllegalArgumentException("Unrecognized outline?"); } diff --git a/core/java/android/view/ScaleGestureDetector.java b/core/java/android/view/ScaleGestureDetector.java index 37e400014781..7cd161c17cd9 100644 --- a/core/java/android/view/ScaleGestureDetector.java +++ b/core/java/android/view/ScaleGestureDetector.java @@ -145,13 +145,6 @@ public class ScaleGestureDetector { private int mSpanSlop; private int mMinSpan; - // Bounds for recently seen values - private float mTouchUpper; - private float mTouchLower; - private float mTouchHistoryLastAccepted; - private int mTouchHistoryDirection; - private long mTouchHistoryLastAcceptedTime; - private int mTouchMinMajor; private final Handler mHandler; private float mAnchoredScaleStartX; @@ -207,8 +200,6 @@ public class ScaleGestureDetector { mSpanSlop = ViewConfiguration.get(context).getScaledTouchSlop() * 2; final Resources res = context.getResources(); - mTouchMinMajor = res.getDimensionPixelSize( - com.android.internal.R.dimen.config_minScalingTouchMajor); mMinSpan = res.getDimensionPixelSize(com.android.internal.R.dimen.config_minScalingSpan); mHandler = handler; // Quick scale is enabled by default after JB_MR2 @@ -223,77 +214,6 @@ public class ScaleGestureDetector { } /** - * The touchMajor/touchMinor elements of a MotionEvent can flutter/jitter on - * some hardware/driver combos. Smooth it out to get kinder, gentler behavior. - * @param ev MotionEvent to add to the ongoing history - */ - private void addTouchHistory(MotionEvent ev) { - final long currentTime = SystemClock.uptimeMillis(); - final int count = ev.getPointerCount(); - boolean accept = currentTime - mTouchHistoryLastAcceptedTime >= TOUCH_STABILIZE_TIME; - float total = 0; - int sampleCount = 0; - for (int i = 0; i < count; i++) { - final boolean hasLastAccepted = !Float.isNaN(mTouchHistoryLastAccepted); - final int historySize = ev.getHistorySize(); - final int pointerSampleCount = historySize + 1; - for (int h = 0; h < pointerSampleCount; h++) { - float major; - if (h < historySize) { - major = ev.getHistoricalTouchMajor(i, h); - } else { - major = ev.getTouchMajor(i); - } - if (major < mTouchMinMajor) major = mTouchMinMajor; - total += major; - - if (Float.isNaN(mTouchUpper) || major > mTouchUpper) { - mTouchUpper = major; - } - if (Float.isNaN(mTouchLower) || major < mTouchLower) { - mTouchLower = major; - } - - if (hasLastAccepted) { - final int directionSig = (int) Math.signum(major - mTouchHistoryLastAccepted); - if (directionSig != mTouchHistoryDirection || - (directionSig == 0 && mTouchHistoryDirection == 0)) { - mTouchHistoryDirection = directionSig; - final long time = h < historySize ? ev.getHistoricalEventTime(h) - : ev.getEventTime(); - mTouchHistoryLastAcceptedTime = time; - accept = false; - } - } - } - sampleCount += pointerSampleCount; - } - - final float avg = total / sampleCount; - - if (accept) { - float newAccepted = (mTouchUpper + mTouchLower + avg) / 3; - mTouchUpper = (mTouchUpper + newAccepted) / 2; - mTouchLower = (mTouchLower + newAccepted) / 2; - mTouchHistoryLastAccepted = newAccepted; - mTouchHistoryDirection = 0; - mTouchHistoryLastAcceptedTime = ev.getEventTime(); - } - } - - /** - * Clear all touch history tracking. Useful in ACTION_CANCEL or ACTION_UP. - * @see #addTouchHistory(MotionEvent) - */ - private void clearTouchHistory() { - mTouchUpper = Float.NaN; - mTouchLower = Float.NaN; - mTouchHistoryLastAccepted = Float.NaN; - mTouchHistoryDirection = 0; - mTouchHistoryLastAcceptedTime = 0; - } - - /** * Accepts MotionEvents and dispatches events to a {@link OnScaleGestureListener} * when appropriate. * @@ -344,7 +264,6 @@ public class ScaleGestureDetector { } if (streamComplete) { - clearTouchHistory(); return true; } } @@ -391,17 +310,14 @@ public class ScaleGestureDetector { focusY = sumY / div; } - addTouchHistory(event); - // Determine average deviation from focal point float devSumX = 0, devSumY = 0; for (int i = 0; i < count; i++) { if (skipIndex == i) continue; // Convert the resulting diameter into a radius. - final float touchSize = mTouchHistoryLastAccepted / 2; - devSumX += Math.abs(event.getX(i) - focusX) + touchSize; - devSumY += Math.abs(event.getY(i) - focusY) + touchSize; + devSumX += Math.abs(event.getX(i) - focusX); + devSumY += Math.abs(event.getY(i) - focusY); } final float devX = devSumX / div; final float devY = devSumY / div; diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 784164d243f1..b95d830ca9f2 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -2434,6 +2434,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * 11111111 PFLAG3_POINTER_ICON_MASK * 1 PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE * 1 PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED + * 1 PFLAG3_TEMPORARY_DETACH * |-------|-------|-------|-------| */ @@ -2667,6 +2668,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ private static final int PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED = 0x1000000; + /** + * Flag indicating that the view is temporarily detached from the parent view. + * + * @see #onStartTemporaryDetach() + * @see #onFinishTemporaryDetach() + */ + static final int PFLAG3_TEMPORARY_DETACH = 0x2000000; + /* End of masks for mPrivateFlags3 */ /** @@ -3890,6 +3899,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * cleanup. */ final RenderNode mRenderNode; + private Runnable mRenderNodeDetachedCallback; /** * Set to true when the view is sending hover accessibility events because it @@ -9735,9 +9745,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * @hide + * @return {@code true} when the View is in the state between {@link #onStartTemporaryDetach()} + * and {@link #onFinishTemporaryDetach()}. */ + public final boolean isTemporarilyDetached() { + return (mPrivateFlags3 & PFLAG3_TEMPORARY_DETACH) != 0; + } + + /** + * Dispatch {@link #onStartTemporaryDetach()} to this View and its direct children if this is + * a container View. + */ + @CallSuper public void dispatchStartTemporaryDetach() { + mPrivateFlags3 |= PFLAG3_TEMPORARY_DETACH; onStartTemporaryDetach(); } @@ -9753,10 +9774,13 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } /** - * @hide + * Dispatch {@link #onFinishTemporaryDetach()} to this View and its direct children if this is + * a container View. */ + @CallSuper public void dispatchFinishTemporaryDetach() { onFinishTemporaryDetach(); + mPrivateFlags3 &= ~PFLAG3_TEMPORARY_DETACH; } /** @@ -15187,6 +15211,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, protected void onDetachedFromWindowInternal() { mPrivateFlags &= ~PFLAG_CANCEL_NEXT_UP_EVENT; mPrivateFlags3 &= ~PFLAG3_IS_LAID_OUT; + mPrivateFlags3 &= ~PFLAG3_TEMPORARY_DETACH; removeUnsetPressCallback(); removeLongPressCallback(); @@ -16013,6 +16038,20 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public void onRenderNodeDetached(RenderNode renderNode) { + if (renderNode == mRenderNode && mRenderNodeDetachedCallback != null) { + mRenderNodeDetachedCallback.run(); + } + } + + /** + * Set callback for functor detach. Exposed to WebView through WebViewDelegate. + * Should not be used otherwise. + * @hide + */ + public final Runnable setRenderNodeDetachedCallback(@Nullable Runnable callback) { + Runnable oldCallback = mRenderNodeDetachedCallback; + mRenderNodeDetachedCallback = callback; + return oldCallback; } /** @@ -16915,7 +16954,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, } } else if (cache != null) { mPrivateFlags &= ~PFLAG_DIRTY_MASK; - if (layerType == LAYER_TYPE_NONE) { + if (layerType == LAYER_TYPE_NONE || mLayerPaint == null) { // no layer paint, use temporary paint to draw bitmap Paint cachePaint = parent.mCachePaint; if (cachePaint == null) { @@ -16927,13 +16966,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback, canvas.drawBitmap(cache, 0.0f, 0.0f, cachePaint); } else { // use layer paint to draw the bitmap, merging the two alphas, but also restore - int layerPaintAlpha = mLayerPaint != null ? mLayerPaint.getAlpha() : 255; - if (mLayerPaint == null && alpha < 1) { - mLayerPaint = new Paint(); + int layerPaintAlpha = mLayerPaint.getAlpha(); + if (alpha < 1) { mLayerPaint.setAlpha((int) (alpha * layerPaintAlpha)); } canvas.drawBitmap(cache, 0.0f, 0.0f, mLayerPaint); - if (mLayerPaint != null) { + if (alpha < 1) { mLayerPaint.setAlpha(layerPaintAlpha); } } diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 420c4f272ff0..5b2877faef02 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -3415,6 +3415,13 @@ public final class ViewRootImpl implements ViewParent, updateConfiguration(config, false); } + final boolean framesChanged = !mWinFrame.equals(args.arg1) + || !mPendingOverscanInsets.equals(args.arg5) + || !mPendingContentInsets.equals(args.arg2) + || !mPendingStableInsets.equals(args.arg6) + || !mPendingVisibleInsets.equals(args.arg3) + || !mPendingOutsets.equals(args.arg7); + mWinFrame.set((Rect) args.arg1); mPendingOverscanInsets.set((Rect) args.arg5); mPendingContentInsets.set((Rect) args.arg2); @@ -3431,7 +3438,7 @@ public final class ViewRootImpl implements ViewParent, mReportNextDraw = true; } - if (mView != null) { + if (mView != null && framesChanged) { forceLayout(mView); } diff --git a/core/java/android/view/WindowInfo.java b/core/java/android/view/WindowInfo.java index b72107447541..737e46071313 100644 --- a/core/java/android/view/WindowInfo.java +++ b/core/java/android/view/WindowInfo.java @@ -44,6 +44,8 @@ public class WindowInfo implements Parcelable { public boolean focused; public final Rect boundsInScreen = new Rect(); public List<IBinder> childTokens; + public CharSequence title; + public int accessibilityIdOfAnchor = View.NO_ID; private WindowInfo() { /* do nothing - hide constructor */ @@ -65,6 +67,8 @@ public class WindowInfo implements Parcelable { window.parentToken = other.parentToken; window.focused = other.focused; window.boundsInScreen.set(other.boundsInScreen); + window.title = other.title; + window.accessibilityIdOfAnchor = other.accessibilityIdOfAnchor; if (other.childTokens != null && !other.childTokens.isEmpty()) { if (window.childTokens == null) { @@ -95,6 +99,8 @@ public class WindowInfo implements Parcelable { parcel.writeStrongBinder(parentToken); parcel.writeInt(focused ? 1 : 0); boundsInScreen.writeToParcel(parcel, flags); + parcel.writeCharSequence(title); + parcel.writeInt(accessibilityIdOfAnchor); if (childTokens != null && !childTokens.isEmpty()) { parcel.writeInt(1); @@ -108,13 +114,15 @@ public class WindowInfo implements Parcelable { public String toString() { StringBuilder builder = new StringBuilder(); builder.append("WindowInfo["); - builder.append("type=").append(type); + builder.append("title=").append(title); + builder.append(", type=").append(type); builder.append(", layer=").append(layer); builder.append(", token=").append(token); builder.append(", bounds=").append(boundsInScreen); builder.append(", parent=").append(parentToken); builder.append(", focused=").append(focused); builder.append(", children=").append(childTokens); + builder.append(", accessibility anchor=").append(accessibilityIdOfAnchor); builder.append(']'); return builder.toString(); } @@ -126,6 +134,8 @@ public class WindowInfo implements Parcelable { parentToken = parcel.readStrongBinder(); focused = (parcel.readInt() == 1); boundsInScreen.readFromParcel(parcel); + title = parcel.readCharSequence(); + accessibilityIdOfAnchor = parcel.readInt(); final boolean hasChildren = (parcel.readInt() == 1); if (hasChildren) { diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 03dcf99258ab..c372c30915f2 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -1693,6 +1693,14 @@ public interface WindowManager extends ViewManager { */ public long userActivityTimeout = -1; + /** + * For windows with an anchor (e.g. PopupWindow), keeps track of the View that anchors the + * window. + * + * @hide + */ + public int accessibilityIdOfAnchor = -1; + public LayoutParams() { super(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); type = TYPE_APPLICATION; @@ -1799,6 +1807,7 @@ public interface WindowManager extends ViewManager { out.writeInt(surfaceInsets.bottom); out.writeInt(hasManualSurfaceInsets ? 1 : 0); out.writeInt(needsMenuKey); + out.writeInt(accessibilityIdOfAnchor); } public static final Parcelable.Creator<LayoutParams> CREATOR @@ -1849,6 +1858,7 @@ public interface WindowManager extends ViewManager { surfaceInsets.bottom = in.readInt(); hasManualSurfaceInsets = in.readInt() != 0; needsMenuKey = in.readInt(); + accessibilityIdOfAnchor = in.readInt(); } @SuppressWarnings({"PointlessBitwiseExpression"}) @@ -1888,6 +1898,8 @@ public interface WindowManager extends ViewManager { /** {@hide} */ public static final int PREFERRED_DISPLAY_MODE_ID = 1 << 23; /** {@hide} */ + public static final int ACCESSIBILITY_ANCHOR_CHANGED = 1 << 24; + /** {@hide} */ public static final int EVERYTHING_CHANGED = 0xffffffff; // internal buffer to backup/restore parameters under compatibility mode. @@ -2048,6 +2060,11 @@ public interface WindowManager extends ViewManager { changes |= NEEDS_MENU_KEY_CHANGED; } + if (accessibilityIdOfAnchor != o.accessibilityIdOfAnchor) { + accessibilityIdOfAnchor = o.accessibilityIdOfAnchor; + changes |= ACCESSIBILITY_ANCHOR_CHANGED; + } + return changes; } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 23b0df2db110..96f179b8db63 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -1397,4 +1397,9 @@ public interface WindowManagerPolicy { * is allowed, so for example, if DOCKED_RIGHT is not allowed, DOCKED_LEFT is allowed. */ public boolean isDockSideAllowed(int dockSide); + + /** + * Called when the configuration has changed, and it's safe to load new values from resources. + */ + public void onConfigurationChanged(); } diff --git a/core/java/android/view/accessibility/AccessibilityEvent.java b/core/java/android/view/accessibility/AccessibilityEvent.java index 2cde03d63529..f8a13a373aec 100644 --- a/core/java/android/view/accessibility/AccessibilityEvent.java +++ b/core/java/android/view/accessibility/AccessibilityEvent.java @@ -240,10 +240,12 @@ import java.util.List; * <li>{@link #getMovementGranularity()} - Sets the granularity at which a view's text * was traversed.</li> * <li>{@link #getText()} - The text of the source's sub-tree.</li> - * <li>{@link #getFromIndex()} - The start of the next/previous text at the specified granularity - * - inclusive.</li> - * <li>{@link #getToIndex()} - The end of the next/previous text at the specified granularity - * - exclusive.</li> + * <li>{@link #getFromIndex()} - The start the text that was skipped over in this movement. + * This is the starting point when moving forward through the text, but not when moving + * back.</li> + * <li>{@link #getToIndex()} - The end of the text that was skipped over in this movement. + * This is the ending point when moving forward through the text, but not when moving + * back.</li> * <li>{@link #isPassword()} - Whether the source is password.</li> * <li>{@link #isEnabled()} - Whether the source is enabled.</li> * <li>{@link #getContentDescription()} - The content description of the source.</li> diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java index 14821118f728..02d2a8bd386f 100644 --- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java +++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java @@ -328,36 +328,6 @@ public class AccessibilityNodeInfo implements Parcelable { // Action arguments /** - * Argument for specifying index of {@link android.text.style.ClickableSpan} the click action is - * related to. - * <p> - * <strong>Type:</strong> int<br> - * <strong>Actions:</strong> - * {@link AccessibilityAction#ACTION_CLICK} - * </p> - * - * @see AccessibilityAction#ACTION_CLICK - */ - public static final String ACTION_ARGUMENT_CLICK_SPAN_INDEX_INT = - "android.view.accessibility.action.ARGUMENT_CLICK_SPAN_INDEX_INT"; - - /** - * Argument for specifying index of character in the text which contains - * {@link android.text.style.ClickableSpan} the click action is - * related to. If there is more than one {@link android.text.style.ClickableSpan} assigned for - * the range the character is in only the first span would be clicked. - * <p> - * <strong>Type:</strong> int<br> - * <strong>Actions:</strong> - * {@link AccessibilityAction#ACTION_CLICK} - * </p> - * - * @see AccessibilityAction#ACTION_CLICK - */ - public static final String ACTION_ARGUMENT_CLICK_CHARACTER_INDEX_INT = - "android.view.accessibility.action.ARGUMENT_CLICK_CHARACTER_INDEX_INT"; - - /** * Argument for which movement granularity to be used when traversing the node text. * <p> * <strong>Type:</strong> int<br> @@ -3391,33 +3361,6 @@ public class AccessibilityNodeInfo implements Parcelable { /** * Action that clicks on the node info. - * - * <p> - * If a specific {@link android.text.style.ClickableSpan} within node's text content is - * supposed to be clicked, then one of {@link #ACTION_ARGUMENT_CLICK_SPAN_INDEX_INT} or - * {@link #ACTION_ARGUMENT_CLICK_CHARACTER_INDEX_INT} arguments should be specified. - * If both arguments are set {@link #ACTION_ARGUMENT_CLICK_CHARACTER_INDEX_INT} would - * be ignored.<br> - * - * {@link #ACTION_ARGUMENT_CLICK_SPAN_INDEX_INT} specifies index of corresponding - * {@link android.text.style.ClickableSpan} in {@link android.text.SpannableString}.<br> - * - * {@link #ACTION_ARGUMENT_CLICK_CHARACTER_INDEX_INT} specifies index of character - * that could contain one or more spans. - * </p> - * - * <p> - * <strong>Optional arguments:</strong> - * {@link #ACTION_ARGUMENT_CLICK_SPAN_INDEX_INT}, - * {@link #ACTION_ARGUMENT_CLICK_CHARACTER_INDEX_INT}<br> - * <strong>Example:</strong> Perform click on 3rd {@link android.text.style.ClickableSpan} - * inside {@link android.text.SpannableString} in node's text. - * <code><pre><p> - * Bundle arguments = new Bundle(); - * arguments.putInt(AccessibilityNodeInfo.ACTION_ARGUMENT_CLICK_SPAN_INDEX_INT, 3); - * info.performAction(AccessibilityAction.ACTION_CLICK.getId(), arguments); - * </code></pre></p> - * </p> */ public static final AccessibilityAction ACTION_CLICK = new AccessibilityAction( diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java index ad78b686b8de..d0d4507e7b62 100644 --- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java +++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java @@ -89,6 +89,8 @@ public final class AccessibilityWindowInfo implements Parcelable { private int mParentId = UNDEFINED; private final Rect mBoundsInScreen = new Rect(); private LongArray mChildIds; + private CharSequence mTitle; + private int mAnchorId = UNDEFINED; private int mConnectionId = UNDEFINED; @@ -97,6 +99,26 @@ public final class AccessibilityWindowInfo implements Parcelable { } /** + * Gets the title of the window. + * + * @return The title. + */ + public CharSequence getTitle() { + return mTitle; + } + + /** + * Sets the title of the window. + * + * @param title The title. + * + * @hide + */ + public void setTitle(CharSequence title) { + mTitle = title; + } + + /** * Gets the type of the window. * * @return The type. @@ -159,9 +181,35 @@ public final class AccessibilityWindowInfo implements Parcelable { } /** - * Gets the parent window if such. + * Sets the anchor node's ID. + * + * @param anchorId The anchor's accessibility id in its window. + * + * @hide + */ + public void setAnchorId(int anchorId) { + mAnchorId = anchorId; + } + + /** + * Gets the node that anchors this window to another. + * + * @return The anchor node, or {@code null} if none exists. + */ + public AccessibilityNodeInfo getAnchor() { + if ((mConnectionId == UNDEFINED) || (mAnchorId == UNDEFINED) || (mParentId == UNDEFINED)) { + return null; + } + + AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance(); + return client.findAccessibilityNodeInfoByAccessibilityId(mConnectionId, + mParentId, mAnchorId, true, 0); + } + + /** + * Gets the parent window. * - * @return The parent window. + * @return The parent window, or {@code null} if none exists. */ public AccessibilityWindowInfo getParent() { if (mConnectionId == UNDEFINED || mParentId == UNDEFINED) { @@ -370,6 +418,8 @@ public final class AccessibilityWindowInfo implements Parcelable { infoClone.mId = info.mId; infoClone.mParentId = info.mParentId; infoClone.mBoundsInScreen.set(info.mBoundsInScreen); + infoClone.mTitle = info.mTitle; + infoClone.mAnchorId = info.mAnchorId; if (info.mChildIds != null && info.mChildIds.size() > 0) { if (infoClone.mChildIds == null) { @@ -410,6 +460,8 @@ public final class AccessibilityWindowInfo implements Parcelable { parcel.writeInt(mId); parcel.writeInt(mParentId); mBoundsInScreen.writeToParcel(parcel, flags); + parcel.writeCharSequence(mTitle); + parcel.writeInt(mAnchorId); final LongArray childIds = mChildIds; if (childIds == null) { @@ -432,6 +484,8 @@ public final class AccessibilityWindowInfo implements Parcelable { mId = parcel.readInt(); mParentId = parcel.readInt(); mBoundsInScreen.readFromParcel(parcel); + mTitle = parcel.readCharSequence(); + mAnchorId = parcel.readInt(); final int childCount = parcel.readInt(); if (childCount > 0) { @@ -471,6 +525,7 @@ public final class AccessibilityWindowInfo implements Parcelable { public String toString() { StringBuilder builder = new StringBuilder(); builder.append("AccessibilityWindowInfo["); + builder.append("title=").append(mTitle); builder.append("id=").append(mId); builder.append(", type=").append(typeToString(mType)); builder.append(", layer=").append(mLayer); @@ -494,6 +549,7 @@ public final class AccessibilityWindowInfo implements Parcelable { builder.append(']'); } else { builder.append(", hasParent=").append(mParentId != UNDEFINED); + builder.append(", isAnchored=").append(mAnchorId != UNDEFINED); builder.append(", hasChildren=").append(mChildIds != null && mChildIds.size() > 0); } @@ -515,6 +571,8 @@ public final class AccessibilityWindowInfo implements Parcelable { mChildIds.clear(); } mConnectionId = UNDEFINED; + mAnchorId = UNDEFINED; + mTitle = null; } /** diff --git a/core/java/android/view/animation/Animation.java b/core/java/android/view/animation/Animation.java index 1536c29bee5b..d89c172be8a7 100644 --- a/core/java/android/view/animation/Animation.java +++ b/core/java/android/view/animation/Animation.java @@ -93,8 +93,12 @@ public abstract class Animation implements Cloneable { */ public static final int ZORDER_BOTTOM = -1; - private static final boolean USE_CLOSEGUARD - = SystemProperties.getBoolean("log.closeguard.Animation", false); + // Use a preload holder to isolate static initialization into inner class, which allows + // Animation and its subclasses to be compile-time initialized. + private static class NoImagePreloadHolder { + public static final boolean USE_CLOSEGUARD + = SystemProperties.getBoolean("log.closeguard.Animation", false); + } /** * Set by {@link #getTransformation(long, Transformation)} when the animation ends. @@ -859,7 +863,7 @@ public abstract class Animation implements Cloneable { if (!mStarted) { fireAnimationStart(); mStarted = true; - if (USE_CLOSEGUARD) { + if (NoImagePreloadHolder.USE_CLOSEGUARD) { guard.open("cancel or detach or getTransformation"); } } diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java index 687990124a55..1ce804342c43 100644 --- a/core/java/android/view/inputmethod/InputMethodManager.java +++ b/core/java/android/view/inputmethod/InputMethodManager.java @@ -1307,6 +1307,12 @@ public final class InputMethodManager { void focusInLocked(View view) { if (DEBUG) Log.v(TAG, "focusIn: " + dumpViewInfo(view)); + if (view != null && view.isTemporarilyDetached()) { + // This is a request from a view that is temporarily detached from a window. + if (DEBUG) Log.v(TAG, "Temporarily detached view, ignoring"); + return; + } + if (mCurRootView != view.getRootView()) { // This is a request from a window that isn't in the window with // IME focus, so ignore it. @@ -1332,6 +1338,7 @@ public final class InputMethodManager { // whenever we go into touch mode, so it ends up hiding // at times when we don't really want it to. For now it // seems better to just turn it all off. + // TODO: Check view.isTemporarilyDetached() when re-enable the following code. if (false && view.hasWindowFocus()) { mNextServedView = null; scheduleCheckFocusLocked(view); @@ -1348,7 +1355,7 @@ public final class InputMethodManager { synchronized (mH) { if (DEBUG) Log.v(TAG, "onViewDetachedFromWindow: view=" + dumpViewInfo(view) + " mServedView=" + dumpViewInfo(mServedView)); - if (mServedView == view && view.hasWindowFocus()) { + if (mServedView == view) { mNextServedView = null; scheduleCheckFocusLocked(view); } @@ -2315,6 +2322,7 @@ public final class InputMethodManager { sb.append(",focus=" + view.hasFocus()); sb.append(",windowFocus=" + view.hasWindowFocus()); sb.append(",window=" + view.getWindowToken()); + sb.append(",temporaryDetach=" + view.isTemporarilyDetached()); return sb.toString(); } } diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java index 8104f7d6f50c..b6516c85d094 100644 --- a/core/java/android/webkit/WebViewDelegate.java +++ b/core/java/android/webkit/WebViewDelegate.java @@ -16,6 +16,8 @@ package android.webkit; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.SystemApi; import android.app.ActivityThread; import android.app.Application; @@ -109,6 +111,24 @@ public final class WebViewDelegate { } /** + * Set the Runnable callback the DrawGlFunction functor is detached and free to be destroyed. + * This will replace the previous callback, if any. + * + * @param view The view to set the callback. Should be the view where onDraw inserted + * DrawGLFunctor. + * @param callback The new callback to set on the view. + * @throws IllegalArgumentException if view is null. + * @return The previous callback on this view. + */ + public Runnable setDrawGlFunctionDetachedCallback( + @NonNull View view, @Nullable Runnable callback) { + if (view == null) { + throw new IllegalArgumentException("View cannot be null"); + } + return view.setRenderNodeDetachedCallback(callback); + } + + /** * Detaches the draw GL functor. * * @param nativeDrawGLFunctor the pointer to the native functor that implements diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index cc496dc72d7c..0ac57319d5de 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -21,7 +21,6 @@ import android.app.ActivityManagerInternal; import android.app.AppGlobals; import android.app.Application; import android.content.Context; -import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -561,18 +560,6 @@ public final class WebViewFactory { return result; } - /** - * Returns whether the entire package from an ACTION_PACKAGE_CHANGED intent was changed (rather - * than just one of its components). - * @hide - */ - public static boolean entirePackageChanged(Intent intent) { - String[] componentList = - intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST); - return Arrays.asList(componentList).contains( - intent.getDataString().substring("package:".length())); - } - private static String WEBVIEW_UPDATE_SERVICE_NAME = "webviewupdate"; /** @hide */ diff --git a/core/java/android/widget/AccessibilityIterators.java b/core/java/android/widget/AccessibilityIterators.java index a3d58a4e2060..442ffa136ca3 100644 --- a/core/java/android/widget/AccessibilityIterators.java +++ b/core/java/android/widget/AccessibilityIterators.java @@ -134,8 +134,8 @@ final class AccessibilityIterators { @Override public int[] following(int offset) { - final int textLegth = mText.length(); - if (textLegth <= 0) { + final int textLength = mText.length(); + if (textLength <= 0) { return null; } if (offset >= mText.length()) { @@ -163,8 +163,8 @@ final class AccessibilityIterators { @Override public int[] preceding(int offset) { - final int textLegth = mText.length(); - if (textLegth <= 0) { + final int textLength = mText.length(); + if (textLength <= 0) { return null; } if (offset <= 0) { @@ -181,8 +181,13 @@ final class AccessibilityIterators { final int pageHeight = mTempRect.height() - mView.getTotalPaddingTop() - mView.getTotalPaddingBottom(); final int previousPageEndY = currentLineTop - pageHeight; - final int currentPageStartLine = (previousPageEndY > 0) ? - mLayout.getLineForVertical(previousPageEndY) + 1 : 0; + int currentPageStartLine = (previousPageEndY > 0) ? + mLayout.getLineForVertical(previousPageEndY) : 0; + // If we're at the end of text, we're at the end of the current line rather than the + // start of the next line, so we should move up one fewer lines than we would otherwise. + if (end == mText.length() && (currentPageStartLine < currentLine)) { + currentPageStartLine += 1; + } final int start = getLineEdgeIndex(currentPageStartLine, DIRECTION_START); diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java index 7d57cb83f6df..6a4e36a9a578 100644 --- a/core/java/android/widget/AutoCompleteTextView.java +++ b/core/java/android/widget/AutoCompleteTextView.java @@ -1116,7 +1116,7 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { super.onFocusChanged(focused, direction, previouslyFocusedRect); - if (mTemporaryDetach) { + if (isTemporarilyDetached()) { // If we are temporarily in the detach state, then do nothing. return; } diff --git a/core/java/android/widget/CalendarView.java b/core/java/android/widget/CalendarView.java index cde7604b7e7c..66896ab70e45 100644 --- a/core/java/android/widget/CalendarView.java +++ b/core/java/android/widget/CalendarView.java @@ -430,9 +430,11 @@ public class CalendarView extends FrameLayout { * Sets whether to show the week number. * * @param showWeekNumber True to show the week number. + * @deprecated No longer used by Material-style CalendarView. * * @attr ref android.R.styleable#CalendarView_showWeekNumber */ + @Deprecated public void setShowWeekNumber(boolean showWeekNumber) { mDelegate.setShowWeekNumber(showWeekNumber); } @@ -441,9 +443,11 @@ public class CalendarView extends FrameLayout { * Gets whether to show the week number. * * @return True if showing the week number. + * @deprecated No longer used by Material-style CalendarView. * * @attr ref android.R.styleable#CalendarView_showWeekNumber */ + @Deprecated public boolean getShowWeekNumber() { return mDelegate.getShowWeekNumber(); } diff --git a/core/java/android/widget/CalendarViewLegacyDelegate.java b/core/java/android/widget/CalendarViewLegacyDelegate.java index 442fb334c4f6..f540479ad641 100644 --- a/core/java/android/widget/CalendarViewLegacyDelegate.java +++ b/core/java/android/widget/CalendarViewLegacyDelegate.java @@ -404,7 +404,7 @@ class CalendarViewLegacyDelegate extends CalendarView.AbstractCalendarViewDelega @Override public int getUnfocusedMonthDateColor() { - return mFocusedMonthDateColor; + return mUnfocusedMonthDateColor; } @Override diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java index e3357a7738f2..0c5edc5f2f81 100644 --- a/core/java/android/widget/DatePicker.java +++ b/core/java/android/widget/DatePicker.java @@ -339,7 +339,9 @@ public class DatePicker extends FrameLayout { * * @return {@code true} if the calendar view is shown * @see #getCalendarView() + * @deprecated Not supported by Material-style {@code calendar} mode */ + @Deprecated public boolean getCalendarViewShown() { return mDelegate.getCalendarViewShown(); } @@ -347,13 +349,18 @@ public class DatePicker extends FrameLayout { /** * Returns the {@link CalendarView} used by this picker. * <p> - * <strong>Note:</strong> This method returns {@code null} when the + * <strong>Note:</strong> This method throws an + * {@link UnsupportedOperationException} when the * {@link android.R.styleable#DatePicker_datePickerMode} attribute is set * to {@code calendar}. * * @return the calendar view * @see #getCalendarViewShown() + * @deprecated Not supported by Material-style {@code calendar} mode + * @throws UnsupportedOperationException if called when the picker is + * displayed in {@code calendar} mode */ + @Deprecated public CalendarView getCalendarView() { return mDelegate.getCalendarView(); } @@ -367,7 +374,9 @@ public class DatePicker extends FrameLayout { * * @param shown {@code true} to show the calendar view, {@code false} to * hide it + * @deprecated Not supported by Material-style {@code calendar} mode */ + @Deprecated public void setCalendarViewShown(boolean shown) { mDelegate.setCalendarViewShown(shown); } @@ -380,7 +389,9 @@ public class DatePicker extends FrameLayout { * to {@code calendar}. * * @return {@code true} if the spinners are shown + * @deprecated Not supported by Material-style {@code calendar} mode */ + @Deprecated public boolean getSpinnersShown() { return mDelegate.getSpinnersShown(); } @@ -394,7 +405,9 @@ public class DatePicker extends FrameLayout { * * @param shown {@code true} to show the spinners, {@code false} to hide * them + * @deprecated Not supported by Material-style {@code calendar} mode */ + @Deprecated public void setSpinnersShown(boolean shown) { mDelegate.setSpinnersShown(shown); } diff --git a/core/java/android/widget/DayPickerPagerAdapter.java b/core/java/android/widget/DayPickerPagerAdapter.java index 8ce2f9cb470c..97936e7c7c5b 100644 --- a/core/java/android/widget/DayPickerPagerAdapter.java +++ b/core/java/android/widget/DayPickerPagerAdapter.java @@ -148,18 +148,22 @@ class DayPickerPagerAdapter extends PagerAdapter { void setCalendarTextColor(ColorStateList calendarTextColor) { mCalendarTextColor = calendarTextColor; + notifyDataSetChanged(); } void setDaySelectorColor(ColorStateList selectorColor) { mDaySelectorColor = selectorColor; + notifyDataSetChanged(); } void setMonthTextAppearance(int resId) { mMonthTextAppearance = resId; + notifyDataSetChanged(); } void setDayOfWeekTextAppearance(int resId) { mDayOfWeekTextAppearance = resId; + notifyDataSetChanged(); } int getDayOfWeekTextAppearance() { @@ -168,6 +172,7 @@ class DayPickerPagerAdapter extends PagerAdapter { void setDayTextAppearance(int resId) { mDayTextAppearance = resId; + notifyDataSetChanged(); } int getDayTextAppearance() { diff --git a/core/java/android/widget/EditText.java b/core/java/android/widget/EditText.java index 434e3eb8237e..ad355504a0ee 100644 --- a/core/java/android/widget/EditText.java +++ b/core/java/android/widget/EditText.java @@ -155,6 +155,9 @@ public class EditText extends TextView { public boolean performAccessibilityActionInternal(int action, Bundle arguments) { switch (action) { case AccessibilityNodeInfo.ACTION_SET_TEXT: { + if (!isEnabled()) { + return false; + } CharSequence text = (arguments != null) ? arguments.getCharSequence( AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE) : null; setText(text); diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 59d857c35afe..440ef2162fc5 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -218,7 +218,6 @@ public class Editor { boolean mShowSoftInputOnFocus = true; private boolean mPreserveSelection; private boolean mRestartActionModeOnNextRefresh; - boolean mTemporaryDetach; boolean mIsBeingLongClicked; @@ -367,7 +366,6 @@ public class Editor { showError(); mShowErrorAfterAttach = false; } - mTemporaryDetach = false; final ViewTreeObserver observer = mTextView.getViewTreeObserver(); // No need to create the controller. @@ -429,7 +427,6 @@ public class Editor { hideCursorAndSpanControllers(); stopTextActionModeWithPreservingSelection(); - mTemporaryDetach = false; } private void discardTextDisplayLists() { @@ -1212,7 +1209,7 @@ public class Editor { stopTextActionModeWithPreservingSelection(); } else { hideCursorAndSpanControllers(); - if (mTemporaryDetach) { + if (mTextView.isTemporarilyDetached()) { stopTextActionModeWithPreservingSelection(); } else { stopTextActionMode(); @@ -1781,6 +1778,18 @@ public class Editor { if (translate) canvas.translate(0, -cursorOffsetVertical); } + void invalidateHandlesAndActionMode() { + if (mSelectionModifierCursorController != null) { + mSelectionModifierCursorController.invalidateHandles(); + } + if (mInsertionPointCursorController != null) { + mInsertionPointCursorController.invalidateHandle(); + } + if (mTextActionMode != null) { + mTextActionMode.invalidate(); + } + } + /** * Invalidates all the sub-display lists that overlap the specified character range */ @@ -1866,9 +1875,9 @@ public class Editor { if (hasSelection) { hideInsertionPointCursorController(); if (mTextActionMode == null) { - if (mRestartActionModeOnNextRefresh || mTextView.isInExtractedMode()) { + if (mRestartActionModeOnNextRefresh) { // To avoid distraction, newly start action mode only when selection action - // mode is being restarted or in full screen extracted mode. + // mode is being restarted. startSelectionActionMode(); } } else if (selectionController == null || !selectionController.isActive()) { @@ -3465,7 +3474,6 @@ public class Editor { popupBackground.getPadding(mTempRect); width += mTempRect.left + mTempRect.right; } - mSuggestionListView.getLayoutParams().width = width; mPopupWindow.setWidth(width); } @@ -3640,6 +3648,9 @@ public class Editor { } if (menu.hasVisibleItems() || mode.getCustomView() != null) { + if (mHasSelection && !mTextView.hasTransientState()) { + mTextView.setHasTransientState(true); + } return true; } else { return false; @@ -4104,6 +4115,14 @@ public class Editor { setMeasuredDimension(getPreferredWidth(), getPreferredHeight()); } + @Override + public void invalidate() { + super.invalidate(); + if (isShowing()) { + positionAtCursorOffset(getCurrentCursorOffset(), true); + } + }; + private int getPreferredWidth() { return Math.max(mDrawable.getIntrinsicWidth(), mMinSize); } @@ -4170,7 +4189,12 @@ public class Editor { return mTextView.getOffsetAtCoordinate(line, x); } - protected void positionAtCursorOffset(int offset, boolean parentScrolled) { + /** + * @param offset Cursor offset. Must be in [-1, length]. + * @param forceUpdatePosition whether to force update the position. This should be true + * when If the parent has been scrolled, for example. + */ + protected void positionAtCursorOffset(int offset, boolean forceUpdatePosition) { // A HandleView relies on the layout, which may be nulled by external methods Layout layout = mTextView.getLayout(); if (layout == null) { @@ -4181,7 +4205,7 @@ public class Editor { layout = mTextView.getLayout(); boolean offsetChanged = offset != mPreviousOffset; - if (offsetChanged || parentScrolled) { + if (offsetChanged || forceUpdatePosition) { if (offsetChanged) { updateSelection(offset); addPositionToTouchUpFilter(offset); @@ -4782,13 +4806,9 @@ public class Editor { mPrevX = x; } - /** - * @param offset Cursor offset. Must be in [-1, length]. - * @param parentScrolled If the parent has been scrolled or not. - */ @Override - protected void positionAtCursorOffset(int offset, boolean parentScrolled) { - super.positionAtCursorOffset(offset, parentScrolled); + protected void positionAtCursorOffset(int offset, boolean forceUpdatePosition) { + super.positionAtCursorOffset(offset, forceUpdatePosition); mInWord = (offset != -1) && !getWordIteratorWithText().isBoundary(offset); } @@ -4875,11 +4895,12 @@ public class Editor { @Override protected int getOffsetAtCoordinate(@NonNull Layout layout, int line, float x) { - final int primaryOffset = layout.getOffsetForHorizontal(line, x, true); + final float localX = mTextView.convertToLocalHorizontalCoordinate(x); + final int primaryOffset = layout.getOffsetForHorizontal(line, localX, true); if (!layout.isLevelBoundary(primaryOffset)) { return primaryOffset; } - final int secondaryOffset = layout.getOffsetForHorizontal(line, x, false); + final int secondaryOffset = layout.getOffsetForHorizontal(line, localX, false); final int currentOffset = getCurrentCursorOffset(); final int primaryDiff = Math.abs(primaryOffset - currentOffset); final int secondaryDiff = Math.abs(secondaryOffset - currentOffset); @@ -5013,6 +5034,12 @@ public class Editor { public boolean isActive() { return mHandle != null && mHandle.isShowing(); } + + public void invalidateHandle() { + if (mHandle != null) { + mHandle.invalidate(); + } + } } class SelectionModifierCursorController implements CursorController { @@ -5417,6 +5444,15 @@ public class Editor { public boolean isActive() { return mStartHandle != null && mStartHandle.isShowing(); } + + public void invalidateHandles() { + if (mStartHandle != null) { + mStartHandle.invalidate(); + } + if (mEndHandle != null) { + mEndHandle.invalidate(); + } + } } private class CorrectionHighlighter { diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java index 7658cc894913..bfc87f297d42 100644 --- a/core/java/android/widget/ListView.java +++ b/core/java/android/widget/ListView.java @@ -1673,7 +1673,7 @@ public class ListView extends AbsListView { focusLayoutRestoreView = findFocus(); if (focusLayoutRestoreView != null) { // Tell it we are going to mess with it. - focusLayoutRestoreView.onStartTemporaryDetach(); + focusLayoutRestoreView.dispatchStartTemporaryDetach(); } } requestFocus(); @@ -1850,7 +1850,7 @@ public class ListView extends AbsListView { // our view hierarchy. if (focusLayoutRestoreView != null && focusLayoutRestoreView.getWindowToken() != null) { - focusLayoutRestoreView.onFinishTemporaryDetach(); + focusLayoutRestoreView.dispatchFinishTemporaryDetach(); } mLayoutMode = LAYOUT_NORMAL; diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index 92631da2da90..0d8d8ed17b65 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -1214,6 +1214,7 @@ public class PopupWindow { final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, p.width, p.height, gravity); updateAboveAnchor(aboveAnchor); + p.accessibilityIdOfAnchor = (anchor != null) ? anchor.getAccessibilityViewId() : -1; invokePopup(p); } @@ -1494,7 +1495,7 @@ public class PopupWindow { * * @param anchor the view on which the popup window must be anchored * @param outParams the layout parameters used to display the drop down - * @param xOffset absolute horizontal offset from the top of the anchor + * @param xOffset absolute horizontal offset from the left of the anchor * @param yOffset absolute vertical offset from the top of the anchor * @param gravity horizontal gravity specifying popup alignment * @return true if the popup is translated upwards to fit on screen @@ -1523,6 +1524,8 @@ public class PopupWindow { // Let the window manager know to align the top to y. outParams.gravity = Gravity.LEFT | Gravity.TOP; + outParams.width = width; + outParams.height = height; final int[] screenLocation = mTmpScreenLocation; anchor.getLocationOnScreen(screenLocation); @@ -1530,100 +1533,154 @@ public class PopupWindow { final Rect displayFrame = new Rect(); anchor.getWindowVisibleDisplayFrame(displayFrame); - boolean onTop = false; - - final View root = anchor.getRootView(); - final int screenY = screenLocation[1] + anchorHeight + yOffset; - final boolean tooFarDown = screenY + height > displayFrame.bottom; - final boolean tooFarRight = outParams.x + width > root.getWidth(); - if (tooFarDown || tooFarRight) { - // If the popup extends beyond the visible area, try to scroll the - // parent so that it is fully visible. - if (mAllowScrollingAnchorParent) { - final int scrollX = anchor.getScrollX(); - final int scrollY = anchor.getScrollY(); - final Rect r = new Rect(scrollX, scrollY, scrollX + width + xOffset, - scrollY + height + anchorHeight + yOffset); - anchor.requestRectangleOnScreen(r, true); + // First, attempt to fit the popup vertically without resizing. + final boolean fitsVertical = tryFitVertical(outParams, yOffset, height, + anchorHeight, drawingLocation[1], screenLocation[1], displayFrame.top, + displayFrame.bottom, false); + + // Next, attempt to fit the popup horizontally without resizing. + final boolean fitsHorizontal = tryFitHorizontal(outParams, xOffset, width, + anchorWidth, drawingLocation[0], screenLocation[0], displayFrame.left, + displayFrame.right, false); + + // If the popup still doesn't fit, attempt to scroll the parent. + if (!fitsVertical || !fitsHorizontal) { + final int scrollX = anchor.getScrollX(); + final int scrollY = anchor.getScrollY(); + final Rect r = new Rect(scrollX, scrollY, scrollX + width + xOffset, + scrollY + height + anchorHeight + yOffset); + if (mAllowScrollingAnchorParent && anchor.requestRectangleOnScreen(r, true)) { + // Reset for the new anchor position. + anchor.getLocationInWindow(drawingLocation); + outParams.x = drawingLocation[0] + xOffset; + outParams.y = drawingLocation[1] + anchorHeight + yOffset; + + // Preserve the gravity adjustment. + if (hgrav == Gravity.RIGHT) { + outParams.x -= width - anchorWidth; + } } - // Update for the new anchor position. - anchor.getLocationInWindow(drawingLocation); - outParams.x = drawingLocation[0] + xOffset; - outParams.y = drawingLocation[1] + anchorHeight + yOffset; + // Try to fit the popup again and allowing resizing. + tryFitVertical(outParams, yOffset, height, anchorHeight, drawingLocation[1], + screenLocation[1], displayFrame.top, displayFrame.bottom, mClipToScreen); + tryFitHorizontal(outParams, xOffset, width, anchorWidth, drawingLocation[0], + screenLocation[0], displayFrame.left, displayFrame.right, mClipToScreen); + } - // Preserve the gravity adjustment. - if (hgrav == Gravity.RIGHT) { - outParams.x -= width - anchorWidth; - } + // Return whether the popup's top edge is above the anchor's top edge. + return outParams.y < drawingLocation[1]; + } - final int newScreenY = screenLocation[1] + anchorHeight + yOffset; - final boolean stillTooFarDown = newScreenY + height > displayFrame.bottom; - if (stillTooFarDown) { - // If the popup is still too far down, re-evaluate the space - // available and decide whether the pop-up will go above or - // below the anchor. - anchor.getLocationOnScreen(screenLocation); - - final int below = displayFrame.bottom - screenLocation[1] - anchorHeight - yOffset; - final int above = screenLocation[1] - displayFrame.top + yOffset; - onTop = above > below; - - if (onTop) { - // Move everything up. - if (mOverlapAnchor) { - yOffset += anchorHeight; - } - outParams.y = drawingLocation[1] - height + yOffset; - } + private boolean tryFitVertical(@NonNull LayoutParams outParams, int yOffset, int height, + int anchorHeight, int drawingLocationY, int screenLocationY, int displayFrameTop, + int displayFrameBottom, boolean allowResize) { + final int anchorTopInScreen = screenLocationY + anchorHeight + yOffset; + final int spaceBelow = displayFrameBottom - anchorTopInScreen; + if (height <= spaceBelow) { + return true; + } + + final int spaceAbove = displayFrameTop + anchorTopInScreen - anchorHeight; + if (height <= spaceAbove) { + // Move everything up. + if (mOverlapAnchor) { + yOffset += anchorHeight; } + outParams.y = drawingLocationY - height + yOffset; + + return true; } - if (mClipToScreen) { - // Use screen coordinates for comparison against display frame. - final int winOffsetX = screenLocation[0] - drawingLocation[0]; - final int winOffsetY = screenLocation[1] - drawingLocation[1]; - outParams.x += winOffsetX; - outParams.y += winOffsetY; + if (positionInDisplayVertical(outParams, height, drawingLocationY, screenLocationY, + displayFrameTop, displayFrameBottom, allowResize)) { + return true; + } - final int right = outParams.x + width; - if (right > displayFrame.right) { - // The popup is too far right, move it back in. - outParams.x -= right - displayFrame.right; - } + return false; + } - if (outParams.x < displayFrame.left) { - // The popup is too far left, move it back in and clip if it's - // still too large. - outParams.x = displayFrame.left; + private boolean positionInDisplayVertical(@NonNull LayoutParams outParams, int height, + int drawingLocationY, int screenLocationY, int displayFrameTop, int displayFrameBottom, + boolean canResize) { + boolean fitsInDisplay = true; - final int displayFrameWidth = displayFrame.width(); - width = Math.min(width, displayFrameWidth); - } + final int winOffsetY = screenLocationY - drawingLocationY; + outParams.y += winOffsetY; + outParams.height = height; - final int bottom = outParams.y + height; - if (bottom > displayFrame.bottom) { - // The popup is too far down, move it back in. - outParams.y -= bottom - displayFrame.bottom; - } + final int bottom = outParams.y + height; + if (bottom > displayFrameBottom) { + // The popup is too far down, move it back in. + outParams.y -= bottom - displayFrameBottom; + } - if (outParams.y < displayFrame.top) { - // The popup is too far up, move it back in and clip if - // it's still too large. - outParams.y = displayFrame.top; + if (outParams.y < displayFrameTop) { + // The popup is too far up, move it back in and clip if + // it's still too large. + outParams.y = displayFrameTop; - final int displayFrameHeight = displayFrame.height(); - height = Math.min(height, displayFrameHeight); + final int displayFrameHeight = displayFrameBottom - displayFrameTop; + if (canResize && height > displayFrameHeight) { + outParams.height = displayFrameHeight; + } else { + fitsInDisplay = false; } + } + + outParams.y -= winOffsetY; - outParams.x -= winOffsetX; - outParams.y -= winOffsetY; + return fitsInDisplay; + } + + private boolean tryFitHorizontal(@NonNull LayoutParams outParams, int xOffset, int width, + int anchorWidth, int drawingLocationX, int screenLocationX, int displayFrameLeft, + int displayFrameRight, boolean allowResize) { + final int anchorLeftInScreen = screenLocationX + xOffset; + final int spaceRight = displayFrameRight - anchorLeftInScreen; + if (width <= spaceRight) { + return true; } - outParams.width = width; - outParams.height = height; + if (positionInDisplayHorizontal(outParams, width, drawingLocationX, screenLocationX, + displayFrameLeft, displayFrameRight, allowResize)) { + return true; + } + + return false; + } + + private boolean positionInDisplayHorizontal(@NonNull LayoutParams outParams, int width, + int drawingLocationX, int screenLocationX, int displayFrameLeft, int displayFrameRight, + boolean canResize) { + boolean fitsInDisplay = true; + + // Use screen coordinates for comparison against display frame. + final int winOffsetX = screenLocationX - drawingLocationX; + outParams.x += winOffsetX; + + final int right = outParams.x + width; + if (right > displayFrameRight) { + // The popup is too far right, move it back in. + outParams.x -= right - displayFrameRight; + } + + if (outParams.x < displayFrameLeft) { + // The popup is too far left, move it back in and clip if it's + // still too large. + outParams.x = displayFrameLeft; + + final int displayFrameWidth = displayFrameRight - displayFrameLeft; + if (canResize && width > displayFrameWidth) { + outParams.width = displayFrameWidth; + } else { + fitsInDisplay = false; + } + } + + outParams.x -= winOffsetX; - return onTop; + return fitsInDisplay; } /** @@ -1984,6 +2041,13 @@ public class PopupWindow { update = true; } + int newAccessibilityIdOfAnchor = + (mAnchor != null) ? mAnchor.get().getAccessibilityViewId() : -1; + if (newAccessibilityIdOfAnchor != p.accessibilityIdOfAnchor) { + p.accessibilityIdOfAnchor = newAccessibilityIdOfAnchor; + update = true; + } + if (update) { setLayoutDirectionFromAnchor(); mWindowManager.updateViewLayout(mDecorView, p); diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 7602416fa751..48fd58b219db 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -330,10 +330,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private int mCurTextColor; private int mCurHintTextColor; private boolean mFreezesText; - private boolean mDispatchTemporaryDetach; - - /** Whether this view is temporarily detached from the parent view. */ - boolean mTemporaryDetach; private Editable.Factory mEditableFactory = Editable.Factory.getInstance(); private Spannable.Factory mSpannableFactory = Spannable.Factory.getInstance(); @@ -3354,7 +3350,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mShadowColor = color; // Will change text clip region - if (mEditor != null) mEditor.invalidateTextDisplayList(); + if (mEditor != null) { + mEditor.invalidateTextDisplayList(); + mEditor.invalidateHandlesAndActionMode(); + } invalidate(); } @@ -5406,8 +5405,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener protected void onAttachedToWindow() { super.onAttachedToWindow(); - mTemporaryDetach = false; - if (mEditor != null) mEditor.onAttachedToWindow(); if (mPreDrawListenerDetached) { @@ -8289,14 +8286,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener newSelEnd = Selection.getSelectionEnd(buf); } - if (newSelStart == newSelEnd && hasTransientState()) { - setHasTransientState(false); - } else if (newSelStart != newSelEnd && !hasTransientState()) { - setHasTransientState(true); - } - if (mEditor != null) { mEditor.refreshTextActionMode(); + if (!hasSelection() && mEditor.mTextActionMode == null && hasTransientState()) { + // User generated selection has been removed. + setHasTransientState(false); + } } onSelectionChanged(newSelStart, newSelEnd); } @@ -8314,6 +8309,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (mEditor != null) { if (oldStart >= 0) mEditor.invalidateTextDisplayList(mLayout, oldStart, oldEnd); if (newStart >= 0) mEditor.invalidateTextDisplayList(mLayout, newStart, newEnd); + mEditor.invalidateHandlesAndActionMode(); } } @@ -8368,40 +8364,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } - /** - * @hide - */ - @Override - public void dispatchFinishTemporaryDetach() { - mDispatchTemporaryDetach = true; - super.dispatchFinishTemporaryDetach(); - mDispatchTemporaryDetach = false; - } - - @Override - public void onStartTemporaryDetach() { - super.onStartTemporaryDetach(); - // Only track when onStartTemporaryDetach() is called directly, - // usually because this instance is an editable field in a list - if (!mDispatchTemporaryDetach) mTemporaryDetach = true; - - // Tell the editor that we are temporarily detached. It can use this to preserve - // selection state as needed. - if (mEditor != null) mEditor.mTemporaryDetach = true; - } - - @Override - public void onFinishTemporaryDetach() { - super.onFinishTemporaryDetach(); - // Only track when onStartTemporaryDetach() is called directly, - // usually because this instance is an editable field in a list - if (!mDispatchTemporaryDetach) mTemporaryDetach = false; - if (mEditor != null) mEditor.mTemporaryDetach = false; - } - @Override protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { - if (mTemporaryDetach) { + if (isTemporarilyDetached()) { // If we are temporarily in the detach state, then do nothing. super.onFocusChanged(focused, direction, previouslyFocusedRect); return; @@ -9096,6 +9061,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (mBufferType == BufferType.EDITABLE) { info.setEditable(true); + if (isEnabled()) { + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SET_TEXT); + } } if (mEditor != null) { @@ -9227,6 +9195,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } } return false; + case AccessibilityNodeInfo.ACTION_SET_TEXT: { + if (!isEnabled() || (mBufferType != BufferType.EDITABLE)) { + return false; + } + CharSequence text = (arguments != null) ? arguments.getCharSequence( + AccessibilityNodeInfo.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE) : null; + setText(text); + if (text != null && text.length() > 0) { + Selection.setSelection((Spannable) mText, text.length()); + } + } return true; default: { return super.performAccessibilityActionInternal(action, arguments); } @@ -9235,52 +9214,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener private boolean performAccessibilityActionClick(Bundle arguments) { boolean handled = false; - boolean processed = false; if (!isEnabled()) { return false; } - if (arguments != null && arguments.containsKey( - AccessibilityNodeInfo.ACTION_ARGUMENT_CLICK_SPAN_INDEX_INT)) { - int spanIndex = arguments.getInt( - AccessibilityNodeInfo.ACTION_ARGUMENT_CLICK_SPAN_INDEX_INT, -1); - if (spanIndex >= 0 && hasSpannableText()) { - ClickableSpan[] spans = ((Spannable) mText).getSpans(0, - mText.length(), ClickableSpan.class); - if (spans != null && spans.length > spanIndex && spans[spanIndex] != null) { - // Simulate View.onTouchEvent for an ACTION_UP event - if (isFocusable() && !isFocused()) { - requestFocus(); - } - spans[spanIndex].onClick(this); - handled = true; - } - } - processed = true; - } - - if (!processed && arguments != null && arguments.containsKey( - AccessibilityNodeInfo.ACTION_ARGUMENT_CLICK_CHARACTER_INDEX_INT)) { - int characterIndex = arguments.getInt( - AccessibilityNodeInfo.ACTION_ARGUMENT_CLICK_CHARACTER_INDEX_INT, -1); - if (characterIndex >= 0 && hasSpannableText()) { - ClickableSpan[] spans = ((Spannable) mText).getSpans(characterIndex, - characterIndex, ClickableSpan.class); - // click only on the first span to keep parity with onTouch() implementation - if (spans != null && spans.length > 0 && spans[0] != null) { - // Simulate View.onTouchEvent for an ACTION_UP event - if (isFocusable() && !isFocused()) { - requestFocus(); - } - spans[0].onClick(this); - handled = true; - } - } - processed = true; - } - - if (!processed && (isClickable() || isLongClickable())) { + if (isClickable() || isLongClickable()) { // Simulate View.onTouchEvent for an ACTION_UP event if (isFocusable() && !isFocused()) { requestFocus(); diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java index 5b0a90adde33..9cdb73ae51ce 100644 --- a/core/java/android/widget/Toolbar.java +++ b/core/java/android/widget/Toolbar.java @@ -23,6 +23,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; import android.annotation.StyleRes; +import android.annotation.TestApi; import android.app.ActionBar; import android.content.Context; import android.content.res.TypedArray; @@ -976,6 +977,15 @@ public class Toolbar extends ViewGroup { } /** + * @hide + */ + @Nullable + @TestApi + public View getNavigationView() { + return mNavButtonView; + } + + /** * Return the Menu shown in the toolbar. * * <p>Applications that wish to populate the toolbar's menu can do so from here. To use diff --git a/core/java/com/android/internal/app/procstats/SparseMappingTable.java b/core/java/com/android/internal/app/procstats/SparseMappingTable.java index 64c49a2bc80d..725227610c88 100644 --- a/core/java/com/android/internal/app/procstats/SparseMappingTable.java +++ b/core/java/com/android/internal/app/procstats/SparseMappingTable.java @@ -28,7 +28,7 @@ import com.android.internal.util.GrowingArrayUtils; /** * Class that contains a set of tables mapping byte ids to long values. - * + * * This class is used to store the ProcessStats data. This data happens to be * a set of very sparse tables, that is mostly append or overwrite, with infrequent * resets of the data. @@ -59,11 +59,11 @@ public class SparseMappingTable { // Where the "index into array" part of the data appears in an offset integer. private static final int INDEX_SHIFT = 16; private static final int INDEX_MASK = 0xffff; - + private int mSequence; private int mNextIndex; private final ArrayList<long[]> mLongs = new ArrayList<long[]>(); - + /** * A table of data as stored in a SparseMappingTable. */ @@ -377,20 +377,24 @@ public class SparseMappingTable { // since we were created or reset. if (mSequence == UNINITIALIZED_SEQUENCE) { logOrThrow("mSequence == UNINITIALIZED_SEQUENCE in" - + " SparseMappingTable.Table. mParent.mSequence=" + mParent.mSequence); + + " SparseMappingTable.Table. -- " + + dumpInternalState()); + return; } // Assert that our sequence number matches mParent's. If it isn't that means - // we have been reset and our + // we have been reset and our if (mSequence != mParent.mSequence) { if (mSequence < mParent.mSequence) { logOrThrow("Sequence mismatch. SparseMappingTable.resetTable()" + " called but not Table.resetTable() -- " + dumpInternalState()); + return; } else if (mSequence > mParent.mSequence) { logOrThrow("Sequence mismatch. Table.resetTable()" + " called but not SparseMappingTable.resetTable() -- " + dumpInternalState()); + return; } } } @@ -423,7 +427,7 @@ public class SparseMappingTable { /** * Check that all the keys are valid locations in the long arrays. - * + * * If any aren't, log it and return false. Else return true. */ private boolean validateKeys(boolean log) { @@ -580,7 +584,7 @@ public class SparseMappingTable { i++; } } - + /** * Extract the id from a key. */ @@ -611,7 +615,7 @@ public class SparseMappingTable { * this is a debug build.) */ private static void logOrThrow(String message) { - logOrThrow(message, null); + logOrThrow(message, new RuntimeException("Stack trace")); } /** diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl index 5a195cb7dd20..4260e50a31f2 100644 --- a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl +++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl @@ -33,8 +33,8 @@ interface IAppWidgetService { // // for AppWidgetHost // - int[] startListening(IAppWidgetHost host, String callingPackage, int hostId, - out List<RemoteViews> updatedViews); + ParceledListSlice startListening(IAppWidgetHost host, String callingPackage, int hostId, + in int[] appWidgetIds, out int[] updatedIds); void stopListening(String callingPackage, int hostId); int allocateAppWidgetId(String callingPackage, int hostId); void deleteAppWidgetId(String callingPackage, int appWidgetId); diff --git a/core/java/com/android/internal/os/BackgroundThread.java b/core/java/com/android/internal/os/BackgroundThread.java index d6f7b20189a8..cffba0177d14 100644 --- a/core/java/com/android/internal/os/BackgroundThread.java +++ b/core/java/com/android/internal/os/BackgroundThread.java @@ -18,6 +18,7 @@ package com.android.internal.os; import android.os.Handler; import android.os.HandlerThread; +import android.os.Trace; /** * Shared singleton background thread for each process. @@ -34,6 +35,7 @@ public final class BackgroundThread extends HandlerThread { if (sInstance == null) { sInstance = new BackgroundThread(); sInstance.start(); + sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_ACTIVITY_MANAGER); sHandler = new Handler(sInstance.getLooper()); } } diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java index 14ebe227f3b4..79138b7b3fbd 100644 --- a/core/java/com/android/internal/os/PowerProfile.java +++ b/core/java/com/android/internal/os/PowerProfile.java @@ -85,6 +85,7 @@ public class PowerProfile { public static final String POWER_WIFI_CONTROLLER_IDLE = "wifi.controller.idle"; public static final String POWER_WIFI_CONTROLLER_RX = "wifi.controller.rx"; public static final String POWER_WIFI_CONTROLLER_TX = "wifi.controller.tx"; + public static final String POWER_WIFI_CONTROLLER_TX_LEVELS = "wifi.controller.tx_levels"; public static final String POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE = "wifi.controller.voltage"; public static final String POWER_BLUETOOTH_CONTROLLER_IDLE = "bluetooth.controller.idle"; @@ -287,9 +288,15 @@ public class PowerProfile { }; for (int i = 0; i < configResIds.length; i++) { + String key = configResIdKeys[i]; + // if we already have some of these parameters in power_profile.xml, ignore the + // value in config.xml + if ((sPowerMap.containsKey(key) && (Double) sPowerMap.get(key) > 0)) { + continue; + } int value = resources.getInteger(configResIds[i]); if (value > 0) { - sPowerMap.put(configResIdKeys[i], (double) value); + sPowerMap.put(key, (double) value); } } } diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl index e330de24f6d6..171a264eea8b 100644 --- a/core/java/com/android/internal/policy/IKeyguardService.aidl +++ b/core/java/com/android/internal/policy/IKeyguardService.aidl @@ -50,9 +50,12 @@ oneway interface IKeyguardService { * Called when the device has finished going to sleep. * * @param why {@link #OFF_BECAUSE_OF_USER}, {@link #OFF_BECAUSE_OF_ADMIN}, - * or {@link #OFF_BECAUSE_OF_TIMEOUT}. + * or {@link #OFF_BECAUSE_OF_TIMEOUT}. + * @param cameraGestureTriggered whether the camera gesture was triggered between + * {@link #onStartedGoingToSleep} and this method; if it's been + * triggered, we shouldn't lock the device. */ - void onFinishedGoingToSleep(int reason); + void onFinishedGoingToSleep(int reason, boolean cameraGestureTriggered); /** * Called when the device has started waking up. diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java index d80b63acb90f..0f257d78d5f5 100644 --- a/core/java/com/android/internal/policy/PhoneWindow.java +++ b/core/java/com/android/internal/policy/PhoneWindow.java @@ -24,6 +24,7 @@ import android.app.ActivityManagerNative; import android.app.SearchManager; import android.os.UserHandle; +import android.text.TextUtils; import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.IRotationWatcher.Stub; @@ -514,6 +515,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { mDecorContentParent.setWindowTitle(title); } mTitle = title; + WindowManager.LayoutParams params = getAttributes(); + if (!TextUtils.equals(title, params.getTitle())) { + params.setTitle(title); + dispatchWindowAttributesChanged(getAttributes()); + } } @Override diff --git a/core/java/com/android/internal/util/FastXmlSerializer.java b/core/java/com/android/internal/util/FastXmlSerializer.java index 7a040801a9a5..3c1d2d6ce581 100644 --- a/core/java/com/android/internal/util/FastXmlSerializer.java +++ b/core/java/com/android/internal/util/FastXmlSerializer.java @@ -28,6 +28,7 @@ import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; @@ -38,14 +39,14 @@ import java.nio.charset.UnsupportedCharsetException; */ public class FastXmlSerializer implements XmlSerializer { private static final String ESCAPE_TABLE[] = new String[] { - null, null, null, null, null, null, null, null, // 0-7 - null, null, null, null, null, null, null, null, // 8-15 - null, null, null, null, null, null, null, null, // 16-23 - null, null, null, null, null, null, null, null, // 24-31 - null, null, """, null, null, null, "&", null, // 32-39 - null, null, null, null, null, null, null, null, // 40-47 - null, null, null, null, null, null, null, null, // 48-55 - null, null, null, null, "<", null, ">", null, // 56-63 + "�", "", "", "", "", "", "", "", // 0-7 + "", "	", " ", "", "", " ", "", "", // 8-15 + "", "", "", "", "", "", "", "", // 16-23 + "", "", "", "", "", "", "", "", // 24-31 + null, null, """, null, null, null, "&", null, // 32-39 + null, null, null, null, null, null, null, null, // 40-47 + null, null, null, null, null, null, null, null, // 48-55 + null, null, null, null, "<", null, ">", null, // 56-63 }; private static final int BUFFER_LEN = 8192; @@ -310,7 +311,9 @@ public class FastXmlSerializer implements XmlSerializer { throw new IllegalArgumentException(); if (true) { try { - mCharset = Charset.forName(encoding).newEncoder(); + mCharset = Charset.forName(encoding).newEncoder() + .onMalformedInput(CodingErrorAction.REPLACE) + .onUnmappableCharacter(CodingErrorAction.REPLACE); } catch (IllegalCharsetNameException e) { throw (UnsupportedEncodingException) (new UnsupportedEncodingException( encoding).initCause(e)); diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index da223a64e2e8..1848fe88dea9 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -1460,6 +1460,7 @@ public final class FloatingToolbar { super(Preconditions.checkNotNull(popup).mContext); this.mPopup = popup; setScrollBarDefaultDelayBeforeFade(ViewConfiguration.getScrollDefaultDelay() * 3); + setScrollIndicators(View.SCROLL_INDICATOR_TOP | View.SCROLL_INDICATOR_BOTTOM); } @Override diff --git a/core/java/com/android/internal/widget/ILockSettings.aidl b/core/java/com/android/internal/widget/ILockSettings.aidl index b07e36adfdf7..21c4d1235042 100644 --- a/core/java/com/android/internal/widget/ILockSettings.aidl +++ b/core/java/com/android/internal/widget/ILockSettings.aidl @@ -33,9 +33,12 @@ interface ILockSettings { void setLockPassword(in String password, in String savedPassword, int userId); VerifyCredentialResponse checkPassword(in String password, int userId); VerifyCredentialResponse verifyPassword(in String password, long challenge, int userId); + VerifyCredentialResponse verifyTiedProfileChallenge(String password, boolean isPattern, long challenge, int userId); boolean checkVoldPassword(int userId); boolean havePattern(int userId); boolean havePassword(int userId); + void setSeparateProfileChallengeEnabled(int userId, boolean enabled, String managedUserPassword); + boolean getSeparateProfileChallengeEnabled(int userId); void registerStrongAuthTracker(in IStrongAuthTracker tracker); void unregisterStrongAuthTracker(in IStrongAuthTracker tracker); void requireStrongAuth(int strongAuthReason, int userId); diff --git a/core/java/com/android/internal/widget/LockPatternChecker.java b/core/java/com/android/internal/widget/LockPatternChecker.java index 4880664f1e7f..713f56f46266 100644 --- a/core/java/com/android/internal/widget/LockPatternChecker.java +++ b/core/java/com/android/internal/widget/LockPatternChecker.java @@ -145,6 +145,43 @@ public final class LockPatternChecker { } /** + * Verify a password asynchronously. + * + * @param utils The LockPatternUtils instance to use. + * @param password The password to check. + * @param challenge The challenge to verify against the pattern. + * @param userId The user to check against the pattern. + * @param callback The callback to be invoked with the verification result. + */ + public static AsyncTask<?, ?, ?> verifyTiedProfileChallenge(final LockPatternUtils utils, + final String password, + final boolean isPattern, + final long challenge, + final int userId, + final OnVerifyCallback callback) { + AsyncTask<Void, Void, byte[]> task = new AsyncTask<Void, Void, byte[]>() { + private int mThrottleTimeout; + + @Override + protected byte[] doInBackground(Void... args) { + try { + return utils.verifyTiedProfileChallenge(password, isPattern, challenge, userId); + } catch (RequestThrottledException ex) { + mThrottleTimeout = ex.getTimeoutMs(); + return null; + } + } + + @Override + protected void onPostExecute(byte[] result) { + callback.onVerified(result, mThrottleTimeout); + } + }; + task.execute(); + return task; + } + + /** * Checks a password asynchronously. * * @param utils The LockPatternUtils instance to use. diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 3d892afbb5f3..bceeaca8e343 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -137,8 +137,6 @@ public class LockPatternUtils { private static final String ENABLED_TRUST_AGENTS = "lockscreen.enabledtrustagents"; private static final String IS_TRUST_USUALLY_MANAGED = "lockscreen.istrustusuallymanaged"; - private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge"; - // Maximum allowed number of repeated or ordered characters in a sequence before we'll // consider it a complex PIN/password. public static final int MAX_ALLOWED_SEQUENCE = 3; @@ -377,6 +375,36 @@ public class LockPatternUtils { } } + + /** + * Check to see if a password matches the saved password. + * If password matches, return an opaque attestation that the challenge + * was verified. + * + * @param password The password to check. + * @param challenge The challenge to verify against the password + * @return the attestation that the challenge was verified, or null. + */ + public byte[] verifyTiedProfileChallenge(String password, boolean isPattern, long challenge, + int userId) throws RequestThrottledException { + throwIfCalledOnMainThread(); + try { + VerifyCredentialResponse response = + getLockSettings().verifyTiedProfileChallenge(password, isPattern, challenge, + userId); + + if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) { + return response.getPayload(); + } else if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_RETRY) { + throw new RequestThrottledException(response.getTimeout()); + } else { + return null; + } + } catch (RemoteException re) { + return null; + } + } + /** * Check to see if a password matches the saved password. If no password exists, * always returns true. @@ -785,6 +813,7 @@ public class LockPatternUtils { } getLockSettings().setLockPassword(password, savedPassword, userHandle); + getLockSettings().setSeparateProfileChallengeEnabled(userHandle, true, null); int computedQuality = computePasswordQuality(password); // Update the device encryption password. @@ -919,11 +948,23 @@ public class LockPatternUtils { /** * Enables/disables the Separate Profile Challenge for this {@param userHandle}. This is a no-op * for user handles that do not belong to a managed profile. + * + * @param userHandle Managed profile user id + * @param enabled True if separate challenge is enabled + * @param managedUserPassword Managed profile previous password. Null when {@param enabled} is + * true */ - public void setSeparateProfileChallengeEnabled(int userHandle, boolean enabled) { + public void setSeparateProfileChallengeEnabled(int userHandle, boolean enabled, + String managedUserPassword) { UserInfo info = getUserManager().getUserInfo(userHandle); if (info.isManagedProfile()) { - setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, enabled, userHandle); + try { + getLockSettings().setSeparateProfileChallengeEnabled(userHandle, enabled, + managedUserPassword); + onAfterChangingPassword(userHandle); + } catch (RemoteException e) { + Log.e(TAG, "Couldn't update work profile challenge enabled"); + } } } @@ -935,7 +976,13 @@ public class LockPatternUtils { if (info == null || !info.isManagedProfile()) { return false; } - return getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userHandle); + try { + return getLockSettings().getSeparateProfileChallengeEnabled(userHandle); + } catch (RemoteException e) { + Log.e(TAG, "Couldn't get separate profile challenge enabled"); + // Default value is false + return false; + } } /** diff --git a/core/java/com/android/internal/widget/ResolverDrawerLayout.java b/core/java/com/android/internal/widget/ResolverDrawerLayout.java index c4347f832bd5..25b487efdae6 100644 --- a/core/java/com/android/internal/widget/ResolverDrawerLayout.java +++ b/core/java/com/android/internal/widget/ResolverDrawerLayout.java @@ -17,9 +17,14 @@ package com.android.internal.widget; +import android.annotation.NonNull; import android.content.Context; import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; @@ -85,6 +90,10 @@ public class ResolverDrawerLayout extends ViewGroup { private final float mMinFlingVelocity; private final OverScroller mScroller; private final VelocityTracker mVelocityTracker; + private final Drawable mScrollIndicatorDrawable; + private final Drawable mFakeForeground; + + private View mButtonBar; private OnDismissedListener mOnDismissedListener; private RunOnDismissedListener mRunOnDismissedListener; @@ -106,6 +115,8 @@ public class ResolverDrawerLayout extends ViewGroup { } }; + private final int[] mTempOffset = new int[2]; + public ResolverDrawerLayout(Context context) { this(context, null); } @@ -127,6 +138,9 @@ public class ResolverDrawerLayout extends ViewGroup { mMaxCollapsedHeight); a.recycle(); + mScrollIndicatorDrawable = mContext.getDrawable(R.drawable.scroll_indicator_material); + mFakeForeground = new ColorDrawable(Color.TRANSPARENT); + mScroller = new OverScroller(context, AnimationUtils.loadInterpolator(context, android.R.interpolator.decelerate_quint)); mVelocityTracker = VelocityTracker.obtain(); @@ -138,6 +152,13 @@ public class ResolverDrawerLayout extends ViewGroup { setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES); } + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + + mButtonBar = findViewById(R.id.button_bar); + } + public void setSmallCollapsed(boolean smallCollapsed) { mSmallCollapsed = smallCollapsed; requestLayout(); @@ -202,8 +223,7 @@ public class ResolverDrawerLayout extends ViewGroup { } final boolean isCollapsedNew = mCollapseOffset != 0; if (isCollapsedOld != isCollapsedNew) { - notifyViewAccessibilityStateChangedIfNeeded( - AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED); + onCollapsedChanged(isCollapsedNew); } } else { // Start out collapsed at first unless we restored state for otherwise @@ -442,8 +462,7 @@ public class ResolverDrawerLayout extends ViewGroup { mTopOffset += dy; final boolean isCollapsedNew = newPos != 0; if (isCollapsedOld != isCollapsedNew) { - notifyViewAccessibilityStateChangedIfNeeded( - AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED); + onCollapsedChanged(isCollapsedNew); } postInvalidateOnAnimation(); return dy; @@ -451,6 +470,14 @@ public class ResolverDrawerLayout extends ViewGroup { return 0; } + private void onCollapsedChanged(boolean isCollapsed) { + notifyViewAccessibilityStateChangedIfNeeded( + AccessibilityEvent.CONTENT_CHANGE_TYPE_UNDEFINED); + + // Set a fake foreground so that we receive onDrawForeground(). + setForeground(isCollapsed ? mFakeForeground : null); + } + void dispatchOnDismissed() { if (mOnDismissedListener != null) { mOnDismissedListener.onDismissed(); @@ -709,6 +736,23 @@ public class ResolverDrawerLayout extends ViewGroup { } @Override + public void onDrawForeground(Canvas canvas) { + if (isCollapsed() && mButtonBar != null) { + // Draw the scroll indicator directly above the button bar. + final int height = mScrollIndicatorDrawable.getIntrinsicHeight(); + mButtonBar.getLocationInWindow(mTempOffset); + final int barTop = mTempOffset[1]; + getLocationInWindow(mTempOffset); + final int myTop = mTempOffset[1]; + final int top = (barTop - myTop) - height; + mScrollIndicatorDrawable.setBounds(0, top, getWidth(), top + height); + mScrollIndicatorDrawable.draw(canvas); + } + + super.onDrawForeground(canvas); + } + + @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { final int sourceWidth = MeasureSpec.getSize(widthMeasureSpec); int widthSize = sourceWidth; diff --git a/core/java/com/android/server/net/NetlinkTracker.java b/core/java/com/android/server/net/NetlinkTracker.java index d45982eff8ba..5b421d988e0a 100644 --- a/core/java/com/android/server/net/NetlinkTracker.java +++ b/core/java/com/android/server/net/NetlinkTracker.java @@ -102,6 +102,19 @@ public class NetlinkTracker extends BaseNetworkObserver { } @Override + public void interfaceRemoved(String iface) { + maybeLog("interfaceRemoved", iface); + if (mInterfaceName.equals(iface)) { + // Our interface was removed. Clear our LinkProperties and tell our owner that they are + // now empty. Note that from the moment that the interface is removed, any further + // interface-specific messages (e.g., RTM_DELADDR) will not reach us, because the netd + // code that parses them will not be able to resolve the ifindex to an interface name. + clearLinkProperties(); + mCallback.update(); + } + } + + @Override public void addressUpdated(String iface, LinkAddress address) { if (mInterfaceName.equals(iface)) { maybeLog("addressUpdated", iface, address); diff --git a/core/jni/Android.mk b/core/jni/Android.mk index c6112d971abe..8a512a6df06b 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -103,7 +103,6 @@ LOCAL_SRC_FILES:= \ android_util_jar_StrictJarFile.cpp \ android_graphics_Canvas.cpp \ android_graphics_Picture.cpp \ - android/graphics/AvoidXfermode.cpp \ android/graphics/Bitmap.cpp \ android/graphics/BitmapFactory.cpp \ android/graphics/Camera.cpp \ diff --git a/core/jni/android/graphics/AvoidXfermode.cpp b/core/jni/android/graphics/AvoidXfermode.cpp deleted file mode 100644 index 9ca1f26e3ab0..000000000000 --- a/core/jni/android/graphics/AvoidXfermode.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2006 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "AvoidXfermode.h" -#include "SkColorPriv.h" -#include "SkReadBuffer.h" -#include "SkWriteBuffer.h" -#include "SkString.h" - -AvoidXfermode::AvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode) { - if (tolerance > 255) { - tolerance = 255; - } - fTolerance = SkToU8(tolerance); - fOpColor = opColor; - fDistMul = (256 << 14) / (tolerance + 1); - fMode = mode; -} - -SkFlattenable* AvoidXfermode::CreateProc(SkReadBuffer& buffer) { - const SkColor color = buffer.readColor(); - const unsigned tolerance = buffer.readUInt(); - const unsigned mode = buffer.readUInt(); - return Create(color, tolerance, (Mode)mode); -} - -void AvoidXfermode::flatten(SkWriteBuffer& buffer) const { - buffer.writeColor(fOpColor); - buffer.writeUInt(fTolerance); - buffer.writeUInt(fMode); -} - -// returns 0..31 -static unsigned color_dist16(uint16_t c, unsigned r, unsigned g, unsigned b) { - SkASSERT(r <= SK_R16_MASK); - SkASSERT(g <= SK_G16_MASK); - SkASSERT(b <= SK_B16_MASK); - - unsigned dr = SkAbs32(SkGetPackedR16(c) - r); - unsigned dg = SkAbs32(SkGetPackedG16(c) - g) >> (SK_G16_BITS - SK_R16_BITS); - unsigned db = SkAbs32(SkGetPackedB16(c) - b); - - return SkMax32(dr, SkMax32(dg, db)); -} - -// returns 0..255 -static unsigned color_dist32(SkPMColor c, U8CPU r, U8CPU g, U8CPU b) { - SkASSERT(r <= 0xFF); - SkASSERT(g <= 0xFF); - SkASSERT(b <= 0xFF); - - unsigned dr = SkAbs32(SkGetPackedR32(c) - r); - unsigned dg = SkAbs32(SkGetPackedG32(c) - g); - unsigned db = SkAbs32(SkGetPackedB32(c) - b); - - return SkMax32(dr, SkMax32(dg, db)); -} - -static int scale_dist_14(int dist, uint32_t mul, uint32_t sub) { - int tmp = dist * mul - sub; - int result = (tmp + (1 << 13)) >> 14; - - return result; -} - -static inline unsigned Accurate255To256(unsigned x) { - return x + (x >> 7); -} - -void AvoidXfermode::xfer32(SkPMColor dst[], const SkPMColor src[], int count, - const SkAlpha aa[]) const { - unsigned opR = SkColorGetR(fOpColor); - unsigned opG = SkColorGetG(fOpColor); - unsigned opB = SkColorGetB(fOpColor); - uint32_t mul = fDistMul; - uint32_t sub = (fDistMul - (1 << 14)) << 8; - - int MAX, mask; - - if (kTargetColor_Mode == fMode) { - mask = -1; - MAX = 255; - } else { - mask = 0; - MAX = 0; - } - - for (int i = 0; i < count; i++) { - int d = color_dist32(dst[i], opR, opG, opB); - // now reverse d if we need to - d = MAX + (d ^ mask) - mask; - SkASSERT((unsigned)d <= 255); - d = Accurate255To256(d); - - d = scale_dist_14(d, mul, sub); - SkASSERT(d <= 256); - - if (d > 0) { - if (aa) { - d = SkAlphaMul(d, Accurate255To256(*aa++)); - if (0 == d) { - continue; - } - } - dst[i] = SkFourByteInterp256(src[i], dst[i], d); - } - } -} - -static inline U16CPU SkBlend3216(SkPMColor src, U16CPU dst, unsigned scale) { - SkASSERT(scale <= 32); - scale <<= 3; - - return SkPackRGB16( SkAlphaBlend(SkPacked32ToR16(src), SkGetPackedR16(dst), scale), - SkAlphaBlend(SkPacked32ToG16(src), SkGetPackedG16(dst), scale), - SkAlphaBlend(SkPacked32ToB16(src), SkGetPackedB16(dst), scale)); -} - -void AvoidXfermode::xfer16(uint16_t dst[], const SkPMColor src[], int count, - const SkAlpha aa[]) const { - unsigned opR = SkColorGetR(fOpColor) >> (8 - SK_R16_BITS); - unsigned opG = SkColorGetG(fOpColor) >> (8 - SK_G16_BITS); - unsigned opB = SkColorGetB(fOpColor) >> (8 - SK_R16_BITS); - uint32_t mul = fDistMul; - uint32_t sub = (fDistMul - (1 << 14)) << SK_R16_BITS; - - int MAX, mask; - - if (kTargetColor_Mode == fMode) { - mask = -1; - MAX = 31; - } else { - mask = 0; - MAX = 0; - } - - for (int i = 0; i < count; i++) { - int d = color_dist16(dst[i], opR, opG, opB); - // now reverse d if we need to - d = MAX + (d ^ mask) - mask; - SkASSERT((unsigned)d <= 31); - // convert from 0..31 to 0..32 - d += d >> 4; - d = scale_dist_14(d, mul, sub); - SkASSERT(d <= 32); - - if (d > 0) { - if (aa) { - d = SkAlphaMul(d, Accurate255To256(*aa++)); - if (0 == d) { - continue; - } - } - dst[i] = SkBlend3216(src[i], dst[i], d); - } - } -} - -void AvoidXfermode::xferA8(SkAlpha dst[], const SkPMColor src[], int count, - const SkAlpha aa[]) const { -} - -#ifndef SK_IGNORE_TO_STRING -void AvoidXfermode::toString(SkString* str) const { - str->append("AvoidXfermode: opColor: "); - str->appendHex(fOpColor); - str->appendf("distMul: %d ", fDistMul); - - static const char* gModeStrings[] = { "Avoid", "Target" }; - - str->appendf("mode: %s", gModeStrings[fMode]); -} -#endif diff --git a/core/jni/android/graphics/AvoidXfermode.h b/core/jni/android/graphics/AvoidXfermode.h deleted file mode 100644 index 8b7fb7165133..000000000000 --- a/core/jni/android/graphics/AvoidXfermode.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2006 The Android Open Source Project - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#ifndef AvoidXfermode_DEFINED -#define AvoidXfermode_DEFINED - -#include "SkColor.h" -#include "SkTypes.h" -#include "SkXfermode.h" - -/** \class AvoidXfermode - - This xfermode will draw the src everywhere except on top of the specified - color. -*/ -class AvoidXfermode : public SkXfermode { -public: - enum Mode { - kAvoidColor_Mode, //!< draw everywhere except on the opColor - kTargetColor_Mode //!< draw only on top of the opColor - }; - - /** This xfermode draws, or doesn't draw, based on the destination's - distance from an op-color. - - There are two modes, and each mode interprets a tolerance value. - - Avoid: In this mode, drawing is allowed only on destination pixels that - are different from the op-color. - Tolerance near 0: avoid any colors even remotely similar to the op-color - Tolerance near 255: avoid only colors nearly identical to the op-color - - Target: In this mode, drawing only occurs on destination pixels that - are similar to the op-color - Tolerance near 0: draw only on colors that are nearly identical to the op-color - Tolerance near 255: draw on any colors even remotely similar to the op-color - */ - static AvoidXfermode* Create(SkColor opColor, U8CPU tolerance, Mode mode) { - return new AvoidXfermode(opColor, tolerance, mode); - } - - // overrides from SkXfermode - void xfer32(SkPMColor dst[], const SkPMColor src[], int count, - const SkAlpha aa[]) const override; - void xfer16(uint16_t dst[], const SkPMColor src[], int count, - const SkAlpha aa[]) const override; - void xferA8(SkAlpha dst[], const SkPMColor src[], int count, - const SkAlpha aa[]) const override; - - SK_TO_STRING_OVERRIDE() - SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(AvoidXfermode) - -protected: - AvoidXfermode(SkColor opColor, U8CPU tolerance, Mode mode); - void flatten(SkWriteBuffer&) const override; - -private: - SkColor fOpColor; - uint32_t fDistMul; // x.14 cached from fTolerance - uint8_t fTolerance; - Mode fMode; - - typedef SkXfermode INHERITED; -}; - -#endif diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 1844a9870ada..f46f45cc5e5d 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -768,6 +768,22 @@ namespace PaintGlue { return false; } + // Returns true if the given string is exact one pair of regional indicators. + static bool isFlag(const jchar* str, size_t length) { + const jchar RI_LEAD_SURROGATE = 0xD83C; + const jchar RI_TRAIL_SURROGATE_MIN = 0xDDE6; + const jchar RI_TRAIL_SURROGATE_MAX = 0xDDFF; + + if (length != 4) { + return false; + } + if (str[0] != RI_LEAD_SURROGATE || str[2] != RI_LEAD_SURROGATE) { + return false; + } + return RI_TRAIL_SURROGATE_MIN <= str[1] && str[1] <= RI_TRAIL_SURROGATE_MAX && + RI_TRAIL_SURROGATE_MIN <= str[3] && str[3] <= RI_TRAIL_SURROGATE_MAX; + } + static jboolean hasGlyph(JNIEnv *env, jclass, jlong paintHandle, jlong typefaceHandle, jint bidiFlags, jstring string) { const Paint* paint = reinterpret_cast<Paint*>(paintHandle); @@ -817,7 +833,26 @@ namespace PaintGlue { // in joining scripts, such as Arabic and Mongolian. return false; } - return nGlyphs > 0 && !layoutContainsNotdef(layout); + + if (nGlyphs == 0 || layoutContainsNotdef(layout)) { + return false; // The collection doesn't have a glyph. + } + + if (nChars == 2 && isFlag(str.get(), str.size())) { + // Some font may have a special glyph for unsupported regional indicator pairs. + // To return false for this case, need to compare the glyph id with the one of ZZ + // since ZZ is reserved for unknown or invalid territory. + // U+1F1FF (REGIONAL INDICATOR SYMBOL LETTER Z) is \uD83C\uDDFF in UTF16. + static const jchar ZZ_FLAG_STR[] = { 0xD83C, 0xDDFF, 0xD83C, 0xDDFF }; + Layout zzLayout; + MinikinUtils::doLayout(&zzLayout, paint, bidiFlags, typeface, ZZ_FLAG_STR, 0, 4, 4); + if (zzLayout.nGlyphs() != 1 || layoutContainsNotdef(zzLayout)) { + // The font collection doesn't have a glyph for unknown flag. Just return true. + return true; + } + return zzLayout.getGlyphId(0) != layout.getGlyphId(0); + } + return true; } static jfloat doRunAdvance(const Paint* paint, Typeface* typeface, const jchar buf[], diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp index 2018e76e9bee..6e9830ec3852 100644 --- a/core/jni/android/graphics/SurfaceTexture.cpp +++ b/core/jni/android/graphics/SurfaceTexture.cpp @@ -65,12 +65,12 @@ static bool isProtectedContext() { EGLContext ctx = eglGetCurrentContext(); if (dpy == EGL_NO_DISPLAY) { - ALOGE("isProtectedSurface: invalid current EGLDisplay"); + ALOGI("isProtectedSurface: invalid current EGLDisplay"); return false; } if (ctx == EGL_NO_CONTEXT) { - ALOGE("isProtectedSurface: invalid current EGLContext"); + ALOGI("isProtectedSurface: invalid current EGLContext"); return false; } diff --git a/core/jni/android_graphics_drawable_VectorDrawable.cpp b/core/jni/android_graphics_drawable_VectorDrawable.cpp index a2662f9e81c7..b04293e0afa8 100644 --- a/core/jni/android_graphics_drawable_VectorDrawable.cpp +++ b/core/jni/android_graphics_drawable_VectorDrawable.cpp @@ -14,11 +14,11 @@ * limitations under the License. */ -#include "jni.h" #include "GraphicsJNI.h" +#include "jni.h" #include "core_jni_helpers.h" -#include "log/log.h" +#include "PathParser.h" #include "VectorDrawable.h" #include <hwui/Paint.h> @@ -27,26 +27,61 @@ namespace android { using namespace uirenderer; using namespace uirenderer::VectorDrawable; +/** + * VectorDrawable's pre-draw construction. + */ static jlong createTree(JNIEnv*, jobject, jlong groupPtr) { VectorDrawable::Group* rootGroup = reinterpret_cast<VectorDrawable::Group*>(groupPtr); VectorDrawable::Tree* tree = new VectorDrawable::Tree(rootGroup); return reinterpret_cast<jlong>(tree); } -static void setTreeViewportSize(JNIEnv*, jobject, jlong treePtr, - jfloat viewportWidth, jfloat viewportHeight) { - VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr); - tree->setViewportSize(viewportWidth, viewportHeight); +static jlong createEmptyFullPath(JNIEnv*, jobject) { + VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath(); + return reinterpret_cast<jlong>(newPath); } -static jboolean setRootAlpha(JNIEnv*, jobject, jlong treePtr, jfloat alpha) { - VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr); - return tree->setRootAlpha(alpha); +static jlong createFullPath(JNIEnv*, jobject, jlong srcFullPathPtr) { + VectorDrawable::FullPath* srcFullPath = + reinterpret_cast<VectorDrawable::FullPath*>(srcFullPathPtr); + VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath(*srcFullPath); + return reinterpret_cast<jlong>(newPath); } -static jfloat getRootAlpha(JNIEnv*, jobject, jlong treePtr) { - VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr); - return tree->getRootAlpha(); +static jlong createEmptyClipPath(JNIEnv*, jobject) { + VectorDrawable::ClipPath* newPath = new VectorDrawable::ClipPath(); + return reinterpret_cast<jlong>(newPath); +} + +static jlong createClipPath(JNIEnv*, jobject, jlong srcClipPathPtr) { + VectorDrawable::ClipPath* srcClipPath = + reinterpret_cast<VectorDrawable::ClipPath*>(srcClipPathPtr); + VectorDrawable::ClipPath* newPath = new VectorDrawable::ClipPath(*srcClipPath); + return reinterpret_cast<jlong>(newPath); +} + +static jlong createEmptyGroup(JNIEnv*, jobject) { + VectorDrawable::Group* newGroup = new VectorDrawable::Group(); + return reinterpret_cast<jlong>(newGroup); +} + +static jlong createGroup(JNIEnv*, jobject, jlong srcGroupPtr) { + VectorDrawable::Group* srcGroup = reinterpret_cast<VectorDrawable::Group*>(srcGroupPtr); + VectorDrawable::Group* newGroup = new VectorDrawable::Group(*srcGroup); + return reinterpret_cast<jlong>(newGroup); +} + +static void setNodeName(JNIEnv* env, jobject, jlong nodePtr, jstring nameStr) { + VectorDrawable::Node* node = reinterpret_cast<VectorDrawable::Node*>(nodePtr); + const char* nodeName = env->GetStringUTFChars(nameStr, NULL); + node->setName(nodeName); + env->ReleaseStringUTFChars(nameStr, nodeName); +} + +static void addChild(JNIEnv*, jobject, jlong groupPtr, jlong childPtr) { + VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); + VectorDrawable::Node* child = reinterpret_cast<VectorDrawable::Node*>(childPtr); + group->addChild(child); } static void setAllowCaching(JNIEnv*, jobject, jlong treePtr, jboolean allowCaching) { @@ -54,6 +89,9 @@ static void setAllowCaching(JNIEnv*, jobject, jlong treePtr, jboolean allowCachi tree->setAllowCaching(allowCaching); } +/** + * Draw + */ static void draw(JNIEnv* env, jobject, jlong treePtr, jlong canvasPtr, jlong colorFilterPtr, jobject jrect, jboolean needsMirroring, jboolean canReuseCache) { VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr); @@ -64,16 +102,23 @@ static void draw(JNIEnv* env, jobject, jlong treePtr, jlong canvasPtr, tree->draw(canvas, colorFilter, rect, needsMirroring, canReuseCache); } -static jlong createEmptyFullPath(JNIEnv*, jobject) { - VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath(); - return reinterpret_cast<jlong>(newPath); +/** + * Setters and getters for updating staging properties that can happen both pre-draw and post draw. + */ +static void setTreeViewportSize(JNIEnv*, jobject, jlong treePtr, + jfloat viewportWidth, jfloat viewportHeight) { + VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr); + tree->mutateStagingProperties()->setViewportSize(viewportWidth, viewportHeight); } -static jlong createFullPath(JNIEnv*, jobject, jlong srcFullPathPtr) { - VectorDrawable::FullPath* srcFullPath = - reinterpret_cast<VectorDrawable::FullPath*>(srcFullPathPtr); - VectorDrawable::FullPath* newPath = new VectorDrawable::FullPath(*srcFullPath); - return reinterpret_cast<jlong>(newPath); +static jboolean setRootAlpha(JNIEnv*, jobject, jlong treePtr, jfloat alpha) { + VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr); + return tree->mutateStagingProperties()->setRootAlpha(alpha); +} + +static jfloat getRootAlpha(JNIEnv*, jobject, jlong treePtr) { + VectorDrawable::Tree* tree = reinterpret_cast<VectorDrawable::Tree*>(treePtr); + return tree->stagingProperties()->getRootAlpha(); } static void updateFullPathPropertiesAndStrokeStyles(JNIEnv*, jobject, jlong fullPathPtr, @@ -81,28 +126,28 @@ static void updateFullPathPropertiesAndStrokeStyles(JNIEnv*, jobject, jlong full jfloat trimPathStart, jfloat trimPathEnd, jfloat trimPathOffset, jfloat strokeMiterLimit, jint strokeLineCap, jint strokeLineJoin, jint fillType) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - fullPath->updateProperties(strokeWidth, strokeColor, strokeAlpha, fillColor, fillAlpha, - trimPathStart, trimPathEnd, trimPathOffset, strokeMiterLimit, strokeLineCap, - strokeLineJoin, fillType); + fullPath->mutateStagingProperties()->updateProperties(strokeWidth, strokeColor, strokeAlpha, + fillColor, fillAlpha, trimPathStart, trimPathEnd, trimPathOffset, strokeMiterLimit, + strokeLineCap, strokeLineJoin, fillType); } static void updateFullPathFillGradient(JNIEnv*, jobject, jlong pathPtr, jlong fillGradientPtr) { VectorDrawable::FullPath* path = reinterpret_cast<VectorDrawable::FullPath*>(pathPtr); SkShader* fillShader = reinterpret_cast<SkShader*>(fillGradientPtr); - path->setFillGradient(fillShader); + path->mutateStagingProperties()->setFillGradient(fillShader); } static void updateFullPathStrokeGradient(JNIEnv*, jobject, jlong pathPtr, jlong strokeGradientPtr) { VectorDrawable::FullPath* path = reinterpret_cast<VectorDrawable::FullPath*>(pathPtr); SkShader* strokeShader = reinterpret_cast<SkShader*>(strokeGradientPtr); - path->setStrokeGradient(strokeShader); + path->mutateStagingProperties()->setStrokeGradient(strokeShader); } static jboolean getFullPathProperties(JNIEnv* env, jobject, jlong fullPathPtr, jbyteArray outProperties, jint length) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); int8_t pathProperties[length]; - bool success = fullPath->getProperties(pathProperties, length); + bool success = fullPath->stagingProperties()->copyProperties(pathProperties, length); env->SetByteArrayRegion(outProperties, 0, length, reinterpret_cast<int8_t*>(&pathProperties)); return success; } @@ -111,215 +156,187 @@ static jboolean getGroupProperties(JNIEnv* env, jobject, jlong groupPtr, jfloatArray outProperties, jint length) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); float groupProperties[length]; - bool success = group->getProperties(groupProperties, length); + bool success = group->stagingProperties()->copyProperties(groupProperties, length); env->SetFloatArrayRegion(outProperties, 0, length, reinterpret_cast<float*>(&groupProperties)); return success; } -static jlong createEmptyClipPath(JNIEnv*, jobject) { - VectorDrawable::ClipPath* newPath = new VectorDrawable::ClipPath(); - return reinterpret_cast<jlong>(newPath); -} - -static jlong createClipPath(JNIEnv*, jobject, jlong srcClipPathPtr) { - VectorDrawable::ClipPath* srcClipPath = - reinterpret_cast<VectorDrawable::ClipPath*>(srcClipPathPtr); - VectorDrawable::ClipPath* newPath = new VectorDrawable::ClipPath(*srcClipPath); - return reinterpret_cast<jlong>(newPath); -} - -static jlong createEmptyGroup(JNIEnv*, jobject) { - VectorDrawable::Group* newGroup = new VectorDrawable::Group(); - return reinterpret_cast<jlong>(newGroup); -} - -static jlong createGroup(JNIEnv*, jobject, jlong srcGroupPtr) { - VectorDrawable::Group* srcGroup = reinterpret_cast<VectorDrawable::Group*>(srcGroupPtr); - VectorDrawable::Group* newGroup = new VectorDrawable::Group(*srcGroup); - return reinterpret_cast<jlong>(newGroup); -} - -static void setNodeName(JNIEnv* env, jobject, jlong nodePtr, jstring nameStr) { - VectorDrawable::Node* node = reinterpret_cast<VectorDrawable::Node*>(nodePtr); - const char* nodeName = env->GetStringUTFChars(nameStr, NULL); - node->setName(nodeName); - env->ReleaseStringUTFChars(nameStr, nodeName); -} - static void updateGroupProperties(JNIEnv*, jobject, jlong groupPtr, jfloat rotate, jfloat pivotX, jfloat pivotY, jfloat scaleX, jfloat scaleY, jfloat translateX, jfloat translateY) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - group->updateLocalMatrix(rotate, pivotX, pivotY, scaleX, scaleY, translateX, translateY); -} - -static void addChild(JNIEnv*, jobject, jlong groupPtr, jlong childPtr) { - VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - VectorDrawable::Node* child = reinterpret_cast<VectorDrawable::Node*>(childPtr); - group->addChild(child); + group->mutateStagingProperties()->updateProperties(rotate, pivotX, pivotY, scaleX, scaleY, + translateX, translateY); } static void setPathString(JNIEnv* env, jobject, jlong pathPtr, jstring inputStr, jint stringLength) { VectorDrawable::Path* path = reinterpret_cast<VectorDrawable::Path*>(pathPtr); const char* pathString = env->GetStringUTFChars(inputStr, NULL); - path->setPath(pathString, stringLength); + + PathParser::ParseResult result; + PathData data; + PathParser::getPathDataFromString(&data, &result, pathString, stringLength); + path->mutateStagingProperties()->setData(data); env->ReleaseStringUTFChars(inputStr, pathString); } +/** + * Setters and getters that should only be called from animation thread for animation purpose. + */ static jfloat getRotation(JNIEnv*, jobject, jlong groupPtr) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - return group->getRotation(); + return group->stagingProperties()->getRotation(); } static void setRotation(JNIEnv*, jobject, jlong groupPtr, jfloat rotation) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - group->setRotation(rotation); + group->mutateStagingProperties()->setRotation(rotation); } static jfloat getPivotX(JNIEnv*, jobject, jlong groupPtr) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - return group->getPivotX(); + return group->stagingProperties()->getPivotX(); } static void setPivotX(JNIEnv*, jobject, jlong groupPtr, jfloat pivotX) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - group->setPivotX(pivotX); + group->mutateStagingProperties()->setPivotX(pivotX); } static jfloat getPivotY(JNIEnv*, jobject, jlong groupPtr) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - return group->getPivotY(); + return group->stagingProperties()->getPivotY(); } static void setPivotY(JNIEnv*, jobject, jlong groupPtr, jfloat pivotY) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - group->setPivotY(pivotY); + group->mutateStagingProperties()->setPivotY(pivotY); } static jfloat getScaleX(JNIEnv*, jobject, jlong groupPtr) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - return group->getScaleX(); + return group->stagingProperties()->getScaleX(); } static void setScaleX(JNIEnv*, jobject, jlong groupPtr, jfloat scaleX) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - group->setScaleX(scaleX); + group->mutateStagingProperties()->setScaleX(scaleX); } static jfloat getScaleY(JNIEnv*, jobject, jlong groupPtr) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - return group->getScaleY(); + return group->stagingProperties()->getScaleY(); } static void setScaleY(JNIEnv*, jobject, jlong groupPtr, jfloat scaleY) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - group->setScaleY(scaleY); + group->mutateStagingProperties()->setScaleY(scaleY); } static jfloat getTranslateX(JNIEnv*, jobject, jlong groupPtr) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - return group->getTranslateX(); + return group->stagingProperties()->getTranslateX(); } static void setTranslateX(JNIEnv*, jobject, jlong groupPtr, jfloat translateX) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - group->setTranslateX(translateX); + group->mutateStagingProperties()->setTranslateX(translateX); } static jfloat getTranslateY(JNIEnv*, jobject, jlong groupPtr) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - return group->getTranslateY(); + return group->stagingProperties()->getTranslateY(); } static void setTranslateY(JNIEnv*, jobject, jlong groupPtr, jfloat translateY) { VectorDrawable::Group* group = reinterpret_cast<VectorDrawable::Group*>(groupPtr); - group->setTranslateY(translateY); + group->mutateStagingProperties()->setTranslateY(translateY); } static void setPathData(JNIEnv*, jobject, jlong pathPtr, jlong pathDataPtr) { VectorDrawable::Path* path = reinterpret_cast<VectorDrawable::Path*>(pathPtr); PathData* pathData = reinterpret_cast<PathData*>(pathDataPtr); - path->setPathData(*pathData); + path->mutateStagingProperties()->setData(*pathData); } static jfloat getStrokeWidth(JNIEnv*, jobject, jlong fullPathPtr) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - return fullPath->getStrokeWidth(); + return fullPath->stagingProperties()->getStrokeWidth(); } static void setStrokeWidth(JNIEnv*, jobject, jlong fullPathPtr, jfloat strokeWidth) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - fullPath->setStrokeWidth(strokeWidth); + fullPath->mutateStagingProperties()->setStrokeWidth(strokeWidth); } static jint getStrokeColor(JNIEnv*, jobject, jlong fullPathPtr) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - return fullPath->getStrokeColor(); + return fullPath->stagingProperties()->getStrokeColor(); } static void setStrokeColor(JNIEnv*, jobject, jlong fullPathPtr, jint strokeColor) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - fullPath->setStrokeColor(strokeColor); + fullPath->mutateStagingProperties()->setStrokeColor(strokeColor); } static jfloat getStrokeAlpha(JNIEnv*, jobject, jlong fullPathPtr) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - return fullPath->getStrokeAlpha(); + return fullPath->stagingProperties()->getStrokeAlpha(); } static void setStrokeAlpha(JNIEnv*, jobject, jlong fullPathPtr, jfloat strokeAlpha) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - fullPath->setStrokeAlpha(strokeAlpha); + fullPath->mutateStagingProperties()->setStrokeAlpha(strokeAlpha); } static jint getFillColor(JNIEnv*, jobject, jlong fullPathPtr) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - return fullPath->getFillColor(); + return fullPath->stagingProperties()->getFillColor(); } static void setFillColor(JNIEnv*, jobject, jlong fullPathPtr, jint fillColor) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - fullPath->setFillColor(fillColor); + fullPath->mutateStagingProperties()->setFillColor(fillColor); } static jfloat getFillAlpha(JNIEnv*, jobject, jlong fullPathPtr) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - return fullPath->getFillAlpha(); + return fullPath->stagingProperties()->getFillAlpha(); } static void setFillAlpha(JNIEnv*, jobject, jlong fullPathPtr, jfloat fillAlpha) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - fullPath->setFillAlpha(fillAlpha); + fullPath->mutateStagingProperties()->setFillAlpha(fillAlpha); } static jfloat getTrimPathStart(JNIEnv*, jobject, jlong fullPathPtr) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - return fullPath->getTrimPathStart(); + return fullPath->stagingProperties()->getTrimPathStart(); } static void setTrimPathStart(JNIEnv*, jobject, jlong fullPathPtr, jfloat trimPathStart) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - fullPath->setTrimPathStart(trimPathStart); + fullPath->mutateStagingProperties()->setTrimPathStart(trimPathStart); } static jfloat getTrimPathEnd(JNIEnv*, jobject, jlong fullPathPtr) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - return fullPath->getTrimPathEnd(); + return fullPath->stagingProperties()->getTrimPathEnd(); } static void setTrimPathEnd(JNIEnv*, jobject, jlong fullPathPtr, jfloat trimPathEnd) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - fullPath->setTrimPathEnd(trimPathEnd); + fullPath->mutateStagingProperties()->setTrimPathEnd(trimPathEnd); } static jfloat getTrimPathOffset(JNIEnv*, jobject, jlong fullPathPtr) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - return fullPath->getTrimPathOffset(); + return fullPath->stagingProperties()->getTrimPathOffset(); } static void setTrimPathOffset(JNIEnv*, jobject, jlong fullPathPtr, jfloat trimPathOffset) { VectorDrawable::FullPath* fullPath = reinterpret_cast<VectorDrawable::FullPath*>(fullPathPtr); - fullPath->setTrimPathOffset(trimPathOffset); + fullPath->mutateStagingProperties()->setTrimPathOffset(trimPathOffset); } static const JNINativeMethod gMethods[] = { diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp index 42dc983792d2..91a3b4f77052 100644 --- a/core/jni/android_hardware_location_ContextHubService.cpp +++ b/core/jni/android_hardware_location_ContextHubService.cpp @@ -33,7 +33,7 @@ #include "JNIHelp.h" #include "core_jni_helpers.h" -//static constexpr int OS_APP_ID=-1; +static constexpr int OS_APP_ID=-1; static constexpr int MIN_APP_ID=1; static constexpr int MAX_APP_ID=128; @@ -145,6 +145,14 @@ static int set_os_app_as_destination(hub_message_t *msg, int hubHandle) { } } +static int get_hub_id_for_hub_handle(int hubHandle) { + if (hubHandle < 0 || hubHandle >= db.hubInfo.numHubs) { + return -1; + } else { + return db.hubInfo.hubs[hubHandle].hub_id; + } +} + static int get_hub_id_for_app_instance(int id) { if (db.appInstances.find(id) == db.appInstances.end()) { ALOGD("%s: Cannot find app for app instance %d", __FUNCTION__, id); @@ -374,6 +382,9 @@ int handle_os_message(uint32_t msgType, uint32_t hubHandle, char *msg, int msgLen) { int retVal; + //ALOGD("Rcd OS message from hubHandle %" PRIu32 " type %" PRIu32 " length %d", + // hubHandle, msgType, msgLen); + switch(msgType) { case CONTEXT_HUB_APPS_ENABLE: retVal = 0; @@ -616,7 +627,6 @@ static jobjectArray nativeInitialize(JNIEnv *env, jobject instance) static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_, jbyteArray data_) { - hub_message_t msg; jint retVal = -1; // Default to failure jint *header = env->GetIntArrayElements(header_, 0); @@ -624,16 +634,30 @@ static jint nativeSendMessage(JNIEnv *env, jobject instance, jintArray header_, jbyte *data = env->GetByteArrayElements(data_, 0); int dataBufferLength = env->GetArrayLength(data_); + if (numHeaderElements >= MSG_HEADER_SIZE) { - if (set_dest_app(&msg, header[HEADER_FIELD_APP_INSTANCE]) == 0) { - msg.message_type = header[HEADER_FIELD_MSG_TYPE]; - msg.message_len = dataBufferLength; - msg.message = data; - retVal = db.hubInfo.contextHubModule->send_message( - get_hub_id_for_app_instance(header[HEADER_FIELD_APP_INSTANCE]), - &msg); + bool setAddressSuccess; + int hubId; + hub_message_t msg; + + if (header[HEADER_FIELD_APP_INSTANCE] == OS_APP_ID) { + setAddressSuccess = (set_os_app_as_destination(&msg, header[HEADER_FIELD_HUB_HANDLE]) == 0); + hubId = get_hub_id_for_hub_handle(header[HEADER_FIELD_HUB_HANDLE]); + } else { + setAddressSuccess = (set_dest_app(&msg, header[HEADER_FIELD_APP_INSTANCE]) == 0); + hubId = get_hub_id_for_app_instance(header[HEADER_FIELD_APP_INSTANCE]); + } + + if (setAddressSuccess && hubId >= 0) { + msg.message_type = header[HEADER_FIELD_MSG_TYPE]; + msg.message_len = dataBufferLength; + msg.message = data; + retVal = db.hubInfo.contextHubModule->send_message(hubId, &msg); } else { - ALOGD("Could not find app instance %d", header[HEADER_FIELD_APP_INSTANCE]); + ALOGD("Could not find app instance %d on hubHandle %d, setAddress %d", + header[HEADER_FIELD_APP_INSTANCE], + header[HEADER_FIELD_HUB_HANDLE], + (int)setAddressSuccess); } } else { ALOGD("Malformed header len"); diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 30a59934e0a4..9a2e39c752de 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -348,6 +348,8 @@ <protected-broadcast android:name="android.app.action.DEVICE_OWNER_CHANGED" /> <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABILITY_CHANGED" /> + <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_AVAILABLE" /> + <protected-broadcast android:name="android.intent.action.MANAGED_PROFILE_UNAVAILABLE" /> <!-- Added in N --> <protected-broadcast android:name="android.intent.action.ANR" /> @@ -399,7 +401,6 @@ <protected-broadcast android:name="android.telephony.action.CARRIER_CONFIG_CHANGED" /> <protected-broadcast android:name="com.android.bluetooth.btservice.action.ALARM_WAKEUP" /> - <protected-broadcast android:name="com.android.ims.IMS_SERVICE_UP" /> <protected-broadcast android:name="com.android.server.action.NETWORK_STATS_POLL" /> <protected-broadcast android:name="com.android.server.action.NETWORK_STATS_UPDATED" /> <protected-broadcast android:name="com.android.server.NetworkTimeUpdateService.action.POLL" /> @@ -459,8 +460,15 @@ <protected-broadcast android:name="android.net.wifi.PASSPOINT_ICON_RECEIVED" /> <protected-broadcast android:name="com.android.server.notification.CountdownConditionProvider" /> - <!-- @hide UCE service Notification --> + <protected-broadcast android:name="com.android.ims.IMS_SERVICE_UP" /> + <protected-broadcast android:name="com.android.ims.IMS_INCOMING_CALL" /> <protected-broadcast android:name="com.android.ims.internal.uce.UCE_SERVICE_UP" /> + <protected-broadcast android:name="com.android.intent.action.IMS_FEATURE_CHANGED" /> + <protected-broadcast android:name="com.android.intent.action.IMS_CONFIG_CHANGED" /> + + <protected-broadcast android:name="com.android.internal.location.ALARM_WAKEUP" /> + <protected-broadcast android:name="com.android.internal.location.ALARM_TIMEOUT" /> + <protected-broadcast android:name="android.intent.action.GLOBAL_BUTTON" /> <!-- ====================================================================== --> <!-- RUNTIME PERMISSIONS --> @@ -2989,6 +2997,11 @@ <permission android:name="android.permission.BIND_VR_LISTENER_SERVICE" android:protectionLevel="signature" /> + <!-- Required to make calls to {@link android.service.vr.IVrManager}. + @hide --> + <permission android:name="android.permission.ACCESS_VR_MANAGER" + android:protectionLevel="signature" /> + <!-- Allows an application to whitelist tasks during lock task mode @hide <p>Not for use by third-party applications.</p> --> <permission android:name="android.permission.UPDATE_LOCK_TASK_PACKAGES" diff --git a/core/res/res/anim/slide_in_enter_micro.xml b/core/res/res/anim/slide_in_enter_micro.xml index 14a5290a66fe..c70874c626b8 100644 --- a/core/res/res/anim/slide_in_enter_micro.xml +++ b/core/res/res/anim/slide_in_enter_micro.xml @@ -19,7 +19,7 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:zAdjustment="top"> - <translate android:fromYDelta="5%p" android:toXDelta="0" + <translate android:fromYDelta="5%p" android:toYDelta="0" android:duration="417" android:interpolator="@android:interpolator/launch_task_micro_ydelta" /> <alpha android:fromAlpha="0.0" android:toAlpha="1.0" diff --git a/core/res/res/layout/notification_material_action_list.xml b/core/res/res/layout/notification_material_action_list.xml index 30b5a790c1ae..ac37c4a4a8e2 100644 --- a/core/res/res/layout/notification_material_action_list.xml +++ b/core/res/res/layout/notification_material_action_list.xml @@ -17,9 +17,7 @@ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/actions_container" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginStart="-16dp" - android:layout_marginEnd="-16dp"> + android:layout_height="wrap_content"> <LinearLayout android:id="@+id/actions" android:layout_width="match_parent" diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml index 0bbaa24a9ad4..992e88e22ad9 100644 --- a/core/res/res/layout/notification_template_header.xml +++ b/core/res/res/layout/notification_template_header.xml @@ -42,7 +42,7 @@ android:singleLine="true" /> <TextView - android:id="@+id/sub_text_divider" + android:id="@+id/header_text_divider" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.Material.Notification.Info" @@ -51,26 +51,7 @@ android:text="@string/notification_header_divider_symbol" android:visibility="gone"/> <TextView - android:id="@+id/header_sub_text" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textAppearance="@style/TextAppearance.Material.Notification.Info" - android:layout_marginStart="2dp" - android:layout_marginEnd="2dp" - android:visibility="gone" - android:singleLine="true"/> - <TextView - android:id="@+id/content_info_divider" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:textAppearance="@style/TextAppearance.Material.Notification.Info" - android:layout_marginStart="2dp" - android:layout_marginEnd="2dp" - android:text="@string/notification_header_divider_symbol" - android:singleLine="true" - android:visibility="gone"/> - <TextView - android:id="@+id/header_content_info" + android:id="@+id/header_text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textAppearance="@style/TextAppearance.Material.Notification.Info" diff --git a/core/res/res/layout/notification_template_material_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml index d53fb5f2e177..c54fa1895dfa 100644 --- a/core/res/res/layout/notification_template_material_big_base.xml +++ b/core/res/res/layout/notification_template_material_big_base.xml @@ -60,9 +60,5 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> - <include - layout="@layout/notification_material_action_list" - android:layout_width="match_parent" - android:layout_height="wrap_content" - /> + <include layout="@layout/notification_material_action_list" /> </LinearLayout> diff --git a/core/res/res/layout/notification_template_material_big_picture.xml b/core/res/res/layout/notification_template_material_big_picture.xml index 50aec6bc704a..d87b9d90e48f 100644 --- a/core/res/res/layout/notification_template_material_big_picture.xml +++ b/core/res/res/layout/notification_template_material_big_picture.xml @@ -27,8 +27,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="top" - android:paddingStart="@dimen/notification_content_margin_start" - android:paddingEnd="@dimen/notification_content_margin_end" android:layout_marginTop="@dimen/notification_content_margin_top" android:clipToPadding="false" android:orientation="vertical" @@ -37,6 +35,8 @@ android:id="@+id/notification_main_column" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_marginStart="@dimen/notification_content_margin_start" + android:layout_marginEnd="@dimen/notification_content_margin_end" android:orientation="vertical"> <include layout="@layout/notification_template_part_line1"/> <include layout="@layout/notification_template_progress"/> @@ -50,14 +50,15 @@ android:layout_weight="1" android:layout_marginTop="13dp" android:layout_marginBottom="16dp" + android:layout_marginStart="@dimen/notification_content_margin_start" + android:layout_marginEnd="@dimen/notification_content_margin_end" android:scaleType="centerCrop" /> + <ViewStub android:layout="@layout/notification_material_reply_text" android:id="@+id/notification_material_reply_container" android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="-16dp" - android:layout_marginEnd="-16dp" /> <include layout="@layout/notification_material_action_list" /> </LinearLayout> diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml index fdfefe10c3b5..3638b20d864a 100644 --- a/core/res/res/layout/notification_template_material_big_text.xml +++ b/core/res/res/layout/notification_template_material_big_text.xml @@ -22,38 +22,45 @@ android:tag="bigText" > <include layout="@layout/notification_template_header" /> + <LinearLayout - android:id="@+id/notification_main_column" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="top" - android:paddingStart="@dimen/notification_content_margin_start" - android:paddingEnd="@dimen/notification_content_margin_end" - android:layout_marginTop="@dimen/notification_content_margin_top" - android:clipToPadding="false" - android:minHeight="@dimen/notification_min_content_height" - android:orientation="vertical" - > - <include layout="@layout/notification_template_part_line1" /> - <include layout="@layout/notification_template_progress" /> - <com.android.internal.widget.ImageFloatingTextView android:id="@+id/big_text" android:layout_width="match_parent" - android:layout_height="0dp" - android:layout_marginTop="0.5dp" - android:paddingBottom="@dimen/notification_content_margin_bottom" - android:textAppearance="@style/TextAppearance.Material.Notification" - android:singleLine="false" - android:layout_weight="1" - android:gravity="top" - android:visibility="gone" - /> + android:layout_height="match_parent" + android:layout_gravity="top" + android:layout_marginTop="@dimen/notification_content_margin_top" + android:clipToPadding="false" + android:orientation="vertical"> + + <LinearLayout + android:id="@+id/notification_main_column" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="top" + android:paddingStart="@dimen/notification_content_margin_start" + android:paddingEnd="@dimen/notification_content_margin_end" + android:clipToPadding="false" + android:minHeight="@dimen/notification_min_content_height" + android:orientation="vertical" + > + <include layout="@layout/notification_template_part_line1" /> + <include layout="@layout/notification_template_progress" /> + <com.android.internal.widget.ImageFloatingTextView android:id="@+id/big_text" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_marginTop="0.5dp" + android:paddingBottom="@dimen/notification_content_margin_bottom" + android:textAppearance="@style/TextAppearance.Material.Notification" + android:singleLine="false" + android:layout_weight="1" + android:gravity="top" + android:visibility="gone" + /> + </LinearLayout> + <ViewStub android:layout="@layout/notification_material_reply_text" android:id="@+id/notification_material_reply_container" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginStart="-16dp" - android:layout_marginEnd="-16dp" - /> + android:layout_height="wrap_content" /> <include layout="@layout/notification_material_action_list" /> </LinearLayout> <include layout="@layout/notification_template_right_icon" /> diff --git a/core/res/res/layout/notification_template_material_inbox.xml b/core/res/res/layout/notification_template_material_inbox.xml index 86902db81426..ce9acda14f9f 100644 --- a/core/res/res/layout/notification_template_material_inbox.xml +++ b/core/res/res/layout/notification_template_material_inbox.xml @@ -23,87 +23,99 @@ > <include layout="@layout/notification_template_header" /> <LinearLayout - android:id="@+id/notification_main_column" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_gravity="top" - android:paddingStart="@dimen/notification_content_margin_start" - android:paddingEnd="@dimen/notification_content_margin_end" - android:layout_marginTop="@dimen/notification_content_margin_top" - android:minHeight="@dimen/notification_min_content_height" - android:clipToPadding="false" - android:orientation="vertical" - > - <include layout="@layout/notification_template_part_line1" android:layout_width="match_parent" - android:layout_height="wrap_content" /> - <include layout="@layout/notification_template_progress" - android:layout_width="match_parent" - android:layout_height="15dp" - android:layout_marginTop="4dp"/> - <TextView android:id="@+id/inbox_text0" - android:textAppearance="@style/TextAppearance.Material.Notification" - android:layout_width="match_parent" - android:layout_height="0dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_text1" - android:textAppearance="@style/TextAppearance.Material.Notification" - android:layout_width="match_parent" - android:layout_height="0dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_text2" - android:textAppearance="@style/TextAppearance.Material.Notification" - android:layout_width="match_parent" - android:layout_height="0dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_text3" - android:textAppearance="@style/TextAppearance.Material.Notification" - android:layout_width="match_parent" - android:layout_height="0dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_text4" - android:textAppearance="@style/TextAppearance.Material.Notification" - android:layout_width="match_parent" - android:layout_height="0dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_text5" - android:textAppearance="@style/TextAppearance.Material.Notification" - android:layout_width="match_parent" - android:layout_height="0dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> - <TextView android:id="@+id/inbox_text6" - android:textAppearance="@style/TextAppearance.Material.Notification" + android:layout_height="match_parent" + android:layout_gravity="top" + android:layout_marginTop="@dimen/notification_content_margin_top" + android:clipToPadding="false" + android:orientation="vertical"> + + <LinearLayout + android:id="@+id/notification_main_column" android:layout_width="match_parent" - android:layout_height="0dp" - android:singleLine="true" - android:ellipsize="end" - android:visibility="gone" - android:layout_weight="1" - /> + android:layout_height="wrap_content" + android:layout_gravity="top" + android:paddingStart="@dimen/notification_content_margin_start" + android:paddingEnd="@dimen/notification_content_margin_end" + android:minHeight="@dimen/notification_min_content_height" + android:clipToPadding="false" + android:orientation="vertical" + > + <include layout="@layout/notification_template_part_line1" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + <include layout="@layout/notification_template_progress" + android:layout_width="match_parent" + android:layout_height="15dp" + android:layout_marginTop="4dp"/> + <TextView android:id="@+id/inbox_text0" + android:textAppearance="@style/TextAppearance.Material.Notification" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_text1" + android:textAppearance="@style/TextAppearance.Material.Notification" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_text2" + android:textAppearance="@style/TextAppearance.Material.Notification" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_text3" + android:textAppearance="@style/TextAppearance.Material.Notification" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_text4" + android:textAppearance="@style/TextAppearance.Material.Notification" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_text5" + android:textAppearance="@style/TextAppearance.Material.Notification" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + <TextView android:id="@+id/inbox_text6" + android:textAppearance="@style/TextAppearance.Material.Notification" + android:layout_width="match_parent" + android:layout_height="0dp" + android:singleLine="true" + android:ellipsize="end" + android:visibility="gone" + android:layout_weight="1" + /> + </LinearLayout> + <ViewStub android:layout="@layout/notification_material_reply_text" + android:id="@+id/notification_material_reply_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> <include layout="@layout/notification_material_action_list" /> </LinearLayout> <include layout="@layout/notification_template_right_icon" /> diff --git a/core/res/res/layout/resolver_list.xml b/core/res/res/layout/resolver_list.xml index 4b8640c91f70..fe43e1c5d8b8 100644 --- a/core/res/res/layout/resolver_list.xml +++ b/core/res/res/layout/resolver_list.xml @@ -30,33 +30,37 @@ android:layout_height="wrap_content" android:layout_alwaysShow="true" android:elevation="8dp" - android:background="@color/white" > - <TextView android:id="@+id/profile_button" - android:layout_width="wrap_content" - android:layout_height="48dp" - android:layout_marginEnd="8dp" - android:paddingStart="8dp" - android:paddingEnd="8dp" - android:visibility="gone" - style="?attr/borderlessButtonStyle" - android:textAppearance="?attr/textAppearanceButton" - android:textColor="@color/material_deep_teal_500" - android:gravity="center_vertical" - android:layout_alignParentTop="true" - android:layout_alignParentRight="true" - android:singleLine="true"/> - <TextView android:id="@+id/title" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:minHeight="56dp" - android:textAppearance="?attr/textAppearanceMedium" - android:gravity="start|center_vertical" - android:paddingStart="?attr/dialogPreferredPadding" - android:paddingEnd="?attr/dialogPreferredPadding" - android:paddingTop="8dp" - android:layout_below="@id/profile_button" - android:layout_alignParentLeft="true" - android:paddingBottom="8dp" /> + android:background="@color/white"> + + <TextView + android:id="@+id/profile_button" + android:layout_width="wrap_content" + android:layout_height="48dp" + android:layout_marginEnd="8dp" + android:paddingStart="8dp" + android:paddingEnd="8dp" + android:visibility="gone" + style="?attr/borderlessButtonStyle" + android:textAppearance="?attr/textAppearanceButton" + android:textColor="@color/material_deep_teal_500" + android:gravity="center_vertical" + android:layout_alignParentTop="true" + android:layout_alignParentRight="true" + android:singleLine="true" /> + + <TextView + android:id="@+id/title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:minHeight="56dp" + android:textAppearance="?attr/textAppearanceMedium" + android:gravity="start|center_vertical" + android:paddingStart="?attr/dialogPreferredPadding" + android:paddingEnd="?attr/dialogPreferredPadding" + android:paddingTop="8dp" + android:layout_below="@id/profile_button" + android:layout_alignParentLeft="true" + android:paddingBottom="8dp" /> </RelativeLayout> <ListView @@ -68,21 +72,23 @@ android:background="@color/white" android:elevation="8dp" android:nestedScrollingEnabled="true" + android:scrollIndicators="top|bottom" android:divider="@null" /> - <TextView android:id="@+id/empty" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:layout_alwaysShow="true" - android:text="@string/noApplications" - android:padding="32dp" - android:gravity="center" - android:visibility="gone" /> + <TextView + android:id="@+id/empty" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_alwaysShow="true" + android:text="@string/noApplications" + android:padding="32dp" + android:gravity="center" + android:visibility="gone" /> <LinearLayout android:id="@+id/button_bar" android:visibility="gone" - style="?android:attr/buttonBarStyle" + style="?attr/buttonBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_ignoreOffset="true" @@ -97,26 +103,30 @@ android:paddingStart="12dp" android:paddingEnd="12dp" android:elevation="8dp"> - <Button android:id="@+id/button_once" - android:layout_width="wrap_content" - android:layout_gravity="start" - android:maxLines="2" - style="?android:attr/buttonBarNegativeButtonStyle" - android:minHeight="@dimen/alert_dialog_button_bar_height" - android:layout_height="wrap_content" - android:enabled="false" - android:text="@string/activity_resolver_use_once" - android:onClick="onButtonClick" /> - <Button android:id="@+id/button_always" - android:layout_width="wrap_content" - android:layout_gravity="end" - android:maxLines="2" - android:minHeight="@dimen/alert_dialog_button_bar_height" - style="?android:attr/buttonBarPositiveButtonStyle" - android:layout_height="wrap_content" - android:enabled="false" - android:text="@string/activity_resolver_use_always" - android:onClick="onButtonClick" /> + + <Button + android:id="@+id/button_once" + android:layout_width="wrap_content" + android:layout_gravity="start" + android:maxLines="2" + style="?attr/buttonBarNegativeButtonStyle" + android:minHeight="@dimen/alert_dialog_button_bar_height" + android:layout_height="wrap_content" + android:enabled="false" + android:text="@string/activity_resolver_use_once" + android:onClick="onButtonClick" /> + + <Button + android:id="@+id/button_always" + android:layout_width="wrap_content" + android:layout_gravity="end" + android:maxLines="2" + android:minHeight="@dimen/alert_dialog_button_bar_height" + style="?attr/buttonBarPositiveButtonStyle" + android:layout_height="wrap_content" + android:enabled="false" + android:text="@string/activity_resolver_use_always" + android:onClick="onButtonClick" /> </LinearLayout> </com.android.internal.widget.ResolverDrawerLayout> diff --git a/core/res/res/layout/resolver_list_with_default.xml b/core/res/res/layout/resolver_list_with_default.xml index 31361e5f9c48..ed7ef5edd817 100644 --- a/core/res/res/layout/resolver_list_with_default.xml +++ b/core/res/res/layout/resolver_list_with_default.xml @@ -22,8 +22,7 @@ android:layout_height="match_parent" android:maxWidth="@dimen/resolver_max_width" android:maxCollapsedHeight="144dp" - android:id="@id/contentPanel" - > + android:id="@id/contentPanel"> <LinearLayout android:layout_width="match_parent" @@ -31,66 +30,75 @@ android:layout_alwaysShow="true" android:orientation="vertical" android:background="@color/white" - android:elevation="8dp" > + android:elevation="8dp"> <LinearLayout android:layout_width="match_parent" android:layout_height="64dp" - android:orientation="horizontal" > + android:orientation="horizontal"> - <ImageView android:id="@+id/icon" - android:layout_width="24dp" - android:layout_height="24dp" - android:layout_gravity="start|top" - android:layout_marginStart="16dp" - android:layout_marginEnd="16dp" - android:layout_marginTop="20dp" - android:scaleType="fitCenter" /> - <TextView android:id="@+id/title" - android:layout_width="0dp" - android:layout_weight="1" - android:layout_height="?android:attr/listPreferredItemHeight" - android:layout_marginStart="16dp" - android:textAppearance="?android:attr/textAppearanceMedium" - android:gravity="start|center_vertical" - android:paddingEnd="16dp" /> - <LinearLayout android:id="@+id/profile_button" - android:layout_width="wrap_content" - android:layout_height="48dp" - android:layout_marginTop="4dp" - android:layout_marginEnd="4dp" - android:paddingStart="8dp" - android:paddingEnd="8dp" - android:paddingTop="4dp" - android:paddingBottom="4dp" - android:focusable="true" - android:visibility="gone" - style="?attr/borderlessButtonStyle"> - <ImageView android:id="@+id/icon" - android:layout_width="24dp" - android:layout_height="24dp" - android:layout_gravity="start|center_vertical" - android:layout_marginEnd="?attr/listPreferredItemPaddingEnd" - android:layout_marginTop="12dp" - android:layout_marginBottom="12dp" - android:scaleType="fitCenter" /> - <TextView android:id="@id/text1" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_gravity="start|center_vertical" - android:layout_marginEnd="?attr/listPreferredItemPaddingEnd" - android:textAppearance="?attr/textAppearanceButton" - android:textColor="?attr/textColorPrimary" - android:minLines="1" - android:maxLines="1" - android:ellipsize="marquee" /> + <ImageView + android:id="@+id/icon" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="start|top" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:layout_marginTop="20dp" + android:scaleType="fitCenter" /> + + <TextView + android:id="@+id/title" + android:layout_width="0dp" + android:layout_weight="1" + android:layout_height="?attr/listPreferredItemHeight" + android:layout_marginStart="16dp" + android:textAppearance="?attr/textAppearanceMedium" + android:gravity="start|center_vertical" + android:paddingEnd="16dp" /> + + <LinearLayout + android:id="@+id/profile_button" + android:layout_width="wrap_content" + android:layout_height="48dp" + android:layout_marginTop="4dp" + android:layout_marginEnd="4dp" + android:paddingStart="8dp" + android:paddingEnd="8dp" + android:paddingTop="4dp" + android:paddingBottom="4dp" + android:focusable="true" + android:visibility="gone" + style="?attr/borderlessButtonStyle"> + + <ImageView + android:id="@+id/icon" + android:layout_width="24dp" + android:layout_height="24dp" + android:layout_gravity="start|center_vertical" + android:layout_marginEnd="?attr/listPreferredItemPaddingEnd" + android:layout_marginTop="12dp" + android:layout_marginBottom="12dp" + android:scaleType="fitCenter" /> + + <TextView + android:id="@id/text1" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="start|center_vertical" + android:layout_marginEnd="?attr/listPreferredItemPaddingEnd" + android:textAppearance="?attr/textAppearanceButton" + android:textColor="?attr/textColorPrimary" + android:minLines="1" + android:maxLines="1" + android:ellipsize="marquee" /> </LinearLayout> </LinearLayout> <LinearLayout android:id="@+id/button_bar" android:visibility="gone" - style="?android:attr/buttonBarStyle" + style="?attr/buttonBarStyle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alwaysShow="true" @@ -104,30 +112,36 @@ android:paddingEnd="12dp" android:background="@color/white" android:elevation="8dp"> - <Button android:id="@+id/button_once" - android:layout_width="wrap_content" - android:layout_gravity="start" - android:maxLines="2" - style="?android:attr/buttonBarNegativeButtonStyle" - android:minHeight="@dimen/alert_dialog_button_bar_height" - android:layout_height="wrap_content" - android:enabled="false" - android:text="@string/activity_resolver_use_once" - android:onClick="onButtonClick" /> - <Button android:id="@+id/button_always" - android:layout_width="wrap_content" - android:layout_gravity="end" - android:maxLines="2" - android:minHeight="@dimen/alert_dialog_button_bar_height" - style="?android:attr/buttonBarPositiveButtonStyle" - android:layout_height="wrap_content" - android:enabled="false" - android:text="@string/activity_resolver_use_always" - android:onClick="onButtonClick" /> + + <Button + android:id="@+id/button_once" + android:layout_width="wrap_content" + android:layout_gravity="start" + android:maxLines="2" + style="?attr/buttonBarNegativeButtonStyle" + android:minHeight="@dimen/alert_dialog_button_bar_height" + android:layout_height="wrap_content" + android:enabled="false" + android:text="@string/activity_resolver_use_once" + android:onClick="onButtonClick" /> + + <Button + android:id="@+id/button_always" + android:layout_width="wrap_content" + android:layout_gravity="end" + android:maxLines="2" + android:minHeight="@dimen/alert_dialog_button_bar_height" + style="?attr/buttonBarPositiveButtonStyle" + android:layout_height="wrap_content" + android:enabled="false" + android:text="@string/activity_resolver_use_always" + android:onClick="onButtonClick" /> </LinearLayout> - <View android:layout_width="match_parent" - android:layout_height="1dp" - android:background="?android:attr/dividerVertical" /> + + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="?attr/dividerVertical" /> </LinearLayout> <ListView @@ -140,6 +154,6 @@ android:elevation="8dp" android:nestedScrollingEnabled="true" android:divider="@null" - /> + android:scrollIndicators="top|bottom" /> </com.android.internal.widget.ResolverDrawerLayout> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 7ca52a3a7a2b..2a16a1ec5d5b 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Inhoud word versteek volgens beleid"</string> <string name="safeMode" msgid="2788228061547930246">"Veiligmodus"</string> <string name="android_system_label" msgid="6577375335728551336">"Android-stelsel"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Skakel oor na persoonlik"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Skakel oor na werk"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakte"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"in te gaan by jou kontakte"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Ligging"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DEEL"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"WEIER"</string> <string name="select_input_method" msgid="8547250819326693584">"Verander sleutelbord"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Ander sleutelborde"</string> <string name="show_ime" msgid="2506087537466597099">"Hou dit op die skerm terwyl fisieke sleutelbord aktief is"</string> <string name="hardware" msgid="194658061510127999">"Wys virtuele sleutelbord"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Stel fisieke sleutelbord op"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tik om taal en uitleg te kies"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidate"</u></string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 200ec3041e88..0668c35f0522 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ይዘቶች በመመሪያ ተደብቀዋል"</string> <string name="safeMode" msgid="2788228061547930246">"የሚያስተማምን ሁነታ"</string> <string name="android_system_label" msgid="6577375335728551336">"Android ስርዓት"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"ወደ የግል ቀይር"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"ወደ ሥራ ቀይር"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"ዕውቂያዎች"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"የእርስዎ እውቂያዎች ላይ ይድረሱባቸው"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"መገኛ አካባቢ"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"አጋራ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"አትቀበል"</string> <string name="select_input_method" msgid="8547250819326693584">"ቁልፍ ሰሌዳ ይቀይሩ"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"ሌሎች ቁልፍ ሰሌዳዎች"</string> <string name="show_ime" msgid="2506087537466597099">"አካላዊ የቁልፍ ሰሌዳ ገቢር ሆኖ ሳለ በማያ ገጽ ላይ አቆየው"</string> <string name="hardware" msgid="194658061510127999">"ምናባዊ የቁልፍ ሰሌዳን አሳይ"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"አካላዊ ቁልፍ ሰሌዳን ያዋቅሩ"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ቋንቋ እና አቀማመጥን ለመምረጥ መታ ያድርጉ"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"ዕጩዎች"</u></string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index d8127878d447..6a7c76cc545f 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -241,10 +241,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"تم إخفاء المحتويات بواسطة السياسة"</string> <string name="safeMode" msgid="2788228061547930246">"الوضع الآمن"</string> <string name="android_system_label" msgid="6577375335728551336">"نظام Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"التبديل إلى الشخصي"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"التبديل إلى العمل"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"جهات الاتصال"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"الوصول إلى جهات اتصالك"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"الموقع"</string> @@ -1095,13 +1093,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"مشاركة"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"رفض"</string> <string name="select_input_method" msgid="8547250819326693584">"تغيير لوحة المفاتيح"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"لوحات المفاتيح الأخرى"</string> <string name="show_ime" msgid="2506087537466597099">"استمرار عرضها على الشاشة أثناء نشاط لوحة المفاتيح الفعلية"</string> <string name="hardware" msgid="194658061510127999">"إظهار لوحة المفاتيح الظاهرية"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"تهيئة لوحة المفاتيح الفعلية"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"انقر لاختيار لغة وتنسيق"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"العناصر المرشحة"</u></string> diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml index 547995846e9a..e76ce87848d6 100644 --- a/core/res/res/values-az-rAZ/strings.xml +++ b/core/res/res/values-az-rAZ/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Məzmun siyasət tərəfindən gizlədilib"</string> <string name="safeMode" msgid="2788228061547930246">"Təhlükəsiz rejim"</string> <string name="android_system_label" msgid="6577375335728551336">"Android sistemi"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Şəxsi profilə keçirin"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"İş profilinə keçirin"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktlar"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"kontaktlarınıza daxil olun"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Yer"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PAYLAŞIN"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RƏDD EDİN"</string> <string name="select_input_method" msgid="8547250819326693584">"Klaviaturanı dəyişin"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Digər klaviaturalar"</string> <string name="show_ime" msgid="2506087537466597099">"Fiziki klaviatura aktiv olduğu halda ekranda saxlayın"</string> <string name="hardware" msgid="194658061510127999">"Virtual klaviaturanı göstərin"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Fiziki klaviaturanı konfiqurasiya edin"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dil və tərtibatı seçmək üçün tıklayın"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCÇDEƏFGĞHXIİJKQLMNOÖPRSŞTUÜVYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCÇDEƏFGĞHİIJKLMNOÖPQRSŞTUÜVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"namizədlər"</u></string> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 9f9b5b8816b0..9231e9a8cc83 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -235,10 +235,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sadržaj je sakriven smernicama"</string> <string name="safeMode" msgid="2788228061547930246">"Bezbedni režim"</string> <string name="android_system_label" msgid="6577375335728551336">"Android sistem"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Pređi na Lični profil"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Pređi na profil za Work"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakti"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"pristupi kontaktima"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string> @@ -1071,13 +1069,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DELI"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBIJ"</string> <string name="select_input_method" msgid="8547250819326693584">"Promenite tastaturu"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Druge tastature"</string> <string name="show_ime" msgid="2506087537466597099">"Zadrži ga na ekranu dok je fizička tastatura aktivna"</string> <string name="hardware" msgid="194658061510127999">"Prikaži virtuelnu tastaturu"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfigurišite fizičku tastaturu"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dodirnite da biste izabrali jezik i raspored"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string> diff --git a/core/res/res/values-be-rBY/strings.xml b/core/res/res/values-be-rBY/strings.xml index 6848fda5a29f..8a23529da4ef 100644 --- a/core/res/res/values-be-rBY/strings.xml +++ b/core/res/res/values-be-rBY/strings.xml @@ -237,10 +237,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Змесціва, схаванае ў адпаведнасці з палітыкай"</string> <string name="safeMode" msgid="2788228061547930246">"Бяспечны рэжым"</string> <string name="android_system_label" msgid="6577375335728551336">"Сістэма Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Пераключыцца на асабісты"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Пераключыцца на працоўны"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Кантакты"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"атрымліваць доступ да вашых кантактаў"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Месцазнаходжанне"</string> @@ -1063,8 +1061,8 @@ <string name="no_permissions" msgid="7283357728219338112">"Дазволу не патрабуецца"</string> <string name="perm_costs_money" msgid="4902470324142151116">"за гэта можа спаганяцца плата"</string> <string name="dlg_ok" msgid="7376953167039865701">"ОК"</string> - <string name="usb_charging_notification_title" msgid="6895185153353640787">"Зарадка гэтай прылады па USB"</string> - <string name="usb_supplying_notification_title" msgid="5310642257296510271">"Падача сілкавання падключанай прыладзе па USB"</string> + <string name="usb_charging_notification_title" msgid="6895185153353640787">"Па USB зараджаецца гэта прыладу"</string> + <string name="usb_supplying_notification_title" msgid="5310642257296510271">"Па USB падачецца сілкаванне падключанай прыладзе"</string> <string name="usb_mtp_notification_title" msgid="8396264943589760855">"USB для перадачы файлаў"</string> <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB для перадачы фота"</string> <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB для MIDI"</string> @@ -1079,13 +1077,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"АБАГУЛІЦЬ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"АДХІЛІЦЬ"</string> <string name="select_input_method" msgid="8547250819326693584">"Змяніць клавіятуру"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Іншыя праграмныя клавіятуры"</string> <string name="show_ime" msgid="2506087537466597099">"Захоўваць яе на экране ў той час, калі фізічная клавіятура актыўная"</string> <string name="hardware" msgid="194658061510127999">"Паказаць віртуальную клавіятуру"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Наладжванне фізічнай клавіятуры"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Дакраніцеся, каб выбраць мову і раскладку"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШ\'ЫЬЭЮЯ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"кандыдат."</u></string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 4f8f80ce6cfe..76c70024a5a8 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Съдържанието е скрито чрез правило"</string> <string name="safeMode" msgid="2788228061547930246">"Безопасен режим"</string> <string name="android_system_label" msgid="6577375335728551336">"Системно от Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Превключване към личния потребителски профил"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Превключване към служебния пoтребителски профил"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"има достъп до контактите ви"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Местоположение"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"СПОДЕЛЯНЕ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ОТХВЪРЛЯНЕ"</string> <string name="select_input_method" msgid="8547250819326693584">"Промяна на клавиатурата"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Други клавиатури"</string> <string name="show_ime" msgid="2506087537466597099">"Показване на екрана, докато физическата клавиатура е активна"</string> <string name="hardware" msgid="194658061510127999">"Показване на вирт. клавиатура"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Конфигуриране на физическата клавиатура"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Докоснете, за да изберете език и подредба"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string> diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml index 13284cf33d59..620e532de355 100644 --- a/core/res/res/values-bn-rBD/strings.xml +++ b/core/res/res/values-bn-rBD/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"নীতির কারণে সামগ্রী লুকানো আছে"</string> <string name="safeMode" msgid="2788228061547930246">"নিরাপদ মোড"</string> <string name="android_system_label" msgid="6577375335728551336">"Android সিস্টেম"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"ব্যক্তিগততে পাল্টান"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"কর্মস্থানে পাল্টান"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"পরিচিতি"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"আপনার পরিচিতিগুলিতে অ্যাক্সেস করুন"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"অবস্থান"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"শেয়ার করুন"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"অস্বীকার করুন"</string> <string name="select_input_method" msgid="8547250819326693584">"কীবোর্ড পরিবর্তন করুন"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"অন্যান্য কীবোর্ড"</string> <string name="show_ime" msgid="2506087537466597099">"ফিজিক্যাল কীবোর্ড সক্রিয় থাকার সময় এটিকে স্ক্রীনে রাখুন"</string> <string name="hardware" msgid="194658061510127999">"ভার্চুয়াল কীবোর্ড দেখান"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"ফিজিক্যাল কীবোর্ড কনফিগার করুন"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ভাষা এবং লেআউট নির্বাচন করুন আলতো চাপ দিন"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"প্রার্থীরা"</u></string> diff --git a/core/res/res/values-bs-rBA/strings.xml b/core/res/res/values-bs-rBA/strings.xml index bbc72d581e53..82639af1e131 100644 --- a/core/res/res/values-bs-rBA/strings.xml +++ b/core/res/res/values-bs-rBA/strings.xml @@ -235,10 +235,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sadržaj skriven u skladu sa pravilima"</string> <string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string> <string name="android_system_label" msgid="6577375335728551336">"Android sistem"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Prebacite se na lični"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Prebacite se na radni"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakti"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"pristupa vašim kontaktima"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string> @@ -1071,13 +1069,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PODIJELI"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBACI"</string> <string name="select_input_method" msgid="8547250819326693584">"Promijeni tastaturu"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Ostale tastature"</string> <string name="show_ime" msgid="2506087537466597099">"Prikaži na ekranu dok je fizička tastatura aktivna"</string> <string name="hardware" msgid="194658061510127999">"Prikaži virtualnu tastaturu"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfiguriraj fizičku tastaturu"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dodirnite za odabir jezika i rasporeda"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 07ba68274eca..6fcadfa26f29 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contingut amagat de conformitat amb la política"</string> <string name="safeMode" msgid="2788228061547930246">"Mode segur"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Canvia al perfil personal"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Canvia al perfil professional"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactes"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"accedir als contactes"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Ubicació"</string> @@ -1048,7 +1046,7 @@ <string name="perm_costs_money" msgid="4902470324142151116">"pot ser que comporti càrrecs"</string> <string name="dlg_ok" msgid="7376953167039865701">"D\'acord"</string> <string name="usb_charging_notification_title" msgid="6895185153353640787">"L\'USB està carregant el dispositiu"</string> - <string name="usb_supplying_notification_title" msgid="5310642257296510271">"L\'USB subministra energia al dispositiu inserit"</string> + <string name="usb_supplying_notification_title" msgid="5310642257296510271">"L\'USB subministra energia al dispositiu connectat"</string> <string name="usb_mtp_notification_title" msgid="8396264943589760855">"USB per transferir fitxers"</string> <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB per transferir fotos"</string> <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB per a MIDI"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTEIX"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REBUTJA"</string> <string name="select_input_method" msgid="8547250819326693584">"Canvia el teclat"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Altres teclats"</string> <string name="show_ime" msgid="2506087537466597099">"El deixa a la pantalla mentre el teclat físic està actiu"</string> <string name="hardware" msgid="194658061510127999">"Mostra el teclat virtual"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configura el teclat físic"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toca per seleccionar l\'idioma i el disseny"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 0a9aa2be2a8b..127d38bf9e42 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -237,10 +237,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Obsah skrytý zásadami"</string> <string name="safeMode" msgid="2788228061547930246">"Nouzový režim"</string> <string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Přepnout na osobní profil"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Přepnout na pracovní profil"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakty"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"přístup ke kontaktům"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Poloha"</string> @@ -1079,13 +1077,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"SDÍLET"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODMÍTNOUT"</string> <string name="select_input_method" msgid="8547250819326693584">"Změna klávesnice"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Další klávesnice"</string> <string name="show_ime" msgid="2506087537466597099">"Ponechat na obrazovce, když je aktivní fyzická klávesnice"</string> <string name="hardware" msgid="194658061510127999">"Zobrazit virtuální klávesnici"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfigurace fyzické klávesnice"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Klepnutím vyberte jazyk a rozvržení"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index dd2d223bfcb5..407f1f8b834e 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Indholdet er skjult af politikken"</string> <string name="safeMode" msgid="2788228061547930246">"Sikker tilstand"</string> <string name="android_system_label" msgid="6577375335728551336">"Android-system"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Skift til Tilpasset"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Skift til arbejde"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktpersoner"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"have adgang til dine kontaktpersoner"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Placering"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DEL"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"AFVIS"</string> <string name="select_input_method" msgid="8547250819326693584">"Skift tastatur"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Andre tastaturer"</string> <string name="show_ime" msgid="2506087537466597099">"Behold den på skærmen, mens det fysiske tastatur er aktivt"</string> <string name="hardware" msgid="194658061510127999">"Vis virtuelt tastatur"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfigurer fysisk tastatur"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tryk for at vælge sprog og layout"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index b32bea6b8e13..e539a28354dd 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Inhalte aufgrund der Richtlinien ausgeblendet"</string> <string name="safeMode" msgid="2788228061547930246">"Abgesicherter Modus"</string> <string name="android_system_label" msgid="6577375335728551336">"Android-System"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Zu \"Privat\" wechseln"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Zu \"Arbeit\" wechseln"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakte"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"auf Kontakte zuzugreifen"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Standort"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"TEILEN"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ABLEHNEN"</string> <string name="select_input_method" msgid="8547250819326693584">"Tastatur ändern"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Weitere Tastaturen"</string> <string name="show_ime" msgid="2506087537466597099">"Auf dem Display einblenden, wenn die physische Tastatur aktiv ist"</string> <string name="hardware" msgid="194658061510127999">"Virtuelle Tastatur einblenden"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Physische Tastatur konfigurieren"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Zum Auswählen von Sprache und Layout tippen"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"Kandidaten"</u></string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 71351a353c0a..1e891d039231 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Το περιεχόμενο είναι κρυφό βάσει πολιτικής"</string> <string name="safeMode" msgid="2788228061547930246">"Ασφαλής λειτουργία"</string> <string name="android_system_label" msgid="6577375335728551336">"Σύστημα Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Μετάβαση σε προσωπικό προφίλ"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Μετάβαση σε προφίλ εργασίας"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Επαφές"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"πρόσβαση στις επαφές σας"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Τοποθεσία"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ΚΟΙΝΟΠΟΙΗΣΗ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ΑΠΟΡΡΙΨΗ"</string> <string name="select_input_method" msgid="8547250819326693584">"Αλλαγή πληκτρολογίου"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Άλλα πληκτρολόγια"</string> <string name="show_ime" msgid="2506087537466597099">"Να παραμένει στην οθόνη όταν είναι ενεργό το φυσικό πληκτρολόγιο"</string> <string name="hardware" msgid="194658061510127999">"Εμφάνιση εικονικού πληκτρολ."</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Διαμόρφωση φυσικού πληκτρολογίου"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Πατήστε για να επιλέξετε γλώσσα και διάταξη"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"υποψήφιοι"</u></string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index c222397d00ce..b94222c7efca 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contents hidden by policy"</string> <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string> <string name="android_system_label" msgid="6577375335728551336">"Android system"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Switch to Personal"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Switch to Work"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"access your contacts"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"SHARE"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"DECLINE"</string> <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Other keyboards"</string> <string name="show_ime" msgid="2506087537466597099">"Keep it on screen while physical keyboard is active"</string> <string name="hardware" msgid="194658061510127999">"Show virtual keyboard"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configure physical keyboard"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tap to select language and layout"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidates"</u></string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index c222397d00ce..b94222c7efca 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contents hidden by policy"</string> <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string> <string name="android_system_label" msgid="6577375335728551336">"Android system"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Switch to Personal"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Switch to Work"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"access your contacts"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"SHARE"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"DECLINE"</string> <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Other keyboards"</string> <string name="show_ime" msgid="2506087537466597099">"Keep it on screen while physical keyboard is active"</string> <string name="hardware" msgid="194658061510127999">"Show virtual keyboard"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configure physical keyboard"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tap to select language and layout"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidates"</u></string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index c222397d00ce..b94222c7efca 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contents hidden by policy"</string> <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string> <string name="android_system_label" msgid="6577375335728551336">"Android system"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Switch to Personal"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Switch to Work"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"access your contacts"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Location"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"SHARE"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"DECLINE"</string> <string name="select_input_method" msgid="8547250819326693584">"Change keyboard"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Other keyboards"</string> <string name="show_ime" msgid="2506087537466597099">"Keep it on screen while physical keyboard is active"</string> <string name="hardware" msgid="194658061510127999">"Show virtual keyboard"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configure physical keyboard"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tap to select language and layout"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidates"</u></string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index afd5f6ccfdea..0bfb9e0b5321 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenido oculto debido a la política"</string> <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Cambiar al perfil personal"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Cambiar al perfil de trabajo"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acceder a los contactos"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Ubicación"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTIR"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RECHAZAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Cambiar el teclado"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Otros teclados"</string> <string name="show_ime" msgid="2506087537466597099">"Mantener en la pantalla cuando el teclado físico está activo"</string> <string name="hardware" msgid="194658061510127999">"Mostrar teclado virtual"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configura el teclado físico"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Presiona para seleccionar el idioma y el diseño"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index 3d5682c63aef..99202abdd5cf 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenidos ocultos por política"</string> <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Cambiar a perfil personal"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Cambiar a perfil de trabajo"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acceder a tus contactos"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Ubicación"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTIR"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RECHAZAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Otros teclados"</string> <string name="show_ime" msgid="2506087537466597099">"Debe seguir en pantalla mientras el teclado físico esté activo"</string> <string name="hardware" msgid="194658061510127999">"Mostrar teclado virtual"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configura el teclado físico"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toca para seleccionar el idioma y el diseño"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml index 7b2e108aff43..b1cc97170674 100644 --- a/core/res/res/values-et-rEE/strings.xml +++ b/core/res/res/values-et-rEE/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sisu on eeskirjadega peidetud"</string> <string name="safeMode" msgid="2788228061547930246">"Turvarežiim"</string> <string name="android_system_label" msgid="6577375335728551336">"Android-süsteem"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Lülita isiklikule profiilile"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Lülita tööprofiilile"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktid"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"juurdepääs kontaktidele"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Asukoht"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"JAGA"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"KEELDU"</string> <string name="select_input_method" msgid="8547250819326693584">"Klaviatuuri muutmine"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Muud klaviatuurid"</string> <string name="show_ime" msgid="2506087537466597099">"Hoia seda ekraanil, kui füüsiline klaviatuur on aktiivne"</string> <string name="hardware" msgid="194658061510127999">"Virtuaalse klaviatuuri kuvam."</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Füüsilise klaviatuuri seadistamine"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Puudutage keele ja paigutuse valimiseks"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaadid"</u></string> diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml index 5bcaed12646f..ea666d975b05 100644 --- a/core/res/res/values-eu-rES/strings.xml +++ b/core/res/res/values-eu-rES/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Gidalerro batzuk ezkutatu dira, gidalerroei jarraiki"</string> <string name="safeMode" msgid="2788228061547930246">"Modu segurua"</string> <string name="android_system_label" msgid="6577375335728551336">"Android sistema"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Aldatu profil pertsonalera"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Aldatu laneko profilera"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktuak"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"kontaktuak atzitzeko"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Kokapena"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PARTEKATU"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"BAZTERTU"</string> <string name="select_input_method" msgid="8547250819326693584">"Aldatu teklatua"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Beste teklatu batzuk"</string> <string name="show_ime" msgid="2506087537466597099">"Erakutsi pantailan teklatu fisikoa aktibo dagoen bitartean"</string> <string name="hardware" msgid="194658061510127999">"Erakutsi teklatu birtuala"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfiguratu teklatu fisikoa"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Hizkuntza eta diseinua hautatzeko, sakatu hau"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"hautagaiak"</u></string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 7688af44979e..df9d78fe7a74 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"محتوا بر اساس خطمشی پنهان شده است"</string> <string name="safeMode" msgid="2788228061547930246">"حالت ایمن"</string> <string name="android_system_label" msgid="6577375335728551336">"سیستم Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"رفتن به نمایه شخصی"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"رفتن به نمایه کاری"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"مخاطبین"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"دسترسی به مخاطبین شما"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"مکان"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"اشتراکگذاری"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"نپذیرفتن"</string> <string name="select_input_method" msgid="8547250819326693584">"تغییر صفحهکلید"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"صفحهکلیدهای دیگر"</string> <string name="show_ime" msgid="2506087537466597099">"وقتی صفحهکلید فیزیکی فعال است این ویرایشگر را روی صفحه نگهمیدارد"</string> <string name="hardware" msgid="194658061510127999">"نمایش صفحهکلید مجازی"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"پیکربندی صفحهکلید فیزیکی"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"برای انتخاب زبان و چیدمان ضربه بزنید"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"داوطلبین"</u></string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 9105842a3acd..c86996181e08 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sisältö on piilotettu käytännön perusteella."</string> <string name="safeMode" msgid="2788228061547930246">"Suojattu tila"</string> <string name="android_system_label" msgid="6577375335728551336">"Android-järjestelmä"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Siirry henkilökohtaiseen profiiliin"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Siirry työprofiiliin"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktit"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"käyttää yhteystietoja"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Sijainti"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"JAA"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"HYLKÄÄ"</string> <string name="select_input_method" msgid="8547250819326693584">"Vaihda näppäimistö"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Muut näppäimistöt"</string> <string name="show_ime" msgid="2506087537466597099">"Pidä näytöllä, kun fyysinen näppäimistö on aktiivinen."</string> <string name="hardware" msgid="194658061510127999">"Näytä virtuaalinen näppäimistö"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Määritä fyysinen näppäimistö"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Valitse kieli ja asettelu koskettamalla."</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaatit"</u></string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 222501f1fc92..efc8af32e4a1 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenu masqué conformément aux politiques"</string> <string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string> <string name="android_system_label" msgid="6577375335728551336">"Système Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Passer au profil personnel"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Passer au profil professionnel"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"accéder à vos contacts"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Localisation"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PARTAGER"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REFUSER"</string> <string name="select_input_method" msgid="8547250819326693584">"Changer de clavier"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Autres claviers"</string> <string name="show_ime" msgid="2506087537466597099">"Afficher lorsque le clavier physique est activé"</string> <string name="hardware" msgid="194658061510127999">"Afficher le clavier virtuel"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configurer le clavier physique"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Touchez pour sélectionner la langue et la configuration du clavier"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 1b8e03ca556f..4e83fa9619fb 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenu masqué conformément aux règles"</string> <string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string> <string name="android_system_label" msgid="6577375335728551336">"Système Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Passer au profil personnel"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Passer au profil professionnel"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"accéder à vos contacts"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Position"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PARTAGER"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REFUSER"</string> <string name="select_input_method" msgid="8547250819326693584">"Changer de clavier"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Autres claviers"</string> <string name="show_ime" msgid="2506087537466597099">"Afficher lorsque le clavier physique est activé"</string> <string name="hardware" msgid="194658061510127999">"Afficher le clavier virtuel"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configurer le clavier physique"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Appuyer pour sélectionner la langue et la disposition"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidats"</u></string> diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml index ae5cc617cb13..2fa6087fa6d2 100644 --- a/core/res/res/values-gl-rES/strings.xml +++ b/core/res/res/values-gl-rES/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Ocultouse contido por causa da política"</string> <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Cambiar ao perfil persoal"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Cambiar ao perfil de traballo"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acceder aos teus contactos"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Localización"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTIR"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ANULAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Outros teclados"</string> <string name="show_ime" msgid="2506087537466597099">"Manteno na pantalla mentres o teclado físico estea activo"</string> <string name="hardware" msgid="194658061510127999">"Mostrar teclado virtual"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configura o teclado físico"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toca para seleccionar o idioma e o deseño"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml index 04876126b575..0b9f4ad8dda9 100644 --- a/core/res/res/values-gu-rIN/strings.xml +++ b/core/res/res/values-gu-rIN/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"નીતિ દ્વારા સામગ્રી છુપાવાઈ"</string> <string name="safeMode" msgid="2788228061547930246">"સુરક્ષિત મોડ"</string> <string name="android_system_label" msgid="6577375335728551336">"Android સિસ્ટમ"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"વ્યક્તિગત પર સ્વિચ કરો"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"કાર્ય પર સ્વિચ કરો"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"સંપર્કો"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"તમારા સંપર્કોને ઍક્સેસ કરો"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"સ્થાન"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"શેર કરો"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"નકારો"</string> <string name="select_input_method" msgid="8547250819326693584">"કીબોર્ડ બદલો"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"અન્ય કીબોર્ડ્સ"</string> <string name="show_ime" msgid="2506087537466597099">"જ્યારે ભૌતિક કીબોર્ડ સક્રિય હોય ત્યારે તેને સ્ક્રીન પર રાખો"</string> <string name="hardware" msgid="194658061510127999">"વર્ચ્યુઅલ કીબોર્ડ બતાવો"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"ભૌતિક કીબોર્ડ ગોઠવો"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ભાષા અને લેઆઉટ પસંદ કરવા માટે ટૅપ કરો"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"ઉમેદવારો"</u></string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index f007f89f9fa4..474e81e66670 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"सामग्री पॉलिसी के द्वारा छिपी हुई है"</string> <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string> <string name="android_system_label" msgid="6577375335728551336">"Android सिस्टम"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"व्यक्तिगत प्रोफ़ाइल में स्विच करें"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"कार्य प्रोफ़ाइल में स्विच करें"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"संपर्क"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"अपने संपर्कों को ऐक्सेस करें"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"साझा करें"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"अस्वीकार करें"</string> <string name="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदलें"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"अन्य कीबोर्ड"</string> <string name="show_ime" msgid="2506087537466597099">"भौतिक कीबोर्ड के सक्रिय होने के दौरान इसे स्क्रीन पर बनाए रखें"</string> <string name="hardware" msgid="194658061510127999">"वर्चुअल कीबोर्ड दिखाएं"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"भौतिक कीबोर्ड कॉन्फ़िगर करें"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"भाषा और लेआउट चुनने के लिए टैप करें"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"उम्मीदवार"</u></string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index af8de3f7ebc4..837aa5662208 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -235,10 +235,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sadržaj je skriven prema pravilima"</string> <string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string> <string name="android_system_label" msgid="6577375335728551336">"Sustav Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Prijeđite na osobni"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Prijeđite na radni"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakti"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"pristupati vašim kontaktima"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string> @@ -1071,13 +1069,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DIJELI"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBIJ"</string> <string name="select_input_method" msgid="8547250819326693584">"Promjena tipkovnice"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Ostale tipkovnice"</string> <string name="show_ime" msgid="2506087537466597099">"Zadržava se na zaslonu dok je fizička tipkovnica aktivna"</string> <string name="hardware" msgid="194658061510127999">"Prikaži virtualnu tipkovnicu"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfigurirajte fizičku tipkovnicu"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dodirnite da biste odabrali jezik i raspored"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 6ae5120ddeb0..0c4705da26cf 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"A tartalom irányelv miatt elrejtve"</string> <string name="safeMode" msgid="2788228061547930246">"Biztonsági üzemmód"</string> <string name="android_system_label" msgid="6577375335728551336">"Android rendszer"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Átváltás személyes profilra"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Átváltás munkaprofilra"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Névjegyek"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"hozzáférés a névjegyekhez"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Helyadatok"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"MEGOSZTÁS"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ELUTASÍTÁS"</string> <string name="select_input_method" msgid="8547250819326693584">"Billentyűzet megváltoztatása"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Más billentyűzetek"</string> <string name="show_ime" msgid="2506087537466597099">"Maradjon a képernyőn, amíg a billentyűzet aktív"</string> <string name="hardware" msgid="194658061510127999">"Virtuális billentyűzet"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Állítsa be a fizikai billentyűzetet"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Koppintson a nyelv és a billentyűzetkiosztás kiválasztásához"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"jelöltek"</u></string> diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml index 1a4a2ebe21c7..4be90da94bb9 100644 --- a/core/res/res/values-hy-rAM/strings.xml +++ b/core/res/res/values-hy-rAM/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Բովանդակությունը թաքցվել է ըստ քաղաքականության"</string> <string name="safeMode" msgid="2788228061547930246">"Անվտանգ ռեժիմ"</string> <string name="android_system_label" msgid="6577375335728551336">"Android համակարգ"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Անցնել անհատական պրոֆիլին"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Անցնել աշխատանքային պրոֆիլին"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Կոնտակտներ"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"կոնտակտների հասանելիություն"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Տեղադրություն"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ՏՐԱՄԱԴՐԵԼ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ՄԵՐԺԵԼ"</string> <string name="select_input_method" msgid="8547250819326693584">"Փոխել ստեղնաշարը"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Այլ ստեղնաշարեր"</string> <string name="show_ime" msgid="2506087537466597099">"Պահել էկրանին մինչդեռ ֆիզիկական ստեղնաշարն ակտիվ է"</string> <string name="hardware" msgid="194658061510127999">"Ցույց տալ վիրտուալ ստեղնաշարը"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Կազմաձևեք ֆիզիկական ստեղնաշարը"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Հպեք՝ լեզուն և դասավորությունն ընտրելու համար"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՈՒՓՔԵւՕՖ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"թեկնածուները"</u></string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 480a845137f9..72186176a41f 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Konten disembunyikan menurut kebijakan"</string> <string name="safeMode" msgid="2788228061547930246">"Mode aman"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Beralih ke Pribadi"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Beralih ke Kantor"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontak"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"mengakses kontak"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Lokasi"</string> @@ -1047,8 +1045,8 @@ <string name="no_permissions" msgid="7283357728219338112">"Tidak perlu izin"</string> <string name="perm_costs_money" msgid="4902470324142151116">"ini mungkin tidak gratis"</string> <string name="dlg_ok" msgid="7376953167039865701">"Oke"</string> - <string name="usb_charging_notification_title" msgid="6895185153353640787">"Mengisi daya perangkat ini melalui USB"</string> - <string name="usb_supplying_notification_title" msgid="5310642257296510271">"Menyuplai daya melalui USB ke perangkat yang terpasang"</string> + <string name="usb_charging_notification_title" msgid="6895185153353640787">"Isi daya perangkat ini melalui USB"</string> + <string name="usb_supplying_notification_title" msgid="5310642257296510271">"Suplai daya melalui USB ke perangkat yang terpasang"</string> <string name="usb_mtp_notification_title" msgid="8396264943589760855">"USB untuk transfer file"</string> <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB untuk transfer foto"</string> <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB untuk MIDI"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"BAGIKAN"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"TOLAK"</string> <string name="select_input_method" msgid="8547250819326693584">"Ubah keyboard"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Keyboard lainnya"</string> <string name="show_ime" msgid="2506087537466597099">"Pertahankan di layar jika keyboard fisik masih aktif"</string> <string name="hardware" msgid="194658061510127999">"Tampilkan keyboard virtual"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Mengonfigurasi keyboard fisik"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Ketuk untuk memilih bahasa dan tata letak"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"calon"</u></string> diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml index ce00b0940271..cebc4ccc0235 100644 --- a/core/res/res/values-is-rIS/strings.xml +++ b/core/res/res/values-is-rIS/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Efni falið með reglu"</string> <string name="safeMode" msgid="2788228061547930246">"Örugg stilling"</string> <string name="android_system_label" msgid="6577375335728551336">"Android kerfið"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Skipta yfir í persónulegt snið"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Skipta yfir í vinnusnið"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Tengiliðir"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"fá aðgang að tengiliðunum þínum"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Staðsetning"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DEILA"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"HAFNA"</string> <string name="select_input_method" msgid="8547250819326693584">"Skipta um lyklaborð"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Önnur lyklaborð"</string> <string name="show_ime" msgid="2506087537466597099">"Haltu því á skjánum meðan vélbúnaðarlyklaborðið er virkt"</string> <string name="hardware" msgid="194658061510127999">"Sýna sýndarlyklaborð"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Stilla vélbúnaðarlyklaborð"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Ýttu til að velja tungumál og útlit"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁBCDÐEÉFGHIÍJKLMNOÓPQRSTUÚVWXYÝZÞÆÖ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AÁBCDÐEÉFGHIÍJKLMNOÓPQRSTUÚVWXYÝZÞÆÖ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"möguleikar"</u></string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 19fcf5585b5f..2a73990fad6b 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenuti nascosti in base alle norme"</string> <string name="safeMode" msgid="2788228061547930246">"Modalità provvisoria"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Passa al profilo personale"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Passa al profilo di lavoro"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contatti"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"accedere ai contatti"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Posizione"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"CONDIVIDI"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RIFIUTO"</string> <string name="select_input_method" msgid="8547250819326693584">"Cambia tastiera"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Altre tastiere"</string> <string name="show_ime" msgid="2506087537466597099">"Tieni sullo schermo quando è attiva la tastiera fisica"</string> <string name="hardware" msgid="194658061510127999">"Mostra tastiera virtuale"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configura la tastiera fisica"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tocca per selezionare la lingua e il layout"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidati"</u></string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 41acce9091eb..80435b684b00 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -237,10 +237,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"התוכן מוסתר על ידי המדיניות"</string> <string name="safeMode" msgid="2788228061547930246">"מצב בטוח"</string> <string name="android_system_label" msgid="6577375335728551336">"מערכת Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"עבור ל\'אישי\'"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"עבור ל\'עבודה\'"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"אנשי קשר"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"גישה אל אנשי הקשר"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"מיקום"</string> @@ -1079,13 +1077,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"שתף"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"דחה"</string> <string name="select_input_method" msgid="8547250819326693584">"שינוי מקלדת"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"מקלדות אחרות"</string> <string name="show_ime" msgid="2506087537466597099">"השאר אותו במסך בזמן שהמקלדת הפיזית פעילה"</string> <string name="hardware" msgid="194658061510127999">"הצג מקלדת וירטואלית"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"הגדרת מקלדת פיזית"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"הקש כדי לבחור שפה ופריסה"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"מועמדים"</u></string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index dff30b42e054..394775f45bdb 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ポリシーによって非表示になっているコンテンツ"</string> <string name="safeMode" msgid="2788228061547930246">"セーフモード"</string> <string name="android_system_label" msgid="6577375335728551336">"Androidシステム"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"個人用に切り替える"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"仕事用に切り替える"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"連絡先"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"連絡先へのアクセス"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"位置情報"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"共有する"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"共有しない"</string> <string name="select_input_method" msgid="8547250819326693584">"キーボードの変更"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"その他のキーボード"</string> <string name="show_ime" msgid="2506087537466597099">"物理キーボードが有効になっている間は、画面に表示されます"</string> <string name="hardware" msgid="194658061510127999">"仮想キーボードの表示"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"物理キーボードの設定"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"タップして言語とレイアウトを選択してください"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"候補"</u></string> diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml index eaed9dd9b86b..fcc56da78f17 100644 --- a/core/res/res/values-ka-rGE/strings.xml +++ b/core/res/res/values-ka-rGE/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"შიგთავსი დამალულია წესების შესაბამისად"</string> <string name="safeMode" msgid="2788228061547930246">"უსაფრთხო რეჟიმი"</string> <string name="android_system_label" msgid="6577375335728551336">"Android-ის სისტემა"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"პირად პროფილზე გადართვა"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"სამსახურის პროფილზე გადართვა"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"კონტაქტები"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"თქვენს კონტაქტებზე წვდომა"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"მდებარეობა"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"გაზიარება"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"უარყოფა"</string> <string name="select_input_method" msgid="8547250819326693584">"კლავიატურის შეცვლა"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"სხვა კლავიატურები"</string> <string name="show_ime" msgid="2506087537466597099">"აქტიური ფიზიკური კლავიატურისას ეკრანზე შენარჩუნება"</string> <string name="hardware" msgid="194658061510127999">"ვირტუალური კლავიატურის ჩვენება"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"მოახდინეთ ფიზიკური კლავიატურის კონფიგურაცია"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"შეეხეთ ენისა და განლაგების ასარჩევად"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"კანდიდატები"</u></string> diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml index aecf49f8d969..6eaa770f9cb9 100644 --- a/core/res/res/values-kk-rKZ/strings.xml +++ b/core/res/res/values-kk-rKZ/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Мазмұн саясатқа сай жасырылған"</string> <string name="safeMode" msgid="2788228061547930246">"Қауіпсіз режим"</string> <string name="android_system_label" msgid="6577375335728551336">"Android жүйесі"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Жекеге ауысу"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Жұмысқа ауысу"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Контактілер"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"контактілерге кіру"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Орын"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"БӨЛІСУ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ҚАБЫЛДАМАУ"</string> <string name="select_input_method" msgid="8547250819326693584">"Пернетақтаны өзгерту"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Басқа пернетақталар"</string> <string name="show_ime" msgid="2506087537466597099">"Физикалық пернетақта белсенді кезде оны экранда ұстау"</string> <string name="hardware" msgid="194658061510127999">"Виртуалды пернетақтаны көрсету"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Физикалық пернетақтаны конфигурациялау"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Тіл мен пернетақта схемасын таңдау үшін түртіңіз"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"үміткерлер"</u></string> diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml index fb80d6e603e7..30d3c0a4a0a4 100644 --- a/core/res/res/values-km-rKH/strings.xml +++ b/core/res/res/values-km-rKH/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"មាតិកាត្រូវបានលាក់ដោយផ្អែកលើគោលការណ៍"</string> <string name="safeMode" msgid="2788228061547930246">"របៀបសុវត្ថិភាព"</string> <string name="android_system_label" msgid="6577375335728551336">"ប្រព័ន្ធ Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"ប្តូរទៅផ្ទាល់ខ្លួន"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"ប្តូរទៅការងារ"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"ទំនាក់ទំនង"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ចូលប្រើទំនាក់ទំនងរបស់អ្នក"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"ទីតាំង"</string> @@ -1065,13 +1063,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ចែករំលែក"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"បដិសេធ"</string> <string name="select_input_method" msgid="8547250819326693584">"ប្ដូរក្ដារចុច"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"ក្តារចុចផ្សេងទៀត"</string> <string name="show_ime" msgid="2506087537466597099">"ទុកវានៅលើអេក្រង់ខណៈពេលក្តារចុចពិតប្រាកដកំពុងសកម្ម"</string> <string name="hardware" msgid="194658061510127999">"បង្ហាញក្ដារចុចនិម្មិត"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"កំណត់រចនាសម្ព័ន្ធក្តារចុចពិតប្រាកដ"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ប៉ះដើម្បីជ្រើសភាសា និងប្លង់"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"បេក្ខជន"</u></string> diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml index f2e5024dbe7f..087b399ed54e 100644 --- a/core/res/res/values-kn-rIN/strings.xml +++ b/core/res/res/values-kn-rIN/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ನೀತಿಯಿಂದ ಮರೆಮಾಡಲಾಗಿರುವ ವಿಷಯಗಳು"</string> <string name="safeMode" msgid="2788228061547930246">"ಸುರಕ್ಷಿತ ಮೋಡ್"</string> <string name="android_system_label" msgid="6577375335728551336">"Android ಸಿಸ್ಟಂ"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"ವೈಯಕ್ತಿಕಗೆ ಬದಲಿಸಿ"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"ಕೆಲಸಕ್ಕೆ ಬದಲಿಸು"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"ಸಂಪರ್ಕಗಳು"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು ಪ್ರವೇಶಿಸಲು"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"ಸ್ಥಳ"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ಹಂಚಿಕೊಳ್ಳಿ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ನಿರಾಕರಿಸು"</string> <string name="select_input_method" msgid="8547250819326693584">"ಕೀಬೋರ್ಡ್ ಬದಲಿಸಿ"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"ಇತರೆ ಕೀಬೋರ್ಡ್ಗಳು"</string> <string name="show_ime" msgid="2506087537466597099">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್ ಸಕ್ರಿಯವಾಗಿರುವಾಗ ಅದನ್ನು ಪರದೆಯ ಮೇಲೆ ಇರಿಸಿಕೊಳ್ಳಿ"</string> <string name="hardware" msgid="194658061510127999">"ವರ್ಚ್ಯುಯಲ್ ಕೀಬೋರ್ಡ್ ತೋರಿಸು"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್ ಕಾನ್ಫಿಗರ್ ಮಾಡಿ"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ಭಾಷೆ ಮತ್ತು ವಿನ್ಯಾಸವನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"ಅಭ್ಯರ್ಥಿಗಳು"</u></string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index dc69ee99146e..52de5bab91c7 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"콘텐츠가 정책에 의해 숨겨졌습니다."</string> <string name="safeMode" msgid="2788228061547930246">"안전 모드"</string> <string name="android_system_label" msgid="6577375335728551336">"Android 시스템"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"개인으로 전환"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"직장으로 전환"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"주소록"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"주소록에 접근할 수 있도록"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"위치"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"공유"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"거부"</string> <string name="select_input_method" msgid="8547250819326693584">"키보드 변경"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"기타 키보드"</string> <string name="show_ime" msgid="2506087537466597099">"물리적 키보드가 활성 상태인 경우 화면에 켜 둠"</string> <string name="hardware" msgid="194658061510127999">"가상 키보드 표시"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"물리적 키보드 설정"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"탭하여 언어와 레이아웃을 선택하세요."</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"가능한 원인"</u></string> diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml index 03951a444c46..34cc7e50a5d7 100644 --- a/core/res/res/values-ky-rKG/strings.xml +++ b/core/res/res/values-ky-rKG/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Тийиштүү саясат боюнча жашырылган мазмундар"</string> <string name="safeMode" msgid="2788228061547930246">"Коопсуз режим"</string> <string name="android_system_label" msgid="6577375335728551336">"Android Тутуму"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Жеке профилге которулуу"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Жумуш профилине которулуу"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Байланыштар"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"байланыштарыңызга уруксат"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Жайгашкан жер"</string> @@ -1064,13 +1062,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"БӨЛҮШҮҮ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ЧЕТКЕ КАГУУ"</string> <string name="select_input_method" msgid="8547250819326693584">"Баскычтопту өзгөртүү"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Башка баскычтоптор"</string> <string name="show_ime" msgid="2506087537466597099">"Баскычтоп иштетилгенде экранда көрүнүп турсун"</string> <string name="hardware" msgid="194658061510127999">"Виртуалдык баскычтоп"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Аппараттык баскычтопту конфигурациялоо"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Тил жана калып тандоо үчүн таптап коюңуз"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"талапкерлер"</u></string> diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml index f64f8df12eaf..ea62f9b93a54 100644 --- a/core/res/res/values-lo-rLA/strings.xml +++ b/core/res/res/values-lo-rLA/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ເນື້ອຫາຖືກເຊື່ອງຕາມນະໂຍບາຍ"</string> <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string> <string name="android_system_label" msgid="6577375335728551336">"ລະບົບ Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"ສະລັບໄປໂປຣໄຟລ໌ສ່ວນຕົວ"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"ສະລັບໄປໂປຣໄຟລ໌ວຽ."</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"ລາຍຊື່"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ເຂົ້າຫາລາຍຊື່ຂອງທ່ານ"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"ສະຖານທີ່"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ແບ່ງປັນ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ປະຕິເສດ"</string> <string name="select_input_method" msgid="8547250819326693584">"ປ່ຽນແປ້ນພິມ"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"ແປ້ນພິມອື່ນໆ"</string> <string name="show_ime" msgid="2506087537466597099">"ເປີດໃຊ້ໃຫ້ມັນຢູ່ໃນໜ້າຈໍໃນຂະນະທີ່ໃຊ້ແປ້ນພິມພາຍນອກຢູ່"</string> <string name="hardware" msgid="194658061510127999">"ສະແດງແປ້ນພິມສະເໝືອນ"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"ຕັ້ງຄ່າແປ້ນພິມພາຍນອກ"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ແຕະເພື່ອເລືອກພາສາ ແລະ ໂຄງແປ້ນພິມ"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"ຕົວເລືອກ"</u></string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 517a069a4aee..3e815ecee396 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -237,10 +237,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Turinys paslėptas vadovaujantis politika"</string> <string name="safeMode" msgid="2788228061547930246">"Saugos režimas"</string> <string name="android_system_label" msgid="6577375335728551336">"„Android“ sistema"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Perjungti į asmeninį režimą"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Perjungti į darbo režimą"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktai"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"pasiekti kontaktus"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Vietovė"</string> @@ -1079,13 +1077,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"BENDRINTI"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ATMESTI"</string> <string name="select_input_method" msgid="8547250819326693584">"Klaviatūros keitimas"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Kitos klaviatūros"</string> <string name="show_ime" msgid="2506087537466597099">"Palikti ekrane, kol fizinė klaviatūra aktyvi"</string> <string name="hardware" msgid="194658061510127999">"Rodyti virtualiąją klaviatūrą"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Fizinės klaviatūros konfigūravimas"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Palieskite, kad pasirinktumėte kalbą ir išdėstymą"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidatai"</u></string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 8d8f99b6d66c..56001fc07de1 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -235,10 +235,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Saskaņā ar politiku saturs ir paslēpts."</string> <string name="safeMode" msgid="2788228061547930246">"Drošais režīms"</string> <string name="android_system_label" msgid="6577375335728551336">"Android sistēma"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Pārslēgt personīgo profilu"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Pārslēgt darba profilu"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktpersonas"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"piekļūt jūsu kontaktpersonu datiem"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Atrašanās vieta"</string> @@ -1071,13 +1069,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"KOPĪGOT"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"NORAIDĪT"</string> <string name="select_input_method" msgid="8547250819326693584">"Tastatūras maiņa"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Citas tastatūras"</string> <string name="show_ime" msgid="2506087537466597099">"Paturēt ekrānā, kamēr ir aktīva fiziskā tastatūra"</string> <string name="hardware" msgid="194658061510127999">"Virtuālās tastatūras rādīšana"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Fiziskās tastatūras konfigurēšana"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Pieskarieties, lai atlasītu valodu un izkārtojumu"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidāti"</u></string> diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml index 71c19517b8d1..060a9fa9fc33 100644 --- a/core/res/res/values-mk-rMK/strings.xml +++ b/core/res/res/values-mk-rMK/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Содржините се скриени поради политиката"</string> <string name="safeMode" msgid="2788228061547930246">"Безбеден режим"</string> <string name="android_system_label" msgid="6577375335728551336">"Систем Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Префрлете на личен профил"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Префрли на работен профил"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"пристапува до контактите"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"СПОДЕЛИ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ОДБИЈ"</string> <string name="select_input_method" msgid="8547250819326693584">"Измени тастатура"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Други тастатури"</string> <string name="show_ime" msgid="2506087537466597099">"Прикажувај го на екранот додека е активна физичката тастатура"</string> <string name="hardware" msgid="194658061510127999">"Прикажи виртуелна тастатура"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Конфигурирајте физичка тастатура"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Допрете за избирање јазик и распоред"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string> diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml index 92f9282cd068..f6ff1d8b5ffd 100644 --- a/core/res/res/values-ml-rIN/strings.xml +++ b/core/res/res/values-ml-rIN/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"നയം അനുസരിച്ച് ഉള്ളടക്കം മറച്ചിരിക്കുന്നു"</string> <string name="safeMode" msgid="2788228061547930246">"സുരക്ഷിത മോഡ്"</string> <string name="android_system_label" msgid="6577375335728551336">"Android സിസ്റ്റം"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"വ്യക്തിഗത പ്രൊഫൈലിലേക്ക് മാറുക"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"ഔദ്യോഗിക പ്രൊഫൈലിലേക്ക് മാറുക"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"കോൺടാക്റ്റുകൾ"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"നിങ്ങളുടെ കോൺടാക്റ്റുകൾ ആക്സസ്സ് ചെയ്യുക"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"ലൊക്കേഷൻ"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"പങ്കിടുക"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"നിരസിക്കുക"</string> <string name="select_input_method" msgid="8547250819326693584">"കീബോഡ് മാറ്റുക"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"മറ്റ് കീബോർഡുകൾ"</string> <string name="show_ime" msgid="2506087537466597099">"ഫിസിക്കൽ കീബോർഡ് സജീവമായിരിക്കുമ്പോൾ സ്ക്രീനിൽ നിലനിർത്തുക"</string> <string name="hardware" msgid="194658061510127999">"വെർച്വൽ കീബോർഡ് കാണിക്കുക"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"ഫിസിക്കൽ കീബോർഡ് കോൺഫിഗർ ചെയ്യുക"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ഭാഷയും ലേഔട്ടും തിരഞ്ഞെടുക്കുന്നതിന് ടാപ്പുചെയ്യുക"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"കാൻഡിഡേറ്റുകൾ"</u></string> diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml index c1cba4feacf4..75105e6a9252 100644 --- a/core/res/res/values-mn-rMN/strings.xml +++ b/core/res/res/values-mn-rMN/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Удирдамжийн дагуу нуусан агуулга"</string> <string name="safeMode" msgid="2788228061547930246">"Аюулгүй горим"</string> <string name="android_system_label" msgid="6577375335728551336">"Андройд систем"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"\"Хувийн\" руу шилжих"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"\"Ажлын\" руу шилжих"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Харилцагчдын хаяг"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"харилцагч руугаа хандах"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Байршил"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ХУВААЛЦАХ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ТАТГАЛЗАХ"</string> <string name="select_input_method" msgid="8547250819326693584">"Гарыг өөрчлөх"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Бусад гар"</string> <string name="show_ime" msgid="2506087537466597099">"Бодит гар идэвхтэй үед үүнийг дэлгэцэнд харуулна уу"</string> <string name="hardware" msgid="194658061510127999">"Хийсвэр гарыг харуулах"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Биет гарыг хэлбэрт оруулах"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Хэл болон бүдүүвчийг сонгохын тулд дарна уу"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"нэр дэвшигч"</u></string> diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml index f41e6ed5d2c3..8a3e56469e83 100644 --- a/core/res/res/values-mr-rIN/strings.xml +++ b/core/res/res/values-mr-rIN/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"धोरणाद्वारे सामग्री लपविली"</string> <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string> <string name="android_system_label" msgid="6577375335728551336">"Android सिस्टम"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"वैयक्तिकवर स्विच करा"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"कार्यावर स्विच करा"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"संपर्क"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"आपल्या संपर्कांवर प्रवेश"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"सामायिक करा"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"नकार द्या"</string> <string name="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदला"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"इतर कीबोर्ड"</string> <string name="show_ime" msgid="2506087537466597099">"भौतिक कीबोर्ड सक्रिय असताना त्यास स्क्रीनवर ठेवा"</string> <string name="hardware" msgid="194658061510127999">"व्हर्च्युअल कीबोर्ड दर्शवा"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"वास्तविक कीबोर्ड कॉन्फिगर करा"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"भाषा आणि लेआउट निवडण्यासाठी टॅप करा"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"उमेदवार"</u></string> diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml index 9a69bf97af91..5db9c779ef34 100644 --- a/core/res/res/values-ms-rMY/strings.xml +++ b/core/res/res/values-ms-rMY/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Kandungan disembunyikan oleh dasar"</string> <string name="safeMode" msgid="2788228061547930246">"Mod selamat"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Beralih kepada Peribadi"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Beralih kepada Kerja"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kenalan"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"mengakses kenalan anda"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Lokasi"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"KONGSI"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"TOLAK"</string> <string name="select_input_method" msgid="8547250819326693584">"Tukar papan kekunci"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Papan kekunci lain"</string> <string name="show_ime" msgid="2506087537466597099">"Pastikannya pada skrin, semasa papan kekunci fizikal aktif"</string> <string name="hardware" msgid="194658061510127999">"Tunjukkan papan kekunci maya"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfigurasikan papan kekunci fizikal"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Ketik untuk memilih bahasa dan susun atur"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"calon"</u></string> diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml index b3c80d59f33b..5e5ec4e03953 100644 --- a/core/res/res/values-my-rMM/strings.xml +++ b/core/res/res/values-my-rMM/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"မူဝါဒမှ အကြောင်းအရာများကို ဝှက်ထားသည်"</string> <string name="safeMode" msgid="2788228061547930246">"အန္တရာယ်ကင်းမှု စနစ်(Safe mode)"</string> <string name="android_system_label" msgid="6577375335728551336">"Android စနစ်"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"ကိုယ်ပိုင်သီးသန့်အဖြစ် ပြောင်းပါ"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"အလုပ်သို့ ပြောင်းပါ"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"အဆက်အသွယ်များ"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"သင့် အဆက်အသွယ်များအား ဝင်ရောက်သုံးရန်"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"တည်နေရာ"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"မျှဝေပါ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ငြင်းပယ်ပါ"</string> <string name="select_input_method" msgid="8547250819326693584">"ကီးဘုတ် ပြောင်းလဲရန်"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"အခြားကီးဘုတ်များ"</string> <string name="show_ime" msgid="2506087537466597099">"စက်၏ကီးဘုတ်ကိုအသုံးပြုနေစဉ် ၎င်းကိုမျက်နှာပြင်ပေါ်တွင် ထားပါ"</string> <string name="hardware" msgid="194658061510127999">"ကီးဘုတ်အတုပြရန်"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"ရုပ်ပိုင်းဆိုင်ရာ အသွင်အပြင်ကို ပြင်ဆင်သတ်မှတ်ပါ"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ဘာသာစကားနှင့် အသွင်အပြင်ရွေးချယ်ရန် တို့ပါ"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"ရွေးချယ်ခံမည့်သူ"</u></string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index bebf59337422..cfccdeb33d87 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Innholdet er skjult i henhold til retningslinjene"</string> <string name="safeMode" msgid="2788228061547930246">"Sikkermodus"</string> <string name="android_system_label" msgid="6577375335728551336">"Android-system"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Bytt til den personlige profilen"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Bytt til jobbprofilen"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakter"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"se kontaktene dine"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Posisjon"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DEL"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"AVSLÅ"</string> <string name="select_input_method" msgid="8547250819326693584">"Endre tastatur"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Andre tastaturoppsett"</string> <string name="show_ime" msgid="2506087537466597099">"Ha den på skjermen mens det fysiske tastaturet er aktivt"</string> <string name="hardware" msgid="194658061510127999">"Vis det virtuelle tastaturet"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfigurer et fysisk tastatur"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Trykk for å velge språk og layout"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string> <string name="candidates_style" msgid="4333913089637062257">"TAG_FONT"<u>"kandidater"</u>"CLOSE_FONT"</string> diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml index 24bb1f0435db..fb817b593423 100644 --- a/core/res/res/values-ne-rNP/strings.xml +++ b/core/res/res/values-ne-rNP/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"नीतिद्वारा लुकाइएका सामग्री"</string> <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string> <string name="android_system_label" msgid="6577375335728551336">"एन्ड्रोइड प्रणाली"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"व्यक्तिगत प्रोफाइलमा स्विच गर्नुहोस्"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"कार्य प्रोफाइलमा स्विच गर्नुहोस्"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"सम्पर्कहरू"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"तपाईँको सम्पर्कमा पहुँच गर्नुहोस्"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"स्थान"</string> @@ -1069,13 +1067,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"साझेदारी गर्नुहोस्"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"अस्वीकार गर्नुहोस्"</string> <string name="select_input_method" msgid="8547250819326693584">"कुञ्जीपाटी परिवर्तन गर्नुहोस्"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"अन्य किबोर्डहरू"</string> <string name="show_ime" msgid="2506087537466597099">"भौतिक किबोर्ड सक्रिय हुँदा यसलाई स्क्रिनमा राख्नुहोस्"</string> <string name="hardware" msgid="194658061510127999">"भर्चुअल किबोर्ड देखाउनुहोस्"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"फिजिकल किबोर्डलाई कन्फिगर गर्नुहोस्"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"भाषा र लेआउट चयन गर्न ट्याप गर्नुहोस्"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"उम्मेदवार"</u></string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 5759cad68922..3de8496872af 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Content verborgen op basis van beleid"</string> <string name="safeMode" msgid="2788228061547930246">"Veilige modus"</string> <string name="android_system_label" msgid="6577375335728551336">"Android-systeem"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Overschakelen naar persoonlijk profiel"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Overschakelen naar werkprofiel"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacten"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"toegang krijgen tot je contacten"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Locatie"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DELEN"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"WEIGEREN"</string> <string name="select_input_method" msgid="8547250819326693584">"Toetsenbord wijzigen"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Andere toetsenborden"</string> <string name="show_ime" msgid="2506087537466597099">"Dit op het scherm weergeven terwijl het fysieke toetsenbord actief is"</string> <string name="hardware" msgid="194658061510127999">"Virtueel toetsenbord tonen"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Fysiek toetsenbord configureren"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tik om een taal en indeling te selecteren"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidaten"</u></string> diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml index b984760d2a04..87f973fe5b40 100644 --- a/core/res/res/values-pa-rIN/strings.xml +++ b/core/res/res/values-pa-rIN/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ਨੀਤੀ ਦੁਆਰਾ ਸਮੱਗਰੀ ਲੁਕਾਈ ਗਈ"</string> <string name="safeMode" msgid="2788228061547930246">"ਸੁਰੱਖਿਅਤ ਮੋਡ"</string> <string name="android_system_label" msgid="6577375335728551336">"Android System"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"ਨਿੱਜੀ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"ਕੰਮ \'ਤੇ ਸਵਿੱਚ ਕਰੋ"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"ਸੰਪਰਕ"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ਆਪਣੇ ਸੰਪਰਕਾਂ ਨੂੰ ਐਕਸੈਸ ਕਰੋ"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"ਨਿਰਧਾਰਿਤ ਸਥਾਨ"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ਸਾਂਝੀ ਕਰੋ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ਅਸਵੀਕਾਰ ਕਰੋ"</string> <string name="select_input_method" msgid="8547250819326693584">"ਕੀਬੋਰਡ ਬਦਲੋ"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"ਹੋਰ ਕੀ-ਬੋਰਡ"</string> <string name="show_ime" msgid="2506087537466597099">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ ਸਰਗਰਮ ਹੋਣ ਦੌਰਾਨ ਇਸ ਨੂੰ ਸਕ੍ਰੀਨ \'ਤੇ ਬਣਾਈ ਰੱਖੋ"</string> <string name="hardware" msgid="194658061510127999">"ਵਰਚੁਅਲ ਕੀ-ਬੋਰਡ ਵਿਖਾਓ"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ ਦਾ ਸੰਰੂਪਣ ਕਰੋ"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"ਭਾਸ਼ਾ ਅਤੇ ਖਾਕਾ ਚੁਣਨ ਲਈ ਟੈਪ ਕਰੋ"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"ਉਮੀਦਵਾਰ"</u></string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 7248f4a8623e..6be9a9d70878 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -237,10 +237,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Treść ukryta z powodu zasad"</string> <string name="safeMode" msgid="2788228061547930246">"Tryb awaryjny"</string> <string name="android_system_label" msgid="6577375335728551336">"System Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Włącz profil osobisty"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Włącz profil do pracy"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakty"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"dostęp do kontaktów"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Lokalizacja"</string> @@ -1079,13 +1077,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"UDOSTĘPNIJ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODRZUĆ"</string> <string name="select_input_method" msgid="8547250819326693584">"Zmień klawiaturę"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Inne klawiatury"</string> <string name="show_ime" msgid="2506087537466597099">"Pozostaw na ekranie, gdy aktywna jest klawiatura fizyczna"</string> <string name="hardware" msgid="194658061510127999">"Pokaż klawiaturę wirtualną"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Skonfiguruj klawiaturę fizyczną"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Kliknij, by wybrać język i układ"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandydaci"</u></string> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index bddb0fcac60e..c8004bf7606d 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Conteúdo ocultado pela política"</string> <string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Alternar para \"Pessoal\""</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Alternar para \"Trabalho\""</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contatos"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acesse seus contatos"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Local"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTILHAR"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RECUSAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Outros teclados"</string> <string name="show_ime" msgid="2506087537466597099">"Manter na tela enquanto o teclado físico estiver ativo"</string> <string name="hardware" msgid="194658061510127999">"Mostrar teclado virtual"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configurar teclado físico"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toque para selecionar o idioma e o layout"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 68c4bd93e12d..c2ba8ad701b5 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Conteúdo ocultado pela política"</string> <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Mudar para pessoal"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Mudar para trabalho"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contactos"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"aceder aos contactos"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Localização"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PARTILHAR"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RECUSAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Outros teclados"</string> <string name="show_ime" msgid="2506087537466597099">"Manter no ecrã enquanto o teclado físico estiver ativo"</string> <string name="hardware" msgid="194658061510127999">"Mostrar o teclado virtual"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configurar teclado físico"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toque para selecionar o idioma e o esquema"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index bddb0fcac60e..c8004bf7606d 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Conteúdo ocultado pela política"</string> <string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistema Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Alternar para \"Pessoal\""</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Alternar para \"Trabalho\""</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Contatos"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acesse seus contatos"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Local"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTILHAR"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RECUSAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Outros teclados"</string> <string name="show_ime" msgid="2506087537466597099">"Manter na tela enquanto o teclado físico estiver ativo"</string> <string name="hardware" msgid="194658061510127999">"Mostrar teclado virtual"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configurar teclado físico"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Toque para selecionar o idioma e o layout"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidatos"</u></string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 58c93834c898..7485e65361a1 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -235,10 +235,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Conținutul este ascuns conform politicii"</string> <string name="safeMode" msgid="2788228061547930246">"Mod sigur"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistemul Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Comutați la Personal"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Comutați la Serviciu"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Persoane de contact"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"acceseze persoanele de contact"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Locație"</string> @@ -1071,13 +1069,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"TRIMITEȚI"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REFUZAȚI"</string> <string name="select_input_method" msgid="8547250819326693584">"Schimbați tastatura"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Alte tastaturi"</string> <string name="show_ime" msgid="2506087537466597099">"Se păstrează pe ecran cât timp este activată tastatura fizică"</string> <string name="hardware" msgid="194658061510127999">"Afișați tastatura virtuală"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Configurați tastatura fizică"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Atingeți pentru a selecta limba și aspectul"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"candidați"</u></string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 345bb49cb076..5926bfdf1b2c 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -237,10 +237,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Содержимое скрыто в соответствии с заданными правилами"</string> <string name="safeMode" msgid="2788228061547930246">"Безопасный режим"</string> <string name="android_system_label" msgid="6577375335728551336">"Система Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Перейти в личный профиль"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Перейти в рабочий профиль"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакты"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"доступ к контактам"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Местоположение"</string> @@ -1079,13 +1077,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ПРЕДОСТАВИТЬ ДОСТУП"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ОТКЛОНИТЬ"</string> <string name="select_input_method" msgid="8547250819326693584">"Выбор раскладки"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Другие клавиатуры"</string> <string name="show_ime" msgid="2506087537466597099">"Показывать на экране, когда физическая клавиатура включена"</string> <string name="hardware" msgid="194658061510127999">"Виртуальная клавиатура"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Настройка физической клавиатуры"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Нажмите, чтобы выбрать язык и раскладку"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"варианты"</u></string> diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml index f01ab61dfe98..6c76da0e7981 100644 --- a/core/res/res/values-si-rLK/strings.xml +++ b/core/res/res/values-si-rLK/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ප්රතිපත්තිය විසින් අන්තර්ගතය සඟවන ලදී"</string> <string name="safeMode" msgid="2788228061547930246">"ආරක්ෂිත ආකාරය"</string> <string name="android_system_label" msgid="6577375335728551336">"Android පද්ධතිය"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"පුද්ගලික වෙත මාරු වන්න"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"කාර්යාලය වෙත මාරු වන්න"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"සම්බන්ධතා"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ඔබේ සම්බන්ධතාවලට පිවිසෙන්න"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"ස්ථානය"</string> @@ -1065,13 +1063,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"බෙදා ගන්න"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ප්රතික්ෂේප කරන්න"</string> <string name="select_input_method" msgid="8547250819326693584">"යතුරු පුවරු වෙනස් කිරීම"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"වෙනත් යතුරු පුවරු"</string> <string name="show_ime" msgid="2506087537466597099">"භෞතික යතුරු පුවරුව සක්රිය අතරතුර එය තිරය මත තබා ගන්න"</string> <string name="hardware" msgid="194658061510127999">"අතථ්ය යතුරු පුවරුව පෙන්වන්න"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"භෞතික යතුරු පුවරුව වින්යාස කරන්න"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"භාෂාව හා පිරිසැලසුම තේරීමට තට්ටු කරන්න"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"අපේක්ෂකයන්"</u></string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 1a3ef4cefbaf..ec45070f83e0 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -237,10 +237,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Obsah je na základe pravidiel skrytý"</string> <string name="safeMode" msgid="2788228061547930246">"Núdzový režim"</string> <string name="android_system_label" msgid="6577375335728551336">"Systém Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Prepnúť na osobný"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Prepnúť na pracovný"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakty"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"prístup k vašim kontaktom"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Poloha"</string> @@ -1079,13 +1077,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ZDIEĽAŤ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODMIETNUŤ"</string> <string name="select_input_method" msgid="8547250819326693584">"Zmeniť klávesnicu"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Ďalšie klávesnice"</string> <string name="show_ime" msgid="2506087537466597099">"Ponechať na obrazovke, keď je aktívna fyzická klávesnica"</string> <string name="hardware" msgid="194658061510127999">"Zobraziť virtuálnu klávesnicu"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfigurácia fyzickej klávesnice"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Klepnutím vyberte jazyk a rozloženie"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" AÁÄBCČDĎDZDŽEÉFGHCHIÍJKLĽMNŇOÓÔPRŔSŠTŤUÚVWXYÝZŽ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidáti"</u></string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index c102abbb1c48..b2dba7e0a686 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -237,10 +237,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Pravilnik je skril vsebino"</string> <string name="safeMode" msgid="2788228061547930246">"Varni način"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistem Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Preklop na osebni profil"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Preklop na delovni profil"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Stiki"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"dostop do stikov"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Lokacija"</string> @@ -1079,13 +1077,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"SKUPNA RABA"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"NE SPREJMEM"</string> <string name="select_input_method" msgid="8547250819326693584">"Sprememba tipkovnice"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Druge tipkovnice"</string> <string name="show_ime" msgid="2506087537466597099">"Ohrani na zaslonu, dokler je aktivna fizična tipkovnica"</string> <string name="hardware" msgid="194658061510127999">"Pokaži navidezno tipkovnico"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfiguriranje fizične tipkovnice"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dotaknite se, če želite izbrati jezik in postavitev."</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidati"</u></string> diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml index 9151893c6064..1846399b5a2d 100644 --- a/core/res/res/values-sq-rAL/strings.xml +++ b/core/res/res/values-sq-rAL/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Përmbajtja është e fshehur për shkak të politikës"</string> <string name="safeMode" msgid="2788228061547930246">"Modaliteti i sigurisë"</string> <string name="android_system_label" msgid="6577375335728551336">"Sistemi \"android\""</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Ndryshoje te \"Personale\""</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Ndryshoje te \"Puna\""</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktet"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"qasu te kontaktet e tua"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Vendndodhja"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"SHPËRNDA"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REFUZO"</string> <string name="select_input_method" msgid="8547250819326693584">"Ndërro tastierë"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Tastierat e tjera"</string> <string name="show_ime" msgid="2506087537466597099">"Mbaje në ekran ndërsa tastiera fizike është aktive"</string> <string name="hardware" msgid="194658061510127999">"Shfaq tastierën virtuale"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfiguro tastierën fizike"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Trokit për të zgjedhur gjuhën dhe strukturën"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidatë"</u></string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 9f8c2c0e5509..2112dbb5afe6 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -235,10 +235,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Садржај је сакривен смерницама"</string> <string name="safeMode" msgid="2788228061547930246">"Безбедни режим"</string> <string name="android_system_label" msgid="6577375335728551336">"Android систем"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Пређи на Лични профил"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Пређи на профил за Work"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"приступи контактима"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Локација"</string> @@ -1071,13 +1069,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ДЕЛИ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ОДБИЈ"</string> <string name="select_input_method" msgid="8547250819326693584">"Промените тастатуру"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Друге тастатуре"</string> <string name="show_ime" msgid="2506087537466597099">"Задржи га на екрану док је физичка тастатура активна"</string> <string name="hardware" msgid="194658061510127999">"Прикажи виртуелну тастатуру"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Конфигуришите физичку тастатуру"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Додирните да бисте изабрали језик и распоред"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index d3855f8d0952..832d4a2bf213 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Innehåll har dolts p.g.a. en policy"</string> <string name="safeMode" msgid="2788228061547930246">"Säkert läge"</string> <string name="android_system_label" msgid="6577375335728551336">"Android-system"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Byt till din personliga profil"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Byt till jobbprofilen"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontakter"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"få tillgång till dina kontakter"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Plats"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DELA"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"AVVISA"</string> <string name="select_input_method" msgid="8547250819326693584">"Byt tangentbord"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Andra tangentbord"</string> <string name="show_ime" msgid="2506087537466597099">"Ha kvar den på skärmen när det fysiska tangentbordet används"</string> <string name="hardware" msgid="194658061510127999">"Visa virtuellt tangentbord"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Konfigurera fysiskt tangentbord"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Tryck om du vill välja språk och layout"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"kandidater"</u></string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index fd5c2c73f261..e0a32f6a61bb 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -235,10 +235,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Maudhui yamefichwa kulingana na sera"</string> <string name="safeMode" msgid="2788228061547930246">"Mtindo salama"</string> <string name="android_system_label" msgid="6577375335728551336">"Mfumo wa Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Badili uweke wasifu wa Binafsi"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Badili uweke wasifu wa Kazini"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Anwani"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ifikie anwani zako"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Mahali"</string> @@ -1065,13 +1063,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"SHIRIKI"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"KATAA"</string> <string name="select_input_method" msgid="8547250819326693584">"Badilisha kibodi"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Kibodi zingine"</string> <string name="show_ime" msgid="2506087537466597099">"Iweke kwenye skrini wakati kibodi inapotumika"</string> <string name="hardware" msgid="194658061510127999">"Onyesha kibodi pepe"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Sanidi kibodi halisi"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Gonga ili uchague lugha na muundo"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"wagombeaji"</u></string> diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml index f92177a06406..773301f2cad5 100644 --- a/core/res/res/values-ta-rIN/strings.xml +++ b/core/res/res/values-ta-rIN/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"கொள்கையின்படி உள்ளடக்கம் மறைக்கப்பட்டது"</string> <string name="safeMode" msgid="2788228061547930246">"பாதுகாப்பு பயன்முறை"</string> <string name="android_system_label" msgid="6577375335728551336">"Android அமைப்பு"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"தனிப்பட்ட சுயவிவரத்திற்கு மாறு"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"பணிச் சுயவிவரத்திற்கு மாறு"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"தொடர்புகள்"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"தொடர்புகளை அணுகும்"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"இருப்பிடம்"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"பகிர்"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"வேண்டாம்"</string> <string name="select_input_method" msgid="8547250819326693584">"விசைப்பலகையை மாற்று"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"பிற விசைப்பலகைகள்"</string> <string name="show_ime" msgid="2506087537466597099">"கைமுறை விசைப்பலகை இயக்கத்தில் இருக்கும் போது IMEஐ திரையில் வைத்திரு"</string> <string name="hardware" msgid="194658061510127999">"விர்ச்சுவல் விசைப்பலகையை காட்டு"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"கைமுறை விசைப்பலகையை உள்ளமைக்கவும்"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"மொழியையும் தளவமைப்பையும் தேர்ந்தெடுக்க, தட்டவும்"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"கேன்டிடேட்ஸ்"</u></string> diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml index 9b5fc0188625..4809c989db2d 100644 --- a/core/res/res/values-te-rIN/strings.xml +++ b/core/res/res/values-te-rIN/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"విధానం ద్వారా కంటెంట్లు దాచబడ్డాయి"</string> <string name="safeMode" msgid="2788228061547930246">"సురక్షిత మోడ్"</string> <string name="android_system_label" msgid="6577375335728551336">"Android సిస్టమ్"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"వ్యక్తిగతానికి మార్చు"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"కార్యాలయానికి మార్చు"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"పరిచయాలు"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"మీ పరిచయాలను ప్రాప్యత చేయడానికి"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"స్థానం"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"భాగస్వామ్యం చేయి"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"తిరస్కరిస్తున్నాను"</string> <string name="select_input_method" msgid="8547250819326693584">"కీబోర్డ్ను మార్చు"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"ఇతర కీబోర్డ్లు"</string> <string name="show_ime" msgid="2506087537466597099">"దీన్ని భౌతిక కీబోర్డ్ సక్రియంగా ఉన్నప్పుడు స్క్రీన్పై ఉంచుతుంది"</string> <string name="hardware" msgid="194658061510127999">"వర్చువల్ కీబోర్డ్ను చూపు"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"భౌతిక కీబోర్డుని కాన్ఫిగర్ చేయండి"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"భాష మరియు లేఅవుట్ను ఎంచుకోవడానికి నొక్కండి"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"క్యాండిడేట్లు"</u></string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index ca401bc93206..0ea2e520bc6c 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"มีการซ่อนเนื้อหาโดยนโยบาย"</string> <string name="safeMode" msgid="2788228061547930246">"โหมดปลอดภัย"</string> <string name="android_system_label" msgid="6577375335728551336">"ระบบ Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"เปลี่ยนไปใช้โปรไฟล์ส่วนตัว"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"เปลี่ยนไปใช้โปรไฟล์งาน"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"รายชื่อติดต่อ"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"เข้าถึงรายชื่อติดต่อ"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"ตำแหน่ง"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"แชร์"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ปฏิเสธ"</string> <string name="select_input_method" msgid="8547250819326693584">"เปลี่ยนแป้นพิมพ์"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"แป้นพิมพ์อื่นๆ"</string> <string name="show_ime" msgid="2506087537466597099">"เปิดทิ้งไว้บนหน้าจอในระหว่างใช้งานแป้นพิมพ์จริง"</string> <string name="hardware" msgid="194658061510127999">"แสดงแป้นพิมพ์เสมือน"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"กำหนดค่าแป้นพิมพ์จริง"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"แตะเพื่อเลือกภาษาและรูปแบบ"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"ตัวเลือก"</u></string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 1a63a99a5294..00918a4fb9fc 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Itinago ang mga content alinsunod sa patakaran"</string> <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string> <string name="android_system_label" msgid="6577375335728551336">"Android System"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Lumipat sa Personal"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Lumipat sa para sa Trabaho"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Mga Contact"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"ina-access ang iyong mga contact"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Lokasyon"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"IBAHAGI"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"TANGGIHAN"</string> <string name="select_input_method" msgid="8547250819326693584">"Baguhin ang keyboard"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Iba pang mga keyboard"</string> <string name="show_ime" msgid="2506087537466597099">"Panatilihin ito sa screen habang aktibo ang pisikal na keyboard"</string> <string name="hardware" msgid="194658061510127999">"Ipakita ang virtual keyboard"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"I-configure ang pisikal na keyboard"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"I-tap upang pumili ng wika at layout"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"mga kandidato"</u></string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index e4a44d20f57d..4db8264743ff 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"İçerikler politika nedeniyle gizlendi"</string> <string name="safeMode" msgid="2788228061547930246">"Güvenli mod"</string> <string name="android_system_label" msgid="6577375335728551336">"Android Sistemi"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Kişisel Profile Geç"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"İş Profiline Geç"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kişiler"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"kişilerinize erişme"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Konum"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PAYLAŞ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REDDET"</string> <string name="select_input_method" msgid="8547250819326693584">"Klavyeyi değiştir"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Diğer klavyeler"</string> <string name="show_ime" msgid="2506087537466597099">"Fiziksel klavye etkin durumdayken ekranda tut"</string> <string name="hardware" msgid="194658061510127999">"Sanal klavyeyi göster"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Fiziksel klavyeyi yapılandırın"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Dili ve düzeni seçmek için hafifçe dokunun"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"adaylar"</u></string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index a6020e8a47bf..fe7be12de34e 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -237,10 +237,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Вміст сховано згідно з правилом"</string> <string name="safeMode" msgid="2788228061547930246">"Безп. режим"</string> <string name="android_system_label" msgid="6577375335728551336">"Система Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Перейти в особистий профіль"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Перейти в робочий профіль"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"отримувати доступ до контактів"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Геодані"</string> @@ -1079,13 +1077,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ПОДІЛИТИСЯ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ВІДХИЛИТИ"</string> <string name="select_input_method" msgid="8547250819326693584">"Змінити клавіатуру"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Інші клавіатури"</string> <string name="show_ime" msgid="2506087537466597099">"Утримуйте на екрані, коли активна фізична клавіатура"</string> <string name="hardware" msgid="194658061510127999">"Показати віртуальну клавіатуру"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Налаштуйте фізичну клавіатуру"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Торкніться, щоб вибрати мову та розкладку"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"кандидати"</u></string> diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml index b515c55f2be9..5236b7fae62b 100644 --- a/core/res/res/values-ur-rPK/strings.xml +++ b/core/res/res/values-ur-rPK/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"مواد پالیسی کے تحت مخفی ہے"</string> <string name="safeMode" msgid="2788228061547930246">"حفاظتی وضع"</string> <string name="android_system_label" msgid="6577375335728551336">"Android سسٹم"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"ذاتی پر سوئچ کریں"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"کام پر سوئچ کریں"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"رابطے"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"اپنے رابطوں تک رسائی حاصل کریں"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"مقام"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"اشتراک کریں"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"مسترد کریں"</string> <string name="select_input_method" msgid="8547250819326693584">"کی بورڈ تبدیل کریں"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"دیگر کی بورڈز"</string> <string name="show_ime" msgid="2506087537466597099">"جب فزیکل کی بورڈ فعال ہو تو IME کو اسکرین پر رکھیں"</string> <string name="hardware" msgid="194658061510127999">"ورچوئل کی بورڈ دکھائیں"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"فزیکل کی بورڈ کنفیگر کریں"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"زبان اور لے آؤٹ منتخب کرنے کیلئے تھپتھپائیں"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"امیدواران"</u></string> diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml index 6323f52dc3f2..6cb65a316a7e 100644 --- a/core/res/res/values-uz-rUZ/strings.xml +++ b/core/res/res/values-uz-rUZ/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Qoidaga muvofiq kontent yashirilgan"</string> <string name="safeMode" msgid="2788228061547930246">"Xavfsiz usul"</string> <string name="android_system_label" msgid="6577375335728551336">"Android tizimi"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Shaxsiy profilga o‘tish"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Ishchi profilga o‘tish"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Kontaktlar"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"kontaktlarga kirish"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Joylashuv"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ULASHISH"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RAD ETISH"</string> <string name="select_input_method" msgid="8547250819326693584">"Klaviaturani o‘zgartirish"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Boshqa klaviaturalar"</string> <string name="show_ime" msgid="2506087537466597099">"Tashqi klaviaturadan foydalanilayotganda buni ekranda saqlab turish"</string> <string name="hardware" msgid="194658061510127999">"Virtual klaviatura ko‘rsatilsin"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Tashqi klaviaturani sozlash"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Til va sxemani belgilash uchun bosing"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"nomzodlar"</u></string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 10516afd2d72..29eef922e02f 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Nội dung bị ẩn theo chính sách"</string> <string name="safeMode" msgid="2788228061547930246">"Chế độ an toàn"</string> <string name="android_system_label" msgid="6577375335728551336">"Hệ thống Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Chuyển sang Cá nhân"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Chuyển sang Công việc"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Danh bạ"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"truy cập vào danh bạ của bạn"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Vị trí"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"CHIA SẺ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"TỪ CHỐI"</string> <string name="select_input_method" msgid="8547250819326693584">"Thay đổi bàn phím"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Bàn phím khác"</string> <string name="show_ime" msgid="2506087537466597099">"Tiếp tục sử dụng ứng dụng trên màn hình trong khi bàn phím thực đang hoạt động"</string> <string name="hardware" msgid="194658061510127999">"Hiển thị bàn phím ảo"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Định cấu hình bàn phím thực"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Nhấn để chọn ngôn ngữ và bố cục"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"ứng viên"</u></string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index f7bcaba0d8e5..3b26e461f7b1 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"内容已隐藏(根据政策规定)"</string> <string name="safeMode" msgid="2788228061547930246">"安全模式"</string> <string name="android_system_label" msgid="6577375335728551336">"Android 系统"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"切换到“个人”"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"切换到“工作”"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"通讯录"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"访问您的通讯录"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"位置信息"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"分享"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"拒绝"</string> <string name="select_input_method" msgid="8547250819326693584">"更改键盘"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"其他键盘"</string> <string name="show_ime" msgid="2506087537466597099">"连接到实体键盘时使其在屏幕上保持显示状态"</string> <string name="hardware" msgid="194658061510127999">"显示虚拟键盘"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"配置实体键盘"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"点按即可选择语言和布局"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"候选"</u></string> @@ -1478,7 +1473,7 @@ <string name="package_installed_device_owner" msgid="8420696545959087545">"已由管理员安装"</string> <string name="package_updated_device_owner" msgid="8856631322440187071">"由您单位的管理员更新"</string> <string name="package_deleted_device_owner" msgid="7650577387493101353">"已被管理员删除"</string> - <string name="battery_saver_description" msgid="1960431123816253034">"为了延长电池的续航时间,节电助手会降低设备的性能,并限制振动、位置信息服务和大部分后台流量。对于电子邮件、聊天工具等依赖于同步功能的应用,可能要打开这类应用时才能收到新信息。\n\n节电助手会在设备充电时自动关闭。"</string> + <string name="battery_saver_description" msgid="1960431123816253034">"为了延长电池的续航时间,省电模式会降低设备的性能,并限制振动、位置信息服务和大部分后台流量。对于电子邮件、聊天工具等依赖于同步功能的应用,可能要打开这类应用时才能收到新信息。\n\n省电模式会在设备充电时自动关闭。"</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> <item quantity="other">%1$d 分钟(到<xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> <item quantity="one">1 分钟(到<xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index 15e9a5e18b8e..28f2bac20af8 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"已根據政策隱藏內容"</string> <string name="safeMode" msgid="2788228061547930246">"安全模式"</string> <string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"切換至個人設定檔"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"切換至工作設定檔"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"通訊錄"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"存取您的通訊錄"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"位置"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"分享"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"拒絕"</string> <string name="select_input_method" msgid="8547250819326693584">"變更鍵盤"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"其他鍵盤"</string> <string name="show_ime" msgid="2506087537466597099">"在實體鍵盤處於連接狀態時保持顯示"</string> <string name="hardware" msgid="194658061510127999">"顯示虛擬鍵盤"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"設定實體鍵盤"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"輕按即可選取語言和鍵盤配置"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index a27f1b76de0d..dfc78902c6f8 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"內容已依據政策隱藏"</string> <string name="safeMode" msgid="2788228061547930246">"安全模式"</string> <string name="android_system_label" msgid="6577375335728551336">"Android 系統"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"切換至個人設定檔"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"切換至公司設定檔"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"聯絡人"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"存取您的聯絡人"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"位置"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"分享"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"拒絕"</string> <string name="select_input_method" msgid="8547250819326693584">"變更鍵盤"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"其他鍵盤"</string> <string name="show_ime" msgid="2506087537466597099">"有連接的實體鍵盤時保持顯示"</string> <string name="hardware" msgid="194658061510127999">"顯示虛擬鍵盤"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"設定實體鍵盤"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"輕觸即可選取語言和版面配置"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"待選項目"</u></string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index 60be8fd9046a..e32f26bf7c89 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -233,10 +233,8 @@ <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Okuqukethwe kufihlwe inqubomgomo"</string> <string name="safeMode" msgid="2788228061547930246">"Imodi ephephile"</string> <string name="android_system_label" msgid="6577375335728551336">"Uhlelo lwe-Android"</string> - <!-- no translation found for user_owner_label (1119010402169916617) --> - <skip /> - <!-- no translation found for managed_profile_label (5289992269827577857) --> - <skip /> + <string name="user_owner_label" msgid="1119010402169916617">"Shintshela komuntu siqu"</string> + <string name="managed_profile_label" msgid="5289992269827577857">"Shintshela kumsebenzi"</string> <string name="permgrouplab_contacts" msgid="3657758145679177612">"Oxhumana nabo"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"finyelela koxhumana nabo"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Indawo"</string> @@ -1063,13 +1061,10 @@ <string name="share_remote_bugreport_action" msgid="6249476773913384948">"YABELANA"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"YENQABA"</string> <string name="select_input_method" msgid="8547250819326693584">"Shintsha ikhibhodi"</string> - <string name="configure_input_methods" msgid="5673193194563164021">"Amanye amakhibhodi"</string> <string name="show_ime" msgid="2506087537466597099">"Yigcine kusikrini ngenkathi kusebenza ikhibhodi ephathekayo"</string> <string name="hardware" msgid="194658061510127999">"Bonisa ikhibhodi ebonakalayo"</string> - <!-- no translation found for select_keyboard_layout_notification_title (597189518763083494) --> - <skip /> - <!-- no translation found for select_keyboard_layout_notification_message (8084622969903004900) --> - <skip /> + <string name="select_keyboard_layout_notification_title" msgid="597189518763083494">"Lungisa ikhibhodi yoqobo"</string> + <string name="select_keyboard_layout_notification_message" msgid="8084622969903004900">"Thepha ukuze ukhethe ulimi nesakhiwo"</string> <string name="fast_scroll_alphabet" msgid="5433275485499039199">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="fast_scroll_numeric_alphabet" msgid="4030170524595123610">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string> <string name="candidates_style" msgid="4333913089637062257"><u>"abahlanganyeli"</u></string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index dbe3dcaa6344..b4371c189d40 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -2504,4 +2504,20 @@ <!-- True if the device requires AppWidgetService even if it does not have the PackageManager.FEATURE_APP_WIDGETS feature --> <bool name="config_enableAppWidgetService">false</bool> + + <!-- True if the device supports Sustained Performance Mode--> + <bool name="config_sustainedPerformanceModeSupported">false</bool> + + <!-- Controls how we deal with externally connected physical keyboards. + 0 - When using this device, it is not clear for users to recognize when the physical + keyboard is (should be) connected and when it is (should be) disconnected. Most of + phones and tablets with Bluetooth keyboard would fall into this category because the + connected Bluetooth keyboard may or may not be nearby the host device. + 1 - When using this device, it is clear for users to recognize when the physical + keyboard is (should be) connected and when it is (should be) disconnected. + Devices with wired USB keyboard is one clear example. Some 2-in-1 convertible + tablets with dedicated keyboards may have the same affordance to wired USB keyboard. + --> + <integer name="config_externalHardKeyboardBehavior">0</integer> + </resources> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 0839187c48d1..6ff7139ecd88 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2716,6 +2716,8 @@ <public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" /> <public type="style" name="Widget.Material.SeekBar.Discrete" /> + <public type="style" name="Widget.Material.CompoundButton.Switch" /> + <public type="style" name="Widget.Material.Light.CompoundButton.Switch" /> <public type="id" name="accessibilityActionSetProgress" /> <public type="id" name="icon_frame" /> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 7d19e99f65eb..2215bd42db1e 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1744,6 +1744,7 @@ <java-symbol type="integer" name="config_defaultNotificationLedOff" /> <java-symbol type="integer" name="config_defaultNotificationLedOn" /> <java-symbol type="integer" name="config_deskDockKeepsScreenOn" /> + <java-symbol type="integer" name="config_externalHardKeyboardBehavior" /> <java-symbol type="integer" name="config_lightSensorWarmupTime" /> <java-symbol type="integer" name="config_lowBatteryCloseWarningBump" /> <java-symbol type="integer" name="config_lowBatteryWarningLevel" /> @@ -2419,13 +2420,11 @@ <java-symbol type="string" name="notification_hidden_text" /> <java-symbol type="string" name="notification_hidden_by_policy_text" /> <java-symbol type="id" name="app_name_text" /> - <java-symbol type="id" name="header_sub_text" /> + <java-symbol type="id" name="header_text" /> <java-symbol type="id" name="expand_button" /> <java-symbol type="id" name="notification_header" /> - <java-symbol type="id" name="header_content_info" /> <java-symbol type="id" name="time_divider" /> - <java-symbol type="id" name="sub_text_divider" /> - <java-symbol type="id" name="content_info_divider" /> + <java-symbol type="id" name="header_text_divider" /> <java-symbol type="id" name="text_line_1" /> <java-symbol type="drawable" name="ic_expand_notification" /> <java-symbol type="drawable" name="ic_collapse_notification" /> @@ -2542,4 +2541,6 @@ <java-symbol type="id" name="textSpacerNoTitle" /> <java-symbol type="id" name="titleDividerNoCustom" /> + + <java-symbol type="bool" name="config_sustainedPerformanceModeSupported" /> </resources> diff --git a/core/res/res/xml/power_profile.xml b/core/res/res/xml/power_profile.xml index 76b5fe1e1b55..2e593a3dc6e8 100644 --- a/core/res/res/xml/power_profile.xml +++ b/core/res/res/xml/power_profile.xml @@ -94,11 +94,27 @@ <!-- This is the battery capacity in mAh (measured at nominal voltage) --> <item name="battery.capacity">1000</item> + <!-- Wifi related values. --> + <!-- Idle Receive current for wifi radio in mA. 0 by default--> + <item name="wifi.controller.idle">0</item> + <!-- Rx current for wifi radio in mA. 0 by default--> + <item name="wifi.controller.rx">0</item> + <!-- Tx current for wifi radio in mA. 0 by default--> + <item name="wifi.controller.tx">0</item> + <!-- Current at each of the wifi Tx levels in mA. The number of tx levels varies per device + and is available only of wifi chipsets which support the tx level reporting. Use + wifi.tx for other chipsets. none by default --> + <array name="wifi.controller.tx_levels"> <!-- mA --> + </array> + <!-- Operating volatage for wifi radio in mV. 0 by default--> + <item name="wifi.controller.voltage">0</item> + <array name="wifi.batchedscan"> <!-- mA --> - <value>.0002</value> <!-- 1-8/hr --> - <value>.002</value> <!-- 9-64/hr --> - <value>.02</value> <!-- 65-512/hr --> - <value>.2</value> <!-- 513-4,096/hr --> - <value>2</value> <!-- 4097-/hr --> + <value>.0002</value> <!-- 1-8/hr --> + <value>.002</value> <!-- 9-64/hr --> + <value>.02</value> <!-- 65-512/hr --> + <value>.2</value> <!-- 513-4,096/hr --> + <value>2</value> <!-- 4097-/hr --> </array> + </device> diff --git a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java index 9ab62cc03bea..e7aca78a0720 100644 --- a/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java +++ b/core/tests/coretests/src/android/net/NetworkScorerAppManagerTest.java @@ -23,10 +23,10 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.content.pm.ServiceInfo; import android.net.NetworkScorerAppManager.NetworkScorerAppData; import android.os.UserHandle; import android.test.InstrumentationTestCase; -import android.util.Pair; import org.mockito.ArgumentMatcher; import org.mockito.Mock; @@ -58,25 +58,26 @@ public class NetworkScorerAppManagerTest extends InstrumentationTestCase { public void testGetAllValidScorers() throws Exception { // Package 1 - Valid scorer. - Pair<ResolveInfo, ResolveInfo> package1 = buildResolveInfo("package1", 1, true, true, - false); + ResolveInfoHolder package1 = buildResolveInfo("package1", 1, true, true, false, false); // Package 2 - Receiver does not have BROADCAST_NETWORK_PRIVILEGED permission. - Pair<ResolveInfo, ResolveInfo> package2 = buildResolveInfo("package2", 2, false, true, - false); + ResolveInfoHolder package2 = buildResolveInfo("package2", 2, false, true, false, false); // Package 3 - App does not have SCORE_NETWORKS permission. - Pair<ResolveInfo, ResolveInfo> package3 = buildResolveInfo("package3", 3, true, false, - false); + ResolveInfoHolder package3 = buildResolveInfo("package3", 3, true, false, false, false); // Package 4 - Valid scorer w/ optional config activity. - Pair<ResolveInfo, ResolveInfo> package4 = buildResolveInfo("package4", 4, true, true, true); + ResolveInfoHolder package4 = buildResolveInfo("package4", 4, true, true, true, false); - List<Pair<ResolveInfo, ResolveInfo>> scorers = new ArrayList<>(); + // Package 5 - Valid scorer w/ optional service to bind to. + ResolveInfoHolder package5 = buildResolveInfo("package5", 5, true, true, false, true); + + List<ResolveInfoHolder> scorers = new ArrayList<>(); scorers.add(package1); scorers.add(package2); scorers.add(package3); scorers.add(package4); + scorers.add(package5); setScorers(scorers); Iterator<NetworkScorerAppData> result = @@ -94,14 +95,20 @@ public class NetworkScorerAppManagerTest extends InstrumentationTestCase { assertEquals(4, next.mPackageUid); assertEquals(".ConfigActivity", next.mConfigurationActivityClassName); + assertTrue(result.hasNext()); + next = result.next(); + assertEquals("package5", next.mPackageName); + assertEquals(5, next.mPackageUid); + assertEquals(".ScoringService", next.mScoringServiceClassName); + assertFalse(result.hasNext()); } - private void setScorers(List<Pair<ResolveInfo, ResolveInfo>> scorers) { + private void setScorers(List<ResolveInfoHolder> scorers) { List<ResolveInfo> receivers = new ArrayList<>(); - for (final Pair<ResolveInfo, ResolveInfo> scorer : scorers) { - receivers.add(scorer.first); - if (scorer.second != null) { + for (final ResolveInfoHolder scorer : scorers) { + receivers.add(scorer.scorerResolveInfo); + if (scorer.configActivityResolveInfo != null) { // This scorer has a config activity. Mockito.when(mMockPm.queryIntentActivities( Mockito.argThat(new ArgumentMatcher<Intent>() { @@ -110,10 +117,26 @@ public class NetworkScorerAppManagerTest extends InstrumentationTestCase { Intent intent = (Intent) object; return NetworkScoreManager.ACTION_CUSTOM_ENABLE.equals( intent.getAction()) - && scorer.first.activityInfo.packageName.equals( + && scorer.scorerResolveInfo.activityInfo.packageName.equals( intent.getPackage()); } - }), Mockito.eq(0))).thenReturn(Collections.singletonList(scorer.second)); + }), Mockito.eq(0))).thenReturn( + Collections.singletonList(scorer.configActivityResolveInfo)); + } + + if (scorer.serviceResolveInfo != null) { + // This scorer has a service to bind to + Mockito.when(mMockPm.resolveService( + Mockito.argThat(new ArgumentMatcher<Intent>() { + @Override + public boolean matches(Object object) { + Intent intent = (Intent) object; + return NetworkScoreManager.ACTION_SCORE_NETWORKS.equals( + intent.getAction()) + && scorer.scorerResolveInfo.activityInfo.packageName.equals( + intent.getPackage()); + } + }), Mockito.eq(0))).thenReturn(scorer.serviceResolveInfo); } } @@ -128,9 +151,9 @@ public class NetworkScorerAppManagerTest extends InstrumentationTestCase { .thenReturn(receivers); } - private Pair<ResolveInfo, ResolveInfo> buildResolveInfo(String packageName, int packageUid, - boolean hasReceiverPermission, boolean hasScorePermission, boolean hasConfigActivity) - throws Exception { + private ResolveInfoHolder buildResolveInfo(String packageName, int packageUid, + boolean hasReceiverPermission, boolean hasScorePermission, boolean hasConfigActivity, + boolean hasServiceInfo) throws Exception { Mockito.when(mMockPm.checkPermission(permission.SCORE_NETWORKS, packageName)) .thenReturn(hasScorePermission ? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED); @@ -150,6 +173,27 @@ public class NetworkScorerAppManagerTest extends InstrumentationTestCase { configActivityInfo.activityInfo = new ActivityInfo(); configActivityInfo.activityInfo.name = ".ConfigActivity"; } - return Pair.create(resolveInfo, configActivityInfo); + + ResolveInfo serviceInfo = null; + if (hasServiceInfo) { + serviceInfo = new ResolveInfo(); + serviceInfo.serviceInfo = new ServiceInfo(); + serviceInfo.serviceInfo.name = ".ScoringService"; + } + + return new ResolveInfoHolder(resolveInfo, configActivityInfo, serviceInfo); + } + + private static class ResolveInfoHolder { + final ResolveInfo scorerResolveInfo; + final ResolveInfo configActivityResolveInfo; + final ResolveInfo serviceResolveInfo; + + public ResolveInfoHolder(ResolveInfo scorerResolveInfo, + ResolveInfo configActivityResolveInfo, ResolveInfo serviceResolveInfo) { + this.scorerResolveInfo = scorerResolveInfo; + this.configActivityResolveInfo = configActivityResolveInfo; + this.serviceResolveInfo = serviceResolveInfo; + } } } diff --git a/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java b/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java index 43a61e301c8f..d491ec4111fb 100644 --- a/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java +++ b/core/tests/coretests/src/android/print/IPrintManagerParametersTest.java @@ -515,7 +515,7 @@ public class IPrintManagerParametersTest extends BasePrintTest { public void testGetPrintServices() throws Exception { List<PrintServiceInfo> printServices = mIPrintManager.getPrintServices( PrintManager.ALL_SERVICES, mUserId); - assertTrue(printServices.size() >= 2); + assertTrue(printServices.size() >= 1); printServices = mIPrintManager.getPrintServices(0, mUserId); assertEquals(printServices, null); diff --git a/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java b/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java index 59ffd566909f..eafe42723780 100644 --- a/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java +++ b/core/tests/coretests/src/android/widget/SuggestionsPopupWindowTest.java @@ -16,13 +16,35 @@ package android.widget; -import android.app.Activity; +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.Espresso.pressBack; +import static android.support.test.espresso.action.ViewActions.clearText; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.replaceText; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.RootMatchers.withDecorView; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; +import static android.widget.espresso.DragHandleUtils.onHandleView; +import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarContainsItem; +import static android.widget.espresso.FloatingToolbarEspressoUtils.clickFloatingToolbarItem; +import static android.widget.espresso.FloatingToolbarEspressoUtils.sleepForFloatingToolbarPopup; +import static android.widget.espresso.SuggestionsPopupwindowUtils.assertSuggestionsPopupContainsItem; +import static android.widget.espresso.SuggestionsPopupwindowUtils.assertSuggestionsPopupIsDisplayed; +import static android.widget.espresso.SuggestionsPopupwindowUtils.assertSuggestionsPopupIsNotDisplayed; +import static android.widget.espresso.SuggestionsPopupwindowUtils.clickSuggestionsPopupItem; +import static android.widget.espresso.SuggestionsPopupwindowUtils.onSuggestionsPopup; +import static android.widget.espresso.TextViewActions.clickOnTextAtIndex; +import static android.widget.espresso.TextViewActions.longPressOnTextAtIndex; +import static org.hamcrest.Matchers.is; import android.content.res.TypedArray; +import android.support.test.espresso.NoMatchingViewException; +import android.support.test.espresso.ViewAssertion; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.SmallTest; import android.test.suitebuilder.annotation.Suppress; import android.text.Selection; -import android.text.SpannableStringBuilder; +import android.text.Spannable; import android.text.Spanned; import android.text.TextPaint; import android.text.style.SuggestionSpan; @@ -42,55 +64,215 @@ public class SuggestionsPopupWindowTest extends ActivityInstrumentationTestCase2 super(TextViewActivity.class); } + @Override + protected void setUp() throws Exception { + super.setUp(); + getActivity(); + } + + private void setSuggestionSpan(SuggestionSpan span, int start, int end) { + final TextView textView = (TextView) getActivity().findViewById(R.id.textview); + textView.post( + () -> { + final Spannable text = (Spannable) textView.getText(); + text.setSpan(span, start, end, Spanned.SPAN_INCLUSIVE_INCLUSIVE); + Selection.setSelection(text, (start + end) / 2); + }); + getInstrumentation().waitForIdleSync(); + } + + @SmallTest + public void testOnTextContextMenuItem() { + final String text = "abc def ghi"; + + onView(withId(R.id.textview)).perform(click()); + onView(withId(R.id.textview)).perform(replaceText(text)); + + final SuggestionSpan suggestionSpan = new SuggestionSpan(getActivity(), + new String[]{"DEF", "Def"}, SuggestionSpan.FLAG_AUTO_CORRECTION); + setSuggestionSpan(suggestionSpan, text.indexOf('d'), text.indexOf('f') + 1); + + final TextView textView = (TextView) getActivity().findViewById(R.id.textview); + textView.post(() -> textView.onTextContextMenuItem(TextView.ID_REPLACE)); + getInstrumentation().waitForIdleSync(); + + assertSuggestionsPopupIsDisplayed(); + } + + @SmallTest + public void testSelectionActionMode() { + final String text = "abc def ghi"; + + onView(withId(R.id.textview)).perform(click()); + onView(withId(R.id.textview)).perform(replaceText(text)); + + final SuggestionSpan suggestionSpan = new SuggestionSpan(getActivity(), + new String[]{"DEF", "Def"}, SuggestionSpan.FLAG_AUTO_CORRECTION); + setSuggestionSpan(suggestionSpan, text.indexOf('d'), text.indexOf('f') + 1); + + onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('e'))); + sleepForFloatingToolbarPopup(); + assertFloatingToolbarContainsItem( + getActivity().getString(com.android.internal.R.string.replace)); + sleepForFloatingToolbarPopup(); + clickFloatingToolbarItem( + getActivity().getString(com.android.internal.R.string.replace)); + + assertSuggestionsPopupIsDisplayed(); + } + + @SmallTest + public void testInsertionActionMode() { + final String text = "abc def ghi"; + + onView(withId(R.id.textview)).perform(click()); + onView(withId(R.id.textview)).perform(replaceText(text)); + + final SuggestionSpan suggestionSpan = new SuggestionSpan(getActivity(), + new String[]{"DEF", "Def"}, SuggestionSpan.FLAG_AUTO_CORRECTION); + setSuggestionSpan(suggestionSpan, text.indexOf('d'), text.indexOf('f') + 1); + + onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.indexOf('e'))); + onHandleView(com.android.internal.R.id.insertion_handle).perform(click()); + sleepForFloatingToolbarPopup(); + assertFloatingToolbarContainsItem( + getActivity().getString(com.android.internal.R.string.replace)); + clickFloatingToolbarItem( + getActivity().getString(com.android.internal.R.string.replace)); + + assertSuggestionsPopupIsDisplayed(); + } + + private void showSuggestionsPopup() { + final TextView textView = (TextView) getActivity().findViewById(R.id.textview); + textView.post(() -> textView.onTextContextMenuItem(TextView.ID_REPLACE)); + getInstrumentation().waitForIdleSync(); + assertSuggestionsPopupIsDisplayed(); + } + + @SmallTest + public void testSuggestionItems() { + final String text = "abc def ghi"; + + onView(withId(R.id.textview)).perform(click()); + onView(withId(R.id.textview)).perform(replaceText(text)); + + final SuggestionSpan suggestionSpan = new SuggestionSpan(getActivity(), + new String[]{"DEF", "Def"}, SuggestionSpan.FLAG_AUTO_CORRECTION); + setSuggestionSpan(suggestionSpan, text.indexOf('d'), text.indexOf('f') + 1); + + showSuggestionsPopup(); + + assertSuggestionsPopupIsDisplayed(); + assertSuggestionsPopupContainsItem("DEF"); + assertSuggestionsPopupContainsItem("Def"); + assertSuggestionsPopupContainsItem( + getActivity().getString(com.android.internal.R.string.delete)); + + // Select an item. + clickSuggestionsPopupItem("DEF"); + assertSuggestionsPopupIsNotDisplayed(); + onView(withId(R.id.textview)).check(matches(withText("abc DEF ghi"))); + + showSuggestionsPopup(); + assertSuggestionsPopupIsDisplayed(); + assertSuggestionsPopupContainsItem("def"); + assertSuggestionsPopupContainsItem("Def"); + assertSuggestionsPopupContainsItem( + getActivity().getString(com.android.internal.R.string.delete)); + + // Delete + clickSuggestionsPopupItem( + getActivity().getString(com.android.internal.R.string.delete)); + assertSuggestionsPopupIsNotDisplayed(); + onView(withId(R.id.textview)).check(matches(withText("abc ghi"))); + } + + @SmallTest + public void testMisspelled() { + final String text = "abc def ghi"; + + onView(withId(R.id.textview)).perform(click()); + onView(withId(R.id.textview)).perform(replaceText(text)); + + final SuggestionSpan suggestionSpan = new SuggestionSpan(getActivity(), + new String[]{"DEF", "Def"}, SuggestionSpan.FLAG_MISSPELLED); + setSuggestionSpan(suggestionSpan, text.indexOf('d'), text.indexOf('f') + 1); + + showSuggestionsPopup(); + + assertSuggestionsPopupIsDisplayed(); + assertSuggestionsPopupContainsItem("DEF"); + assertSuggestionsPopupContainsItem("Def"); + assertSuggestionsPopupContainsItem( + getActivity().getString(com.android.internal.R.string.addToDictionary)); + assertSuggestionsPopupContainsItem( + getActivity().getString(com.android.internal.R.string.delete)); + + // Click "Add to dictionary". + clickSuggestionsPopupItem( + getActivity().getString(com.android.internal.R.string.addToDictionary)); + // TODO: Check if add to dictionary dialog is displayed. + } + + @SmallTest + public void testEasyCorrect() { + final String text = "abc def ghi"; + + onView(withId(R.id.textview)).perform(click()); + onView(withId(R.id.textview)).perform(replaceText(text)); + + final SuggestionSpan suggestionSpan = new SuggestionSpan(getActivity(), + new String[]{"DEF", "Def"}, + SuggestionSpan.FLAG_EASY_CORRECT | SuggestionSpan.FLAG_MISSPELLED); + setSuggestionSpan(suggestionSpan, text.indexOf('d'), text.indexOf('f') + 1); + + onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.indexOf('e'))); + + assertSuggestionsPopupIsDisplayed(); + assertSuggestionsPopupContainsItem("DEF"); + assertSuggestionsPopupContainsItem("Def"); + assertSuggestionsPopupContainsItem( + getActivity().getString(com.android.internal.R.string.delete)); + + // Select an item. + clickSuggestionsPopupItem("DEF"); + assertSuggestionsPopupIsNotDisplayed(); + onView(withId(R.id.textview)).check(matches(withText("abc DEF ghi"))); + + onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.indexOf('e'))); + assertSuggestionsPopupIsNotDisplayed(); + + showSuggestionsPopup(); + assertSuggestionsPopupIsDisplayed(); + assertSuggestionsPopupContainsItem("def"); + assertSuggestionsPopupContainsItem("Def"); + assertSuggestionsPopupContainsItem( + getActivity().getString(com.android.internal.R.string.delete)); + } + @SmallTest - @Suppress public void testTextAppearanceInSuggestionsPopup() { - final Activity activity = getActivity(); + final String text = "abc def ghi"; - final String sampleText = "abc def ghi"; final String[] singleWordCandidates = {"DEF", "Def"}; - final SuggestionSpan singleWordSuggestionSpan = new SuggestionSpan(activity, - singleWordCandidates, SuggestionSpan.FLAG_AUTO_CORRECTION); - final int singleWordSpanStart = 4; - final int singleWordSpanEnd = 7; - + final SuggestionSpan suggestionSpan = new SuggestionSpan(getActivity(), + singleWordCandidates, SuggestionSpan.FLAG_MISSPELLED); final String[] multiWordCandidates = {"ABC DEF GHI", "Abc Def Ghi"}; - final SuggestionSpan multiWordSuggestionSpan = new SuggestionSpan(activity, - multiWordCandidates, SuggestionSpan.FLAG_AUTO_CORRECTION); - final int multiWordSpanStart = 0; - final int multiWordSpanEnd = 11; + final SuggestionSpan multiWordSuggestionSpan = new SuggestionSpan(getActivity(), + multiWordCandidates, SuggestionSpan.FLAG_MISSPELLED); - TypedArray array = activity.obtainStyledAttributes(com.android.internal.R.styleable.Theme); - int id = array.getResourceId( + final TypedArray array = + getActivity().obtainStyledAttributes(com.android.internal.R.styleable.Theme); + final int id = array.getResourceId( com.android.internal.R.styleable.Theme_textEditSuggestionHighlightStyle, 0); array.recycle(); - - TextAppearanceSpan expectedSpan = new TextAppearanceSpan(activity, id); - TextPaint tmpTp = new TextPaint(); + final TextAppearanceSpan expectedSpan = new TextAppearanceSpan(getActivity(), id); + final TextPaint tmpTp = new TextPaint(); expectedSpan.updateDrawState(tmpTp); final int expectedHighlightTextColor = tmpTp.getColor(); final float expectedHighlightTextSize = tmpTp.getTextSize(); - - final EditText editText = (EditText) activity.findViewById(R.id.textview); - final Editor editor = editText.getEditorForTesting(); - assertNotNull(editor); - - // Request to show SuggestionsPopupWindow. - Runnable showSuggestionWindowRunner = new Runnable() { - @Override - public void run() { - SpannableStringBuilder ssb = new SpannableStringBuilder(); - ssb.append(sampleText); - ssb.setSpan(singleWordSuggestionSpan, singleWordSpanStart, singleWordSpanEnd, - Spanned.SPAN_INCLUSIVE_INCLUSIVE); - ssb.setSpan(multiWordSuggestionSpan, multiWordSpanStart, multiWordSpanEnd, - Spanned.SPAN_INCLUSIVE_INCLUSIVE); - editText.setText(ssb); - - Selection.setSelection(editText.getText(), singleWordSpanStart, singleWordSpanEnd); - editText.onTextContextMenuItem(TextView.ID_REPLACE); - } - }; + final TextView textView = (TextView) getActivity().findViewById(R.id.textview); // In this test, the SuggestionsPopupWindow looks like // abc def ghi @@ -103,96 +285,74 @@ public class SuggestionsPopupWindowTest extends ActivityInstrumentationTestCase2 // | DELETE | // ----------------- // *XX* means that XX is highlighted. - Runnable popupVaridator = new Runnable() { - @Override - public void run() { - Editor.SuggestionsPopupWindow popupWindow = - editor.getSuggestionsPopupWindowForTesting(); - assertNotNull(popupWindow); - - LinearLayout linearLayout = (LinearLayout) popupWindow.getContentViewForTesting(); - assertNotNull(linearLayout); - - ListView listView = (ListView)linearLayout.findViewById( - com.android.internal.R.id.suggestionContainer); - assertNotNull(listView); - - int childNum = listView.getChildCount(); - assertEquals(singleWordCandidates.length + multiWordCandidates.length, childNum); - - for (int i = 0; i < singleWordCandidates.length; ++i) { - TextView textView = (TextView) listView.getChildAt(i); - assertNotNull(textView); - - Spanned spanned = (Spanned) textView.getText(); - assertNotNull(spanned); - - // Check that the suggestion item order is kept. - String expectedText = "abc " + singleWordCandidates[i] + " ghi"; - assertEquals(expectedText, spanned.toString()); - - // Check that the text is highlighted with correct color and text size. - TextAppearanceSpan[] taSpan = spanned.getSpans(singleWordSpanStart, - singleWordSpanEnd, TextAppearanceSpan.class); - assertEquals(1, taSpan.length); - TextPaint tp = new TextPaint(); - taSpan[0].updateDrawState(tp); - assertEquals(expectedHighlightTextColor, tp.getColor()); - assertEquals(expectedHighlightTextSize, tp.getTextSize()); - - // Check only center word is highlighted. - assertEquals(singleWordSpanStart, spanned.getSpanStart(taSpan[0])); - assertEquals(singleWordSpanEnd, spanned.getSpanEnd(taSpan[0])); - } + for (int i = 0; i < 2; i++) { + onView(withId(R.id.textview)).perform(click()); + onView(withId(R.id.textview)).perform(replaceText(text)); + setSuggestionSpan(suggestionSpan, text.indexOf('d'), text.indexOf('f') + 1); + setSuggestionSpan(multiWordSuggestionSpan, 0, text.length()); - for (int i = 0; i < multiWordCandidates.length; ++i) { - int indexInListView = singleWordCandidates.length + i; - TextView textView = (TextView) listView.getChildAt(indexInListView); - assertNotNull(textView); - - Spanned spanned = (Spanned) textView.getText(); - assertNotNull(spanned); - - // Check that the suggestion item order is kept. - assertEquals(multiWordCandidates[i], spanned.toString()); - - // Check that the text is highlighted with correct color and text size. - TextAppearanceSpan[] taSpan = spanned.getSpans( - 0, multiWordCandidates[i].length(), TextAppearanceSpan.class); - assertEquals(1, taSpan.length); - TextPaint tp = new TextPaint(); - taSpan[0].updateDrawState(tp); - assertEquals(expectedHighlightTextColor, tp.getColor()); - assertEquals(expectedHighlightTextSize, tp.getTextSize()); - - // Check the whole text is highlighted. - assertEquals(multiWordSpanStart, spanned.getSpanStart(taSpan[0])); - assertEquals(multiWordSpanEnd, spanned.getSpanEnd(taSpan[0])); - } + showSuggestionsPopup(); + assertSuggestionsPopupIsDisplayed(); + assertSuggestionsPopupContainsItem("abc DEF ghi"); + assertSuggestionsPopupContainsItem("abc Def ghi"); + assertSuggestionsPopupContainsItem("ABC DEF GHI"); + assertSuggestionsPopupContainsItem("Abc Def Ghi"); + assertSuggestionsPopupContainsItem( + getActivity().getString(com.android.internal.R.string.delete)); - TextView deleteButton = (TextView)linearLayout.findViewById( - com.android.internal.R.id.deleteButton); - assertEquals(View.VISIBLE, deleteButton.getWindowVisibility()); - } - }; + onSuggestionsPopup().check(new ViewAssertion() { + @Override + public void check(View view, NoMatchingViewException e) { + final ListView listView = (ListView) view.findViewById( + com.android.internal.R.id.suggestionContainer); + assertNotNull(listView); + final int childNum = listView.getChildCount(); + assertEquals(singleWordCandidates.length + multiWordCandidates.length, + childNum); - // Show the SuggestionWindow and verify the contents. - activity.runOnUiThread(showSuggestionWindowRunner); - getInstrumentation().waitForIdleSync(); - activity.runOnUiThread(popupVaridator); - - // Request to hide the SuggestionPopupWindow and wait until it is hidden. - activity.runOnUiThread(new Runnable() { - @Override - public void run() { - editText.setText(""); - } - }); - getInstrumentation().waitForIdleSync(); + for (int j = 0; j < childNum; j++) { + final TextView suggestion = (TextView) listView.getChildAt(j); + assertNotNull(suggestion); + final Spanned spanned = (Spanned) suggestion.getText(); + assertNotNull(spanned); - // Show and verify the contents again. - activity.runOnUiThread(showSuggestionWindowRunner); - getInstrumentation().waitForIdleSync(); - activity.runOnUiThread(popupVaridator); + // Check that the suggestion item order is kept. + final String expectedText; + if (j < singleWordCandidates.length) { + expectedText = "abc " + singleWordCandidates[j] + " ghi"; + } else { + expectedText = multiWordCandidates[j - singleWordCandidates.length]; + } + assertEquals(expectedText, spanned.toString()); + + // Check that the text is highlighted with correct color and text size. + final TextAppearanceSpan[] taSpan = spanned.getSpans( + text.indexOf('d'), text.indexOf('f') + 1, TextAppearanceSpan.class); + assertEquals(1, taSpan.length); + TextPaint tp = new TextPaint(); + taSpan[0].updateDrawState(tp); + assertEquals(expectedHighlightTextColor, tp.getColor()); + assertEquals(expectedHighlightTextSize, tp.getTextSize()); + + // Check the correct part of the text is highlighted. + final int expectedStart; + final int expectedEnd; + if (j < singleWordCandidates.length) { + expectedStart = text.indexOf('d'); + expectedEnd = text.indexOf('f') + 1; + } else { + expectedStart = 0; + expectedEnd = text.length(); + } + assertEquals(expectedStart, spanned.getSpanStart(taSpan[0])); + assertEquals(expectedEnd, spanned.getSpanEnd(taSpan[0])); + } + } + }); + pressBack(); + onView(withId(R.id.textview)) + .inRoot(withDecorView(is(getActivity().getWindow().getDecorView()))) + .perform(clearText()); + } } } diff --git a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java index 923b8299a60a..edb749b95b10 100644 --- a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java +++ b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java @@ -16,6 +16,10 @@ package android.widget; + +import static android.widget.espresso.ContextMenuUtils.assertContextMenuContainsItemDisabled; +import static android.widget.espresso.ContextMenuUtils.assertContextMenuContainsItemEnabled; +import static android.widget.espresso.ContextMenuUtils.assertContextMenuIsNotDisplayed; import static android.widget.espresso.DragHandleUtils.assertNoSelectionHandles; import static android.widget.espresso.DragHandleUtils.onHandleView; import static android.widget.espresso.TextViewActions.mouseClickOnTextAtIndex; @@ -41,11 +45,9 @@ import static android.support.test.espresso.matcher.ViewMatchers.withText; import com.android.frameworks.coretests.R; -import android.support.test.espresso.Espresso; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.SmallTest; import android.view.MotionEvent; -import android.widget.espresso.ContextMenuUtils; /** * Tests mouse interaction of the TextView widget from an Activity @@ -57,7 +59,8 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< } @Override - public void setUp() { + public void setUp() throws Exception { + super.setUp(); getActivity(); } @@ -102,28 +105,28 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< onView(withId(R.id.textview)).perform(click()); onView(withId(R.id.textview)).perform(typeTextIntoFocusedView(text)); - ContextMenuUtils.assertContextMenuIsNotDisplayed(); + assertContextMenuIsNotDisplayed(); onView(withId(R.id.textview)).perform( mouseClickOnTextAtIndex(text.indexOf("d"), MotionEvent.BUTTON_SECONDARY)); - ContextMenuUtils.assertContextMenuContainsItemDisabled( + assertContextMenuContainsItemDisabled( getActivity().getString(com.android.internal.R.string.copy)); - ContextMenuUtils.assertContextMenuContainsItemEnabled( + assertContextMenuContainsItemEnabled( getActivity().getString(com.android.internal.R.string.undo)); // Hide context menu. pressBack(); - ContextMenuUtils.assertContextMenuIsNotDisplayed(); + assertContextMenuIsNotDisplayed(); onView(withId(R.id.textview)).perform( mouseDragOnText(text.indexOf("c"), text.indexOf("h"))); onView(withId(R.id.textview)).perform( mouseClickOnTextAtIndex(text.indexOf("d"), MotionEvent.BUTTON_SECONDARY)); - ContextMenuUtils.assertContextMenuContainsItemEnabled( + assertContextMenuContainsItemEnabled( getActivity().getString(com.android.internal.R.string.copy)); - ContextMenuUtils.assertContextMenuContainsItemEnabled( + assertContextMenuContainsItemEnabled( getActivity().getString(com.android.internal.R.string.undo)); // Hide context menu. @@ -133,9 +136,9 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< onView(withId(R.id.textview)).perform( mouseClickOnTextAtIndex(text.indexOf("i"), MotionEvent.BUTTON_SECONDARY)); - ContextMenuUtils.assertContextMenuContainsItemDisabled( + assertContextMenuContainsItemDisabled( getActivity().getString(com.android.internal.R.string.copy)); - ContextMenuUtils.assertContextMenuContainsItemEnabled( + assertContextMenuContainsItemEnabled( getActivity().getString(com.android.internal.R.string.undo)); // Hide context menu. diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java index f779d6cee976..67ffd2b0ca3b 100644 --- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java +++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java @@ -19,7 +19,6 @@ package android.widget; import static android.support.test.espresso.action.ViewActions.longClick; import static android.widget.espresso.DragHandleUtils.assertNoSelectionHandles; import static android.widget.espresso.DragHandleUtils.onHandleView; -import static android.widget.espresso.FloatingToolbarEspressoUtils.onFloatingToolBarItem; import static android.widget.espresso.TextViewActions.clickOnTextAtIndex; import static android.widget.espresso.TextViewActions.doubleTapAndDragOnText; import static android.widget.espresso.TextViewActions.doubleClickOnTextAtIndex; @@ -31,9 +30,10 @@ import static android.widget.espresso.TextViewAssertions.hasInsertionPointerAtIn import static android.widget.espresso.TextViewAssertions.hasSelection; import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsDisplayed; import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarIsNotDisplayed; -import static android.widget.espresso.FloatingToolbarEspressoUtils.sleepForFloatingToolbarPopup; import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarContainsItem; import static android.widget.espresso.FloatingToolbarEspressoUtils.assertFloatingToolbarDoesNotContainItem; +import static android.widget.espresso.FloatingToolbarEspressoUtils.clickFloatingToolbarItem; +import static android.widget.espresso.FloatingToolbarEspressoUtils.sleepForFloatingToolbarPopup; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.action.ViewActions.pressKey; @@ -67,7 +67,8 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV } @Override - public void setUp() { + public void setUp() throws Exception { + super.setUp(); getActivity(); } @@ -256,7 +257,8 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV onView(withId(R.id.textview)).perform(typeTextIntoFocusedView("test")); onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(1)); - onFloatingToolBarItem(withText(com.android.internal.R.string.cut)).perform(click()); + clickFloatingToolbarItem( + getActivity().getString(com.android.internal.R.string.cut)); onView(withId(R.id.textview)).perform(longClick()); sleepForFloatingToolbarPopup(); @@ -675,4 +677,26 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV assertFloatingToolbarContainsItem( getActivity().getString(com.android.internal.R.string.copy)); } + + @SmallTest + public void testTransientState() throws Exception { + final String text = "abc def"; + onView(withId(R.id.textview)).perform(click()); + onView(withId(R.id.textview)).perform(replaceText(text)); + + final TextView textView = (TextView) getActivity().findViewById(R.id.textview); + assertFalse(textView.hasTransientState()); + + onView(withId(R.id.textview)).perform(longPressOnTextAtIndex(text.indexOf('b'))); + // hasTransientState should return true when user generated selection is active. + assertTrue(textView.hasTransientState()); + onView(withId(R.id.textview)).perform(clickOnTextAtIndex(text.indexOf('d'))); + // hasTransientState should return false as the selection has been cleared. + assertFalse(textView.hasTransientState()); + textView.post( + () -> Selection.setSelection((Spannable) textView.getText(), 0, text.length())); + getInstrumentation().waitForIdleSync(); + // hasTransientState should return false when selection is created by API. + assertFalse(textView.hasTransientState()); + } } diff --git a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java index 0f7f359447ad..838f4db76165 100644 --- a/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java +++ b/core/tests/coretests/src/android/widget/espresso/FloatingToolbarEspressoUtils.java @@ -17,6 +17,7 @@ package android.widget.espresso; import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.assertion.ViewAssertions.matches; import static android.support.test.espresso.matcher.RootMatchers.withDecorView; import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; @@ -24,6 +25,7 @@ import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.isRoot; import static android.support.test.espresso.matcher.ViewMatchers.withTagValue; import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; import static org.hamcrest.Matchers.allOf; import static org.hamcrest.Matchers.is; @@ -34,8 +36,6 @@ import android.support.test.espresso.NoMatchingViewException; import android.support.test.espresso.UiController; import android.support.test.espresso.ViewAction; import android.support.test.espresso.ViewInteraction; -import android.support.test.espresso.action.ViewActions; -import android.support.test.espresso.matcher.ViewMatchers; import android.view.View; import com.android.internal.widget.FloatingToolbar; @@ -90,7 +90,7 @@ public class FloatingToolbarEspressoUtils { final int id = com.android.internal.R.id.overflow; onView(allOf(withId(id), isDisplayed())) .inRoot(withDecorView(hasDescendant(withId(id)))) - .perform(ViewActions.click()); + .perform(click()); onView(isRoot()).perform(SLEEP); } @@ -106,7 +106,7 @@ public class FloatingToolbarEspressoUtils { */ public static void assertFloatingToolbarContainsItem(String itemLabel) { try{ - onFloatingToolBar().check(matches(hasDescendant(ViewMatchers.withText(itemLabel)))); + onFloatingToolBar().check(matches(hasDescendant(withText(itemLabel)))); } catch (AssertionError e) { try{ toggleOverflow(); @@ -115,7 +115,7 @@ public class FloatingToolbarEspressoUtils { throw e; } try{ - onFloatingToolBar().check(matches(hasDescendant(ViewMatchers.withText(itemLabel)))); + onFloatingToolBar().check(matches(hasDescendant(withText(itemLabel)))); } finally { toggleOverflow(); } @@ -138,6 +138,21 @@ public class FloatingToolbarEspressoUtils { } /** + * Click specified item on the floating tool bar. + * + * @param itemLabel label of the item. + */ + public static void clickFloatingToolbarItem(String itemLabel) { + try{ + onFloatingToolBarItem(withText(itemLabel)).check(matches(isDisplayed())); + } catch (AssertionError e) { + // Try to find the item in the overflow menu. + toggleOverflow(); + } + onFloatingToolBarItem(withText(itemLabel)).perform(click()); + } + + /** * ViewAction to sleep to wait floating toolbar's animation. */ private static final ViewAction SLEEP = new ViewAction() { diff --git a/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java b/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java index b8ea2de3abfd..bec4180cc1f4 100644 --- a/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java +++ b/core/tests/coretests/src/android/widget/espresso/MouseClickAction.java @@ -21,7 +21,6 @@ import org.hamcrest.Matcher; import android.support.test.espresso.UiController; import android.support.test.espresso.ViewAction; import android.support.test.espresso.action.CoordinatesProvider; -import android.support.test.espresso.action.GeneralClickAction; import android.support.test.espresso.action.MotionEvents; import android.support.test.espresso.action.MotionEvents.DownResultHolder; import android.support.test.espresso.action.Press; @@ -34,7 +33,7 @@ import android.view.ViewConfiguration; * ViewAction for performing an click on View by a mouse. */ public final class MouseClickAction implements ViewAction { - private final GeneralClickAction mGeneralClickAction; + private final ViewClickAction mViewClickAction; @MouseUiController.MouseButton private final int mButton; @@ -100,30 +99,22 @@ public final class MouseClickAction implements ViewAction { */ public MouseClickAction(Tapper tapper, CoordinatesProvider coordinatesProvider, @MouseUiController.MouseButton int button) { - mGeneralClickAction = new GeneralClickAction(tapper, coordinatesProvider, Press.PINPOINT); + mViewClickAction = new ViewClickAction(tapper, coordinatesProvider, Press.PINPOINT); mButton = button; } @Override public Matcher<View> getConstraints() { - return mGeneralClickAction.getConstraints(); + return mViewClickAction.getConstraints(); } @Override public String getDescription() { - return mGeneralClickAction.getDescription(); + return mViewClickAction.getDescription(); } @Override public void perform(UiController uiController, View view) { - mGeneralClickAction.perform(new MouseUiController(uiController, mButton), view); - long doubleTapTimeout = ViewConfiguration.getDoubleTapTimeout(); - if (0 < doubleTapTimeout) { - // Wait to avoid false gesture detection. Without this wait, consecutive clicks can be - // detected as a triple click. e.g. 2 double clicks are detected as a triple click and - // a single click because espresso isn't aware of triple click detection logic, which - // is TextView specific gesture. - uiController.loopMainThreadForAtLeast(doubleTapTimeout); - } + mViewClickAction.perform(new MouseUiController(uiController, mButton), view); } } diff --git a/core/tests/coretests/src/android/widget/espresso/SuggestionsPopupwindowUtils.java b/core/tests/coretests/src/android/widget/espresso/SuggestionsPopupwindowUtils.java new file mode 100644 index 000000000000..b5a96ae6c49a --- /dev/null +++ b/core/tests/coretests/src/android/widget/espresso/SuggestionsPopupwindowUtils.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2016 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.widget.espresso; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.assertion.ViewAssertions.matches; +import static android.support.test.espresso.matcher.RootMatchers.withDecorView; +import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant; +import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.matcher.ViewMatchers.withText; + +import org.hamcrest.Matcher; + +import android.support.test.espresso.NoMatchingRootException; +import android.support.test.espresso.NoMatchingViewException; +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.support.test.espresso.ViewInteraction; +import android.support.test.espresso.action.GeneralLocation; +import android.support.test.espresso.action.Press; +import android.support.test.espresso.action.Tap; +import android.view.View; + +public final class SuggestionsPopupwindowUtils { + private static final int id = com.android.internal.R.id.suggestionWindowContainer; + + private SuggestionsPopupwindowUtils() {}; + + public static ViewInteraction onSuggestionsPopup() { + return onView(withId(id)).inRoot(withDecorView(hasDescendant(withId(id)))); + } + + private static ViewInteraction onSuggestionsPopupItem(Matcher<View> matcher) { + return onView(matcher).inRoot(withDecorView(hasDescendant(withId(id)))); + } + + /** + * Asserts that the suggestions popup is displayed on screen. + * + * @throws AssertionError if the assertion fails + */ + public static void assertSuggestionsPopupIsDisplayed() { + onSuggestionsPopup().check(matches(isDisplayed())); + } + + /** + * Asserts that the suggestions popup is not displayed on screen. + * + * @throws AssertionError if the assertion fails + */ + public static void assertSuggestionsPopupIsNotDisplayed() { + try { + onSuggestionsPopup().check(matches(isDisplayed())); + } catch (NoMatchingRootException | NoMatchingViewException | AssertionError e) { + return; + } + throw new AssertionError("Suggestions popup is displayed"); + } + + /** + * Asserts that the suggestions popup contains the specified item. + * + * @param itemLabel label of the item. + * @throws AssertionError if the assertion fails + */ + public static void assertSuggestionsPopupContainsItem(String itemLabel) { + onSuggestionsPopupItem(withText(itemLabel)).check(matches(isDisplayed())); + } + + /** + * Click on the specified item in the suggestions popup. + * + * @param itemLabel label of the item. + */ + public static void clickSuggestionsPopupItem(String itemLabel) { + onSuggestionsPopupItem(withText(itemLabel)).perform(new SuggestionItemClickAction()); + } + + /** + * Click action to avoid checking ViewClickAction#getConstraints(). + * TODO: Use Espresso.onData instead of this. + */ + private static final class SuggestionItemClickAction implements ViewAction { + private final ViewClickAction mViewClickAction; + + public SuggestionItemClickAction() { + mViewClickAction = + new ViewClickAction(Tap.SINGLE, GeneralLocation.VISIBLE_CENTER, Press.FINGER); + } + + @Override + public Matcher<View> getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return mViewClickAction.getDescription(); + } + + @Override + public void perform(UiController uiController, View view) { + mViewClickAction.perform(uiController, view); + } + } +} diff --git a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java index 4cecb65f5fa3..335d021efd14 100644 --- a/core/tests/coretests/src/android/widget/espresso/TextViewActions.java +++ b/core/tests/coretests/src/android/widget/espresso/TextViewActions.java @@ -17,15 +17,10 @@ package android.widget.espresso; import static android.support.test.espresso.action.ViewActions.actionWithAssertions; - -import org.hamcrest.core.Is; -import org.hamcrest.core.IsInstanceOf; - import android.graphics.Rect; import android.support.test.espresso.PerformException; import android.support.test.espresso.ViewAction; import android.support.test.espresso.action.CoordinatesProvider; -import android.support.test.espresso.action.GeneralClickAction; import android.support.test.espresso.action.Press; import android.support.test.espresso.action.Tap; import android.support.test.espresso.util.HumanReadables; @@ -55,7 +50,7 @@ public final class TextViewActions { */ public static ViewAction clickOnTextAtIndex(int index) { return actionWithAssertions( - new GeneralClickAction(Tap.SINGLE, new TextCoordinates(index), Press.FINGER)); + new ViewClickAction(Tap.SINGLE, new TextCoordinates(index), Press.FINGER)); } /** @@ -101,7 +96,7 @@ public final class TextViewActions { */ public static ViewAction doubleClickOnTextAtIndex(int index) { return actionWithAssertions( - new GeneralClickAction(Tap.DOUBLE, new TextCoordinates(index), Press.FINGER)); + new ViewClickAction(Tap.DOUBLE, new TextCoordinates(index), Press.FINGER)); } /** @@ -131,7 +126,7 @@ public final class TextViewActions { */ public static ViewAction longPressOnTextAtIndex(int index) { return actionWithAssertions( - new GeneralClickAction(Tap.LONG, new TextCoordinates(index), Press.FINGER)); + new ViewClickAction(Tap.LONG, new TextCoordinates(index), Press.FINGER)); } /** diff --git a/core/tests/coretests/src/android/widget/espresso/ViewClickAction.java b/core/tests/coretests/src/android/widget/espresso/ViewClickAction.java new file mode 100644 index 000000000000..8bce1b09517b --- /dev/null +++ b/core/tests/coretests/src/android/widget/espresso/ViewClickAction.java @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2016 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.widget.espresso; + +import org.hamcrest.Matcher; + +import android.support.test.espresso.UiController; +import android.support.test.espresso.ViewAction; +import android.support.test.espresso.action.CoordinatesProvider; +import android.support.test.espresso.action.GeneralClickAction; +import android.support.test.espresso.action.PrecisionDescriber; +import android.support.test.espresso.action.Tapper; +import android.view.View; +import android.view.ViewConfiguration; + +public final class ViewClickAction implements ViewAction { + private final GeneralClickAction mGeneralClickAction; + + public ViewClickAction(Tapper tapper, CoordinatesProvider coordinatesProvider, + PrecisionDescriber precisionDescriber) { + mGeneralClickAction = new GeneralClickAction(tapper, coordinatesProvider, + precisionDescriber); + } + + @Override + public Matcher<View> getConstraints() { + return mGeneralClickAction.getConstraints(); + } + + @Override + public String getDescription() { + return mGeneralClickAction.getDescription(); + } + + @Override + public void perform(UiController uiController, View view) { + mGeneralClickAction.perform(uiController, view); + long doubleTapTimeout = ViewConfiguration.getDoubleTapTimeout(); + if (0 < doubleTapTimeout) { + // Wait to avoid false gesture detection. Without this wait, consecutive clicks can be + // detected as a double click or triple click. e.g. 2 double clicks on TextView are + // detected as a triple click and a single click because espresso isn't aware of + // TextView specific gestures. + uiController.loopMainThreadForAtLeast(doubleTapTimeout); + } + } +} diff --git a/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java b/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java index 5f36c2d0c29b..3cef33621a01 100644 --- a/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java +++ b/core/tests/utiltests/src/com/android/internal/util/FastXmlSerializerTest.java @@ -16,16 +16,32 @@ package com.android.internal.util; +import android.test.suitebuilder.annotation.LargeTest; +import android.test.suitebuilder.annotation.SmallTest; +import android.util.Log; +import android.util.Xml; + import junit.framework.TestCase; +import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlSerializer; +import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; +import java.nio.charset.StandardCharsets; /** * Tests for {@link FastXmlSerializer} */ +@SmallTest public class FastXmlSerializerTest extends TestCase { + private static final String TAG = "FastXmlSerializerTest"; + + private static final boolean ENABLE_DUMP = false; // DO NOT SUBMIT WITH TRUE. + + private static final String ROOT_TAG = "root"; + private static final String ATTR = "attr"; + public void testEmptyText() throws Exception { final ByteArrayOutputStream stream = new ByteArrayOutputStream(); @@ -44,4 +60,93 @@ public class FastXmlSerializerTest extends TestCase { assertEquals("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n" + "<string name=\"meow\"></string>\n", stream.toString()); } + + private boolean checkPreserved(String description, String str) { + boolean ok = true; + byte[] data; + try (final ByteArrayOutputStream baos = new ByteArrayOutputStream()) { + final XmlSerializer out = new FastXmlSerializer(); + out.setOutput(baos, StandardCharsets.UTF_16.name()); + out.startDocument(null, true); + + out.startTag(null, ROOT_TAG); + out.attribute(null, ATTR, str); + out.text(str); + out.endTag(null, ROOT_TAG); + + out.endDocument(); + baos.flush(); + data = baos.toByteArray(); + } catch (Exception e) { + Log.e(TAG, "Unable to serialize: " + description, e); + return false; + } + + if (ENABLE_DUMP) { + Log.d(TAG, "Dump:"); + Log.d(TAG, new String(data)); + } + + try (final ByteArrayInputStream baos = new ByteArrayInputStream(data)) { + XmlPullParser parser = Xml.newPullParser(); + parser.setInput(baos, StandardCharsets.UTF_16.name()); + + int type; + String tag = null; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { + if (type == XmlPullParser.START_TAG) { + tag = parser.getName(); + if (ROOT_TAG.equals(tag)) { + String read = parser.getAttributeValue(null, ATTR); + if (!str.equals(read)) { + Log.e(TAG, "Attribute not preserved: " + description + + " input=\"" + str + "\", but read=\"" + read + "\""); + ok = false; + } + } + } + if (type == XmlPullParser.TEXT && ROOT_TAG.equals(tag)) { + String read = parser.getText(); + if (!str.equals(parser.getText())) { + Log.e(TAG, "Text not preserved: " + description + + " input=\"" + str + "\", but read=\"" + read + "\""); + ok = false; + } + } + } + } catch (Exception e) { + Log.e(TAG, "Unable to parse: " + description, e); + return false; + } + return ok; + } + + private boolean check(String description, String str) throws Exception { + boolean ok = false; + ok |= checkPreserved(description, str); + ok |= checkPreserved(description + " wrapped with spaces" ," " + str + " "); + return ok; + } + + @LargeTest + public void testAllCharacters() throws Exception { + boolean ok = true; + for (int i = 0; i < 0xffff; i++) { + if (0xd800 <= i && i <= 0xdfff) { + // Surrogate pair characters. + continue; + } + ok &= check("char: " + i, String.valueOf((char) i)); + } + // Dangling surrogate pairs. We can't preserve them. + assertFalse(check("+ud800", "\ud800")); + assertFalse(check("+udc00", "\udc00")); + + for (int i = 0xd800; i < 0xdc00; i ++) { + for (int j = 0xdc00; j < 0xe000; j++) { + ok &= check("char: " + i, String.valueOf((char) i) + String.valueOf((char) j)); + } + } + assertTrue("Some tests failed. See logcat for details.", ok); + } } diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk index e3639ecdeeb8..f4c5b53dd36b 100644 --- a/data/fonts/Android.mk +++ b/data/fonts/Android.mk @@ -108,6 +108,6 @@ CHECK_EMOJI := true endif .PHONY: fontchain_lint -fontchain_lint: $(FONTCHAIN_LINTER) $(TARGET_OUT)/etc/fonts.xml +fontchain_lint: $(FONTCHAIN_LINTER) $(TARGET_OUT)/etc/fonts.xml $(PRODUCT_OUT)/system.img PYTHONPATH=$$PYTHONPATH:external/fonttools/Lib \ python $(FONTCHAIN_LINTER) $(TARGET_OUT) $(CHECK_EMOJI) external/unicode diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java index 3973f2ff428b..aa81b9196fe1 100644 --- a/graphics/java/android/graphics/Outline.java +++ b/graphics/java/android/graphics/Outline.java @@ -37,22 +37,26 @@ import java.lang.annotation.RetentionPolicy; public final class Outline { private static final float RADIUS_UNDEFINED = Float.NEGATIVE_INFINITY; - private static final int MODE_EMPTY = 0; - private static final int MODE_RECT = 1; - private static final int MODE_CONVEX_PATH = 2; + /** @hide */ + public static final int MODE_EMPTY = 0; + /** @hide */ + public static final int MODE_ROUND_RECT = 1; + /** @hide */ + public static final int MODE_CONVEX_PATH = 2; /** @hide */ @Retention(RetentionPolicy.SOURCE) @IntDef(flag = false, value = { MODE_EMPTY, - MODE_RECT, + MODE_ROUND_RECT, MODE_CONVEX_PATH, }) public @interface Mode {} + /** @hide */ @Mode - private int mMode = MODE_EMPTY; + public int mMode = MODE_EMPTY; /** @hide */ public final Path mPath = new Path(); @@ -176,7 +180,7 @@ public final class Outline { return; } - mMode = MODE_RECT; + mMode = MODE_ROUND_RECT; mRect.set(left, top, right, bottom); mRadius = radius; mPath.rewind(); @@ -199,7 +203,7 @@ public final class Outline { * bounds, or {@code false} if no outline bounds are set */ public boolean getRect(@NonNull Rect outRect) { - if (mMode != MODE_RECT) { + if (mMode != MODE_ROUND_RECT) { return false; } outRect.set(mRect); @@ -270,7 +274,7 @@ public final class Outline { * Offsets the Outline by (dx,dy) */ public void offset(int dx, int dy) { - if (mMode == MODE_RECT) { + if (mMode == MODE_ROUND_RECT) { mRect.offset(dx, dy); } else if (mMode == MODE_CONVEX_PATH) { mPath.offset(dx, dy); diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index 46a0f438e8a4..35385ebcd57f 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -1416,6 +1416,9 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { Log.d(LOGTAG, "on finished called from native"); } mStarted = false; + // Invalidate in the end of the animation to make sure the data in + // RT thread is synced back to UI thread. + invalidateOwningView(); if (mListener != null) { mListener.onAnimationEnd(null); } diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp index f43bf860946b..5fb842598046 100644 --- a/libs/hwui/BakedOpDispatcher.cpp +++ b/libs/hwui/BakedOpDispatcher.cpp @@ -809,10 +809,6 @@ void BakedOpDispatcher::onLayerOp(BakedOpRenderer& renderer, const LayerOp& op, Rect(op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight())) .build(); renderer.renderGlop(state, glop); - - if (op.destroy) { - renderer.renderState().layerPool().putOrDelete(buffer); - } } } diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp index 20f102bac351..3c302b3f6c9f 100644 --- a/libs/hwui/BakedOpRenderer.cpp +++ b/libs/hwui/BakedOpRenderer.cpp @@ -37,6 +37,10 @@ OffscreenBuffer* BakedOpRenderer::startTemporaryLayer(uint32_t width, uint32_t h return buffer; } +void BakedOpRenderer::recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) { + mRenderState.layerPool().putOrDelete(offscreenBuffer); +} + void BakedOpRenderer::startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect) { LOG_ALWAYS_FATAL_IF(mRenderTarget.offscreenBuffer, "already has layer..."); diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h index 1b4065aa0aa6..62bc564a4a2a 100644 --- a/libs/hwui/BakedOpRenderer.h +++ b/libs/hwui/BakedOpRenderer.h @@ -69,6 +69,7 @@ public: void startFrame(uint32_t width, uint32_t height, const Rect& repaintRect); void endFrame(const Rect& repaintRect); WARN_UNUSED_RESULT OffscreenBuffer* startTemporaryLayer(uint32_t width, uint32_t height); + void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer); void startRepaintLayer(OffscreenBuffer* offscreenBuffer, const Rect& repaintRect); void endLayer(); WARN_UNUSED_RESULT OffscreenBuffer* copyToLayer(const Rect& area); diff --git a/libs/hwui/DisplayList.cpp b/libs/hwui/DisplayList.cpp index 59f0d7cc7346..181b3433381c 100644 --- a/libs/hwui/DisplayList.cpp +++ b/libs/hwui/DisplayList.cpp @@ -45,6 +45,7 @@ DisplayList::DisplayList() , regions(stdAllocator) , referenceHolders(stdAllocator) , functors(stdAllocator) + , pushStagingFunctors(stdAllocator) , hasDrawOps(false) { } diff --git a/libs/hwui/DisplayList.h b/libs/hwui/DisplayList.h index 60cc7bab64dd..e209e2a896fc 100644 --- a/libs/hwui/DisplayList.h +++ b/libs/hwui/DisplayList.h @@ -110,6 +110,16 @@ struct ReplayStateStruct : public PlaybackStateStruct { }; /** + * Functor that can be used for objects with data in both UI thread and RT to keep the data + * in sync. This functor, when added to DisplayList, will be call during DisplayList sync. + */ +struct PushStagingFunctor { + PushStagingFunctor() {} + virtual ~PushStagingFunctor() {} + virtual void operator ()() {} +}; + +/** * Data structure that holds the list of commands used in display list stream */ class DisplayList { @@ -142,6 +152,7 @@ public: const LsaVector<const SkBitmap*>& getBitmapResources() const { return bitmapResources; } const LsaVector<Functor*>& getFunctors() const { return functors; } + const LsaVector<PushStagingFunctor*>& getPushStagingFunctors() { return pushStagingFunctors; } size_t addChild(NodeOpType* childOp); @@ -183,6 +194,11 @@ private: // List of functors LsaVector<Functor*> functors; + // List of functors that need to be notified of pushStaging. Note that this list gets nothing + // but a callback during sync DisplayList, unlike the list of functors defined above, which + // gets special treatment exclusive for webview. + LsaVector<PushStagingFunctor*> pushStagingFunctors; + bool hasDrawOps; // only used if !HWUI_NEW_OPS void cleanupResources(); diff --git a/libs/hwui/DisplayListCanvas.cpp b/libs/hwui/DisplayListCanvas.cpp index 2dccf32a7c78..c6e92abbe0c3 100644 --- a/libs/hwui/DisplayListCanvas.cpp +++ b/libs/hwui/DisplayListCanvas.cpp @@ -415,7 +415,8 @@ void DisplayListCanvas::drawPoints(const float* points, int count, const SkPaint void DisplayListCanvas::drawVectorDrawable(VectorDrawableRoot* tree) { mDisplayList->ref(tree); - addDrawOp(new (alloc()) DrawVectorDrawableOp(tree)); + mDisplayList->pushStagingFunctors.push_back(tree->getFunctor()); + addDrawOp(new (alloc()) DrawVectorDrawableOp(tree, tree->stagingProperties()->getBounds())); } void DisplayListCanvas::drawGlyphsOnPath(const uint16_t* glyphs, int count, diff --git a/libs/hwui/DisplayListOp.h b/libs/hwui/DisplayListOp.h index 516e6199bd27..59f073ff593c 100644 --- a/libs/hwui/DisplayListOp.h +++ b/libs/hwui/DisplayListOp.h @@ -1110,15 +1110,14 @@ private: class DrawVectorDrawableOp : public DrawOp { public: - DrawVectorDrawableOp(VectorDrawableRoot* tree) - : DrawOp(nullptr), mTree(tree) {} + DrawVectorDrawableOp(VectorDrawableRoot* tree, const SkRect& bounds) + : DrawOp(nullptr), mTree(tree), mDst(bounds) {} virtual void applyDraw(OpenGLRenderer& renderer, Rect& dirty) override { const SkBitmap& bitmap = mTree->getBitmapUpdateIfDirty(); SkPaint* paint = mTree->getPaint(); - const SkRect bounds = mTree->getBounds(); renderer.drawBitmap(&bitmap, Rect(0, 0, bitmap.width(), bitmap.height()), - bounds, paint); + mDst, paint); } virtual void output(int level, uint32_t logFlags) const override { @@ -1129,6 +1128,7 @@ public: private: VectorDrawableRoot* mTree; + SkRect mDst; }; diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp index 9c46c0058f68..0401f2d44776 100644 --- a/libs/hwui/FrameBuilder.cpp +++ b/libs/hwui/FrameBuilder.cpp @@ -522,7 +522,10 @@ static bool hasMergeableClip(const BakedOpState& state) { void FrameBuilder::deferBitmapOp(const BitmapOp& op) { BakedOpState* bakedState = tryBakeOpState(op); if (!bakedState) return; // quick rejected - bakedState->setupOpacity(op.paint); + + if (op.bitmap->isOpaque()) { + bakedState->setupOpacity(op.paint); + } // Don't merge non-simply transformed or neg scale ops, SET_TEXTURE doesn't handle rotation // Don't merge A8 bitmaps - the paint's color isn't compared by mergeId, or in diff --git a/libs/hwui/FrameBuilder.h b/libs/hwui/FrameBuilder.h index e41822729695..039ab6bd88ab 100644 --- a/libs/hwui/FrameBuilder.h +++ b/libs/hwui/FrameBuilder.h @@ -86,6 +86,7 @@ public: */ template <typename StaticDispatcher, typename Renderer> void replayBakedOps(Renderer& renderer) { + std::vector<OffscreenBuffer*> temporaryLayers; finishDefer(); /** * Defines a LUT of lambdas which allow a recorded BakedOpState to use state->op->opId to @@ -129,6 +130,7 @@ public: } else if (!layer.empty()) { // save layer - skip entire layer if empty (in which case, LayerOp has null layer). layer.offscreenBuffer = renderer.startTemporaryLayer(layer.width, layer.height); + temporaryLayers.push_back(layer.offscreenBuffer); GL_CHECKPOINT(MODERATE); layer.replayBakedOpsImpl((void*)&renderer, unmergedReceivers, mergedReceivers); GL_CHECKPOINT(MODERATE); @@ -145,6 +147,10 @@ public: GL_CHECKPOINT(MODERATE); renderer.endFrame(fbo0.repaintRect); } + + for (auto& temporaryLayer : temporaryLayers) { + renderer.recycleTemporaryLayer(temporaryLayer); + } } void dump() const { diff --git a/libs/hwui/PropertyValuesHolder.cpp b/libs/hwui/PropertyValuesHolder.cpp index 8f837f6048d6..0932d653fd5e 100644 --- a/libs/hwui/PropertyValuesHolder.cpp +++ b/libs/hwui/PropertyValuesHolder.cpp @@ -53,7 +53,7 @@ void GroupPropertyValuesHolder::setFraction(float fraction) { } else { animatedValue = mStartValue * (1 - fraction) + mEndValue * fraction; } - mGroup->setPropertyValue(mPropertyId, animatedValue); + mGroup->mutateProperties()->setPropertyValue(mPropertyId, animatedValue); } inline U8CPU lerp(U8CPU fromValue, U8CPU toValue, float fraction) { @@ -72,7 +72,7 @@ SkColor FullPathColorPropertyValuesHolder::interpolateColors(SkColor fromColor, void FullPathColorPropertyValuesHolder::setFraction(float fraction) { SkColor animatedValue = interpolateColors(mStartValue, mEndValue, fraction); - mFullPath->setColorPropertyValue(mPropertyId, animatedValue); + mFullPath->mutateProperties()->setColorPropertyValue(mPropertyId, animatedValue); } void FullPathPropertyValuesHolder::setFraction(float fraction) { @@ -82,17 +82,17 @@ void FullPathPropertyValuesHolder::setFraction(float fraction) { } else { animatedValue = mStartValue * (1 - fraction) + mEndValue * fraction; } - mFullPath->setPropertyValue(mPropertyId, animatedValue); + mFullPath->mutateProperties()->setPropertyValue(mPropertyId, animatedValue); } void PathDataPropertyValuesHolder::setFraction(float fraction) { VectorDrawableUtils::interpolatePaths(&mPathData, mStartValue, mEndValue, fraction); - mPath->setPathData(mPathData); + mPath->mutateProperties()->setData(mPathData); } void RootAlphaPropertyValuesHolder::setFraction(float fraction) { float animatedValue = mStartValue * (1 - fraction) + mEndValue * fraction; - mTree->setRootAlpha(animatedValue); + mTree->mutateProperties()->setRootAlpha(animatedValue); } } // namepace uirenderer diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h index 0271a80d4c17..aee9d6370083 100644 --- a/libs/hwui/RecordedOp.h +++ b/libs/hwui/RecordedOp.h @@ -501,22 +501,20 @@ struct CopyFromLayerOp : RecordedOp { * when creating/tracking a SkPaint* during defer isn't worth the bother. */ struct LayerOp : RecordedOp { - // Records a one-use (saveLayer) layer for drawing. Once drawn, the layer will be destroyed. + // Records a one-use (saveLayer) layer for drawing. LayerOp(BASE_PARAMS, OffscreenBuffer** layerHandle) : SUPER_PAINTLESS(LayerOp) , layerHandle(layerHandle) , alpha(paint ? paint->getAlpha() / 255.0f : 1.0f) , mode(PaintUtils::getXfermodeDirect(paint)) - , colorFilter(paint ? paint->getColorFilter() : nullptr) - , destroy(true) {} + , colorFilter(paint ? paint->getColorFilter() : nullptr) {} LayerOp(RenderNode& node) : RecordedOp(RecordedOpId::LayerOp, Rect(node.getWidth(), node.getHeight()), Matrix4::identity(), nullptr, nullptr) , layerHandle(node.getLayerHandle()) , alpha(node.properties().layerProperties().alpha() / 255.0f) , mode(node.properties().layerProperties().xferMode()) - , colorFilter(node.properties().layerProperties().colorFilter()) - , destroy(false) {} + , colorFilter(node.properties().layerProperties().colorFilter()) {} // Records a handle to the Layer object, since the Layer itself won't be // constructed until after this operation is constructed. @@ -527,9 +525,6 @@ struct LayerOp : RecordedOp { // pointer to object owned by either LayerProperties, or a recorded Paint object in a // BeginLayerOp. Lives longer than LayerOp in either case, so no skia ref counting is used. SkColorFilter* colorFilter; - - // whether to destroy the layer, once rendered - const bool destroy; }; }; // namespace uirenderer diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index 4f9cd688d4b6..b78497d6b6fc 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -430,10 +430,11 @@ void RecordingCanvas::drawPath(const SkPath& path, const SkPaint& paint) { } void RecordingCanvas::drawVectorDrawable(VectorDrawableRoot* tree) { + mDisplayList->pushStagingFunctors.push_back(tree->getFunctor()); mDisplayList->ref(tree); addOp(alloc().create_trivial<VectorDrawableOp>( tree, - Rect(tree->getBounds()), + Rect(tree->stagingProperties()->getBounds()), *(mState.currentSnapshot()->transform), getRecordedClip())); } diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index f6f92f731c1c..957848628059 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -477,6 +477,9 @@ void RenderNode::syncDisplayList(TreeObserver* observer) { for (size_t i = 0; i < mDisplayList->getFunctors().size(); i++) { (*mDisplayList->getFunctors()[i])(DrawGlInfo::kModeSync, nullptr); } + for (size_t i = 0; i < mDisplayList->getPushStagingFunctors().size(); i++) { + (*mDisplayList->getPushStagingFunctors()[i])(); + } } } diff --git a/libs/hwui/RenderProperties.cpp b/libs/hwui/RenderProperties.cpp index f577785110d3..5ebf5458da18 100644 --- a/libs/hwui/RenderProperties.cpp +++ b/libs/hwui/RenderProperties.cpp @@ -155,6 +155,23 @@ void RenderProperties::debugOutputProperties(const int level) const { ALOGD("%*s(ClipRect %d, %d, %d, %d)", level * 2, "", (int)clipRect.left, (int)clipRect.top, (int)clipRect.right, (int)clipRect.bottom); } + + if (getRevealClip().willClip()) { + Rect bounds; + getRevealClip().getBounds(&bounds); + ALOGD("%*s(Clip to reveal clip with bounds %.2f %.2f %.2f %.2f)", level * 2, "", + RECT_ARGS(bounds)); + } + + auto& outline = mPrimitiveFields.mOutline; + if (outline.getShouldClip()) { + if (outline.isEmpty()) { + ALOGD("%*s(Clip to empty outline)", level * 2, ""); + } else if (outline.willClip()) { + ALOGD("%*s(Clip to outline with bounds %.2f %.2f %.2f %.2f)", level * 2, "", + RECT_ARGS(outline.getBounds())); + } + } } void RenderProperties::updateMatrix() { diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp index 5d24fa009f04..1b459c142561 100644 --- a/libs/hwui/SkiaCanvas.cpp +++ b/libs/hwui/SkiaCanvas.cpp @@ -747,11 +747,7 @@ void SkiaCanvas::drawNinePatch(const SkBitmap& bitmap, const Res_png_9patch& chu } void SkiaCanvas::drawVectorDrawable(VectorDrawableRoot* vectorDrawable) { - const SkBitmap& bitmap = vectorDrawable->getBitmapUpdateIfDirty(); - SkRect bounds = vectorDrawable->getBounds(); - drawBitmap(bitmap, 0, 0, bitmap.width(), bitmap.height(), - bounds.fLeft, bounds.fTop, bounds.fRight, bounds.fBottom, - vectorDrawable->getPaint()); + vectorDrawable->drawStaging(this); } // ---------------------------------------------------------------------------- diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp index d35f76485bd1..adfe45c64885 100644 --- a/libs/hwui/VectorDrawable.cpp +++ b/libs/hwui/VectorDrawable.cpp @@ -17,6 +17,7 @@ #include "VectorDrawable.h" #include "PathParser.h" +#include "SkColorFilter.h" #include "SkImageInfo.h" #include "SkShader.h" #include <utils/Log.h> @@ -32,41 +33,36 @@ namespace VectorDrawable { const int Tree::MAX_CACHED_BITMAP_SIZE = 2048; -void Path::draw(SkCanvas* outCanvas, const SkMatrix& groupStackedMatrix, float scaleX, float scaleY) { +void Path::draw(SkCanvas* outCanvas, const SkMatrix& groupStackedMatrix, float scaleX, float scaleY, + bool useStagingData) { float matrixScale = getMatrixScale(groupStackedMatrix); if (matrixScale == 0) { // When either x or y is scaled to 0, we don't need to draw anything. return; } - const SkPath updatedPath = getUpdatedPath(); SkMatrix pathMatrix(groupStackedMatrix); pathMatrix.postScale(scaleX, scaleY); //TODO: try apply the path matrix to the canvas instead of creating a new path. SkPath renderPath; renderPath.reset(); - renderPath.addPath(updatedPath, pathMatrix); + + if (useStagingData) { + SkPath tmpPath; + getStagingPath(&tmpPath); + renderPath.addPath(tmpPath, pathMatrix); + } else { + renderPath.addPath(getUpdatedPath(), pathMatrix); + } float minScale = fmin(scaleX, scaleY); float strokeScale = minScale * matrixScale; - drawPath(outCanvas, renderPath, strokeScale, pathMatrix); -} - -void Path::setPathData(const Data& data) { - if (mData == data) { - return; - } - // Updates the path data. Note that we don't generate a new Skia path right away - // because there are cases where the animation is changing the path data, but the view - // that hosts the VD has gone off screen, in which case we won't even draw. So we - // postpone the Skia path generation to the draw time. - mData = data; - mSkPathDirty = true; + drawPath(outCanvas, renderPath, strokeScale, pathMatrix, useStagingData); } void Path::dump() { - ALOGD("Path: %s has %zu points", mName.c_str(), mData.points.size()); + ALOGD("Path: %s has %zu points", mName.c_str(), mProperties.getData().points.size()); } float Path::getMatrixScale(const SkMatrix& groupStackedMatrix) { @@ -95,213 +91,215 @@ float Path::getMatrixScale(const SkMatrix& groupStackedMatrix) { } return matrixScale; } + +// Called from UI thread during the initial setup/theme change. Path::Path(const char* pathStr, size_t strLength) { PathParser::ParseResult result; - PathParser::getPathDataFromString(&mData, &result, pathStr, strLength); - if (!result.failureOccurred) { - VectorDrawableUtils::verbsToPath(&mSkPath, mData); - } -} - -Path::Path(const Data& data) { - mData = data; - // Now we need to construct a path - VectorDrawableUtils::verbsToPath(&mSkPath, data); + Data data; + PathParser::getPathDataFromString(&data, &result, pathStr, strLength); + mStagingProperties.setData(data); } Path::Path(const Path& path) : Node(path) { - mData = path.mData; - VectorDrawableUtils::verbsToPath(&mSkPath, mData); -} - -bool Path::canMorph(const Data& morphTo) { - return VectorDrawableUtils::canMorph(mData, morphTo); -} - -bool Path::canMorph(const Path& path) { - return canMorph(path.mData); + mStagingProperties.syncProperties(path.mStagingProperties); } const SkPath& Path::getUpdatedPath() { if (mSkPathDirty) { mSkPath.reset(); - VectorDrawableUtils::verbsToPath(&mSkPath, mData); + VectorDrawableUtils::verbsToPath(&mSkPath, mProperties.getData()); mSkPathDirty = false; } return mSkPath; } -void Path::setPath(const char* pathStr, size_t strLength) { - PathParser::ParseResult result; - mSkPathDirty = true; - PathParser::getPathDataFromString(&mData, &result, pathStr, strLength); +void Path::getStagingPath(SkPath* outPath) { + outPath->reset(); + VectorDrawableUtils::verbsToPath(outPath, mStagingProperties.getData()); +} + +void Path::syncProperties() { + if (mStagingPropertiesDirty) { + mProperties.syncProperties(mStagingProperties); + } else { + mStagingProperties.syncProperties(mProperties); + } + mStagingPropertiesDirty = false; } FullPath::FullPath(const FullPath& path) : Path(path) { - mProperties = path.mProperties; - SkRefCnt_SafeAssign(mStrokeGradient, path.mStrokeGradient); - SkRefCnt_SafeAssign(mFillGradient, path.mFillGradient); + mStagingProperties.syncProperties(path.mStagingProperties); +} + +static void applyTrim(SkPath* outPath, const SkPath& inPath, float trimPathStart, float trimPathEnd, + float trimPathOffset) { + if (trimPathStart == 0.0f && trimPathEnd == 1.0f) { + *outPath = inPath; + return; + } + outPath->reset(); + if (trimPathStart == trimPathEnd) { + // Trimmed path should be empty. + return; + } + SkPathMeasure measure(inPath, false); + float len = SkScalarToFloat(measure.getLength()); + float start = len * fmod((trimPathStart + trimPathOffset), 1.0f); + float end = len * fmod((trimPathEnd + trimPathOffset), 1.0f); + + if (start > end) { + measure.getSegment(start, len, outPath, true); + if (end > 0) { + measure.getSegment(0, end, outPath, true); + } + } else { + measure.getSegment(start, end, outPath, true); + } } const SkPath& FullPath::getUpdatedPath() { - if (!mSkPathDirty && !mTrimDirty) { + if (!mSkPathDirty && !mProperties.mTrimDirty) { return mTrimmedSkPath; } Path::getUpdatedPath(); - if (mProperties.trimPathStart != 0.0f || mProperties.trimPathEnd != 1.0f) { - applyTrim(); + if (mProperties.getTrimPathStart() != 0.0f || mProperties.getTrimPathEnd() != 1.0f) { + mProperties.mTrimDirty = false; + applyTrim(&mTrimmedSkPath, mSkPath, mProperties.getTrimPathStart(), + mProperties.getTrimPathEnd(), mProperties.getTrimPathOffset()); return mTrimmedSkPath; } else { return mSkPath; } } -void FullPath::updateProperties(float strokeWidth, SkColor strokeColor, float strokeAlpha, - SkColor fillColor, float fillAlpha, float trimPathStart, float trimPathEnd, - float trimPathOffset, float strokeMiterLimit, int strokeLineCap, int strokeLineJoin, - int fillType) { - mProperties.strokeWidth = strokeWidth; - mProperties.strokeColor = strokeColor; - mProperties.strokeAlpha = strokeAlpha; - mProperties.fillColor = fillColor; - mProperties.fillAlpha = fillAlpha; - mProperties.strokeMiterLimit = strokeMiterLimit; - mProperties.strokeLineCap = strokeLineCap; - mProperties.strokeLineJoin = strokeLineJoin; - mProperties.fillType = fillType; +void FullPath::getStagingPath(SkPath* outPath) { + Path::getStagingPath(outPath); + SkPath inPath = *outPath; + applyTrim(outPath, inPath, mStagingProperties.getTrimPathStart(), + mStagingProperties.getTrimPathEnd(), mStagingProperties.getTrimPathOffset()); +} - // If any trim property changes, mark trim dirty and update the trim path - setTrimPathStart(trimPathStart); - setTrimPathEnd(trimPathEnd); - setTrimPathOffset(trimPathOffset); +void FullPath::dump() { + Path::dump(); + ALOGD("stroke width, color, alpha: %f, %d, %f, fill color, alpha: %d, %f", + mProperties.getStrokeWidth(), mProperties.getStrokeColor(), mProperties.getStrokeAlpha(), + mProperties.getFillColor(), mProperties.getFillAlpha()); } + inline SkColor applyAlpha(SkColor color, float alpha) { int alphaBytes = SkColorGetA(color); return SkColorSetA(color, alphaBytes * alpha); } void FullPath::drawPath(SkCanvas* outCanvas, SkPath& renderPath, float strokeScale, - const SkMatrix& matrix){ + const SkMatrix& matrix, bool useStagingData){ + const FullPathProperties& properties = useStagingData ? mStagingProperties : mProperties; + // Draw path's fill, if fill color or gradient is valid bool needsFill = false; - if (mFillGradient != nullptr) { - mPaint.setColor(applyAlpha(SK_ColorBLACK, mProperties.fillAlpha)); - SkShader* newShader = mFillGradient->newWithLocalMatrix(matrix); - mPaint.setShader(newShader); + SkPaint paint; + if (properties.getFillGradient() != nullptr) { + paint.setColor(applyAlpha(SK_ColorBLACK, properties.getFillAlpha())); + SkShader* newShader = properties.getFillGradient()->newWithLocalMatrix(matrix); + paint.setShader(newShader); needsFill = true; - } else if (mProperties.fillColor != SK_ColorTRANSPARENT) { - mPaint.setColor(applyAlpha(mProperties.fillColor, mProperties.fillAlpha)); + } else if (properties.getFillColor() != SK_ColorTRANSPARENT) { + paint.setColor(applyAlpha(properties.getFillColor(), properties.getFillAlpha())); needsFill = true; } if (needsFill) { - mPaint.setStyle(SkPaint::Style::kFill_Style); - mPaint.setAntiAlias(true); - SkPath::FillType ft = static_cast<SkPath::FillType>(mProperties.fillType); + paint.setStyle(SkPaint::Style::kFill_Style); + paint.setAntiAlias(true); + SkPath::FillType ft = static_cast<SkPath::FillType>(properties.getFillType()); renderPath.setFillType(ft); - outCanvas->drawPath(renderPath, mPaint); + outCanvas->drawPath(renderPath, paint); } - // Draw path's stroke, if stroke color or gradient is valid + // Draw path's stroke, if stroke color or Gradient is valid bool needsStroke = false; - if (mStrokeGradient != nullptr) { - mPaint.setColor(applyAlpha(SK_ColorBLACK, mProperties.strokeAlpha)); - SkShader* newShader = mStrokeGradient->newWithLocalMatrix(matrix); - mPaint.setShader(newShader); + if (properties.getStrokeGradient() != nullptr) { + paint.setColor(applyAlpha(SK_ColorBLACK, properties.getStrokeAlpha())); + SkShader* newShader = properties.getStrokeGradient()->newWithLocalMatrix(matrix); + paint.setShader(newShader); needsStroke = true; - } else if (mProperties.strokeColor != SK_ColorTRANSPARENT) { - mPaint.setColor(applyAlpha(mProperties.strokeColor, mProperties.strokeAlpha)); + } else if (properties.getStrokeColor() != SK_ColorTRANSPARENT) { + paint.setColor(applyAlpha(properties.getStrokeColor(), properties.getStrokeAlpha())); needsStroke = true; } if (needsStroke) { - mPaint.setStyle(SkPaint::Style::kStroke_Style); - mPaint.setAntiAlias(true); - mPaint.setStrokeJoin(SkPaint::Join(mProperties.strokeLineJoin)); - mPaint.setStrokeCap(SkPaint::Cap(mProperties.strokeLineCap)); - mPaint.setStrokeMiter(mProperties.strokeMiterLimit); - mPaint.setStrokeWidth(mProperties.strokeWidth * strokeScale); - outCanvas->drawPath(renderPath, mPaint); + paint.setStyle(SkPaint::Style::kStroke_Style); + paint.setAntiAlias(true); + paint.setStrokeJoin(SkPaint::Join(properties.getStrokeLineJoin())); + paint.setStrokeCap(SkPaint::Cap(properties.getStrokeLineCap())); + paint.setStrokeMiter(properties.getStrokeMiterLimit()); + paint.setStrokeWidth(properties.getStrokeWidth() * strokeScale); + outCanvas->drawPath(renderPath, paint); } } -/** - * Applies trimming to the specified path. - */ -void FullPath::applyTrim() { - if (mProperties.trimPathStart == 0.0f && mProperties.trimPathEnd == 1.0f) { - // No trimming necessary. - return; - } - mTrimDirty = false; - mTrimmedSkPath.reset(); - if (mProperties.trimPathStart == mProperties.trimPathEnd) { - // Trimmed path should be empty. - return; - } - SkPathMeasure measure(mSkPath, false); - float len = SkScalarToFloat(measure.getLength()); - float start = len * fmod((mProperties.trimPathStart + mProperties.trimPathOffset), 1.0f); - float end = len * fmod((mProperties.trimPathEnd + mProperties.trimPathOffset), 1.0f); +void FullPath::syncProperties() { + Path::syncProperties(); - if (start > end) { - measure.getSegment(start, len, &mTrimmedSkPath, true); - if (end > 0) { - measure.getSegment(0, end, &mTrimmedSkPath, true); - } + if (mStagingPropertiesDirty) { + mProperties.syncProperties(mStagingProperties); } else { - measure.getSegment(start, end, &mTrimmedSkPath, true); + // Update staging property with property values from animation. + mStagingProperties.syncProperties(mProperties); } + mStagingPropertiesDirty = false; } -REQUIRE_COMPATIBLE_LAYOUT(FullPath::Properties); +REQUIRE_COMPATIBLE_LAYOUT(FullPath::FullPathProperties::PrimitiveFields); static_assert(sizeof(float) == sizeof(int32_t), "float is not the same size as int32_t"); static_assert(sizeof(SkColor) == sizeof(int32_t), "SkColor is not the same size as int32_t"); -bool FullPath::getProperties(int8_t* outProperties, int length) { - int propertyDataSize = sizeof(Properties); +bool FullPath::FullPathProperties::copyProperties(int8_t* outProperties, int length) const { + int propertyDataSize = sizeof(FullPathProperties::PrimitiveFields); if (length != propertyDataSize) { LOG_ALWAYS_FATAL("Properties needs exactly %d bytes, a byte array of size %d is provided", propertyDataSize, length); return false; } - Properties* out = reinterpret_cast<Properties*>(outProperties); - *out = mProperties; + + PrimitiveFields* out = reinterpret_cast<PrimitiveFields*>(outProperties); + *out = mPrimitiveFields; return true; } -void FullPath::setColorPropertyValue(int propertyId, int32_t value) { +void FullPath::FullPathProperties::setColorPropertyValue(int propertyId, int32_t value) { Property currentProperty = static_cast<Property>(propertyId); - if (currentProperty == Property::StrokeColor) { - mProperties.strokeColor = value; - } else if (currentProperty == Property::FillColor) { - mProperties.fillColor = value; + if (currentProperty == Property::strokeColor) { + setStrokeColor(value); + } else if (currentProperty == Property::fillColor) { + setFillColor(value); } else { - LOG_ALWAYS_FATAL("Error setting color property on FullPath: No valid property with id: %d", - propertyId); + LOG_ALWAYS_FATAL("Error setting color property on FullPath: No valid property" + " with id: %d", propertyId); } } -void FullPath::setPropertyValue(int propertyId, float value) { +void FullPath::FullPathProperties::setPropertyValue(int propertyId, float value) { Property property = static_cast<Property>(propertyId); switch (property) { - case Property::StrokeWidth: + case Property::strokeWidth: setStrokeWidth(value); break; - case Property::StrokeAlpha: + case Property::strokeAlpha: setStrokeAlpha(value); break; - case Property::FillAlpha: + case Property::fillAlpha: setFillAlpha(value); break; - case Property::TrimPathStart: + case Property::trimPathStart: setTrimPathStart(value); break; - case Property::TrimPathEnd: + case Property::trimPathEnd: setTrimPathEnd(value); break; - case Property::TrimPathOffset: + case Property::trimPathOffset: setTrimPathOffset(value); break; default: @@ -311,16 +309,16 @@ void FullPath::setPropertyValue(int propertyId, float value) { } void ClipPath::drawPath(SkCanvas* outCanvas, SkPath& renderPath, - float strokeScale, const SkMatrix& matrix){ + float strokeScale, const SkMatrix& matrix, bool useStagingData){ outCanvas->clipPath(renderPath, SkRegion::kIntersect_Op); } Group::Group(const Group& group) : Node(group) { - mProperties = group.mProperties; + mStagingProperties.syncProperties(group.mStagingProperties); } void Group::draw(SkCanvas* outCanvas, const SkMatrix& currentMatrix, float scaleX, - float scaleY) { + float scaleY, bool useStagingData) { // TODO: Try apply the matrix to the canvas instead of passing it down the tree // Calculate current group's matrix by preConcat the parent's and @@ -328,14 +326,15 @@ void Group::draw(SkCanvas* outCanvas, const SkMatrix& currentMatrix, float scale // Basically the Mfinal = Mviewport * M0 * M1 * M2; // Mi the local matrix at level i of the group tree. SkMatrix stackedMatrix; - getLocalMatrix(&stackedMatrix); + const GroupProperties& prop = useStagingData ? mStagingProperties : mProperties; + getLocalMatrix(&stackedMatrix, prop); stackedMatrix.postConcat(currentMatrix); // Save the current clip information, which is local to this group. outCanvas->save(); // Draw the group tree in the same order as the XML file. for (auto& child : mChildren) { - child->draw(outCanvas, stackedMatrix, scaleX, scaleY); + child->draw(outCanvas, stackedMatrix, scaleX, scaleY, useStagingData); } // Restore the previous clip information. outCanvas->restore(); @@ -343,96 +342,106 @@ void Group::draw(SkCanvas* outCanvas, const SkMatrix& currentMatrix, float scale void Group::dump() { ALOGD("Group %s has %zu children: ", mName.c_str(), mChildren.size()); + ALOGD("Group translateX, Y : %f, %f, scaleX, Y: %f, %f", mProperties.getTranslateX(), + mProperties.getTranslateY(), mProperties.getScaleX(), mProperties.getScaleY()); for (size_t i = 0; i < mChildren.size(); i++) { mChildren[i]->dump(); } } -void Group::updateLocalMatrix(float rotate, float pivotX, float pivotY, - float scaleX, float scaleY, float translateX, float translateY) { - setRotation(rotate); - setPivotX(pivotX); - setPivotY(pivotY); - setScaleX(scaleX); - setScaleY(scaleY); - setTranslateX(translateX); - setTranslateY(translateY); +void Group::syncProperties() { + // Copy over the dirty staging properties + if (mStagingPropertiesDirty) { + mProperties.syncProperties(mStagingProperties); + } else { + mStagingProperties.syncProperties(mProperties); + } + mStagingPropertiesDirty = false; + for (auto& child : mChildren) { + child->syncProperties(); + } } -void Group::getLocalMatrix(SkMatrix* outMatrix) { +void Group::getLocalMatrix(SkMatrix* outMatrix, const GroupProperties& properties) { outMatrix->reset(); // TODO: use rotate(mRotate, mPivotX, mPivotY) and scale with pivot point, instead of // translating to pivot for rotating and scaling, then translating back. - outMatrix->postTranslate(-mProperties.pivotX, -mProperties.pivotY); - outMatrix->postScale(mProperties.scaleX, mProperties.scaleY); - outMatrix->postRotate(mProperties.rotate, 0, 0); - outMatrix->postTranslate(mProperties.translateX + mProperties.pivotX, - mProperties.translateY + mProperties.pivotY); + outMatrix->postTranslate(-properties.getPivotX(), -properties.getPivotY()); + outMatrix->postScale(properties.getScaleX(), properties.getScaleY()); + outMatrix->postRotate(properties.getRotation(), 0, 0); + outMatrix->postTranslate(properties.getTranslateX() + properties.getPivotX(), + properties.getTranslateY() + properties.getPivotY()); } void Group::addChild(Node* child) { mChildren.emplace_back(child); + if (mPropertyChangedListener != nullptr) { + child->setPropertyChangedListener(mPropertyChangedListener); + } } -bool Group::getProperties(float* outProperties, int length) { - int propertyCount = static_cast<int>(Property::Count); +bool Group::GroupProperties::copyProperties(float* outProperties, int length) const { + int propertyCount = static_cast<int>(Property::count); if (length != propertyCount) { LOG_ALWAYS_FATAL("Properties needs exactly %d bytes, a byte array of size %d is provided", propertyCount, length); return false; } - Properties* out = reinterpret_cast<Properties*>(outProperties); - *out = mProperties; + + PrimitiveFields* out = reinterpret_cast<PrimitiveFields*>(outProperties); + *out = mPrimitiveFields; return true; } // TODO: Consider animating the properties as float pointers -float Group::getPropertyValue(int propertyId) const { +// Called on render thread +float Group::GroupProperties::getPropertyValue(int propertyId) const { Property currentProperty = static_cast<Property>(propertyId); switch (currentProperty) { - case Property::Rotate: - return mProperties.rotate; - case Property::PivotX: - return mProperties.pivotX; - case Property::PivotY: - return mProperties.pivotY; - case Property::ScaleX: - return mProperties.scaleX; - case Property::ScaleY: - return mProperties.scaleY; - case Property::TranslateX: - return mProperties.translateX; - case Property::TranslateY: - return mProperties.translateY; + case Property::rotate: + return getRotation(); + case Property::pivotX: + return getPivotX(); + case Property::pivotY: + return getPivotY(); + case Property::scaleX: + return getScaleX(); + case Property::scaleY: + return getScaleY(); + case Property::translateX: + return getTranslateX(); + case Property::translateY: + return getTranslateY(); default: LOG_ALWAYS_FATAL("Invalid property index: %d", propertyId); return 0; } } -void Group::setPropertyValue(int propertyId, float value) { +// Called on render thread +void Group::GroupProperties::setPropertyValue(int propertyId, float value) { Property currentProperty = static_cast<Property>(propertyId); switch (currentProperty) { - case Property::Rotate: - mProperties.rotate = value; + case Property::rotate: + setRotation(value); break; - case Property::PivotX: - mProperties.pivotX = value; + case Property::pivotX: + setPivotX(value); break; - case Property::PivotY: - mProperties.pivotY = value; + case Property::pivotY: + setPivotY(value); break; - case Property::ScaleX: - mProperties.scaleX = value; + case Property::scaleX: + setScaleX(value); break; - case Property::ScaleY: - mProperties.scaleY = value; + case Property::scaleY: + setScaleY(value); break; - case Property::TranslateX: - mProperties.translateX = value; + case Property::translateX: + setTranslateX(value); break; - case Property::TranslateY: - mProperties.translateY = value; + case Property::translateY: + setTranslateY(value); break; default: LOG_ALWAYS_FATAL("Invalid property index: %d", propertyId); @@ -440,7 +449,11 @@ void Group::setPropertyValue(int propertyId, float value) { } bool Group::isValidProperty(int propertyId) { - return propertyId >= 0 && propertyId < static_cast<int>(Property::Count); + return GroupProperties::isValidProperty(propertyId); +} + +bool Group::GroupProperties::isValidProperty(int propertyId) { + return propertyId >= 0 && propertyId < static_cast<int>(Property::count); } void Tree::draw(Canvas* outCanvas, SkColorFilter* colorFilter, @@ -449,18 +462,18 @@ void Tree::draw(Canvas* outCanvas, SkColorFilter* colorFilter, // avoid blurry scaling, we have to draw into a bitmap with exact pixel // size first. This bitmap size is determined by the bounds and the // canvas scale. - outCanvas->getMatrix(&mCanvasMatrix); - mBounds = bounds; + SkMatrix canvasMatrix; + outCanvas->getMatrix(&canvasMatrix); float canvasScaleX = 1.0f; float canvasScaleY = 1.0f; - if (mCanvasMatrix.getSkewX() == 0 && mCanvasMatrix.getSkewY() == 0) { + if (canvasMatrix.getSkewX() == 0 && canvasMatrix.getSkewY() == 0) { // Only use the scale value when there's no skew or rotation in the canvas matrix. // TODO: Add a cts test for drawing VD on a canvas with negative scaling factors. - canvasScaleX = fabs(mCanvasMatrix.getScaleX()); - canvasScaleY = fabs(mCanvasMatrix.getScaleY()); + canvasScaleX = fabs(canvasMatrix.getScaleX()); + canvasScaleY = fabs(canvasMatrix.getScaleY()); } - int scaledWidth = (int) (mBounds.width() * canvasScaleX); - int scaledHeight = (int) (mBounds.height() * canvasScaleY); + int scaledWidth = (int) (bounds.width() * canvasScaleX); + int scaledHeight = (int) (bounds.height() * canvasScaleY); scaledWidth = std::min(Tree::MAX_CACHED_BITMAP_SIZE, scaledWidth); scaledHeight = std::min(Tree::MAX_CACHED_BITMAP_SIZE, scaledHeight); @@ -468,63 +481,105 @@ void Tree::draw(Canvas* outCanvas, SkColorFilter* colorFilter, return; } - mPaint.setColorFilter(colorFilter); - + mStagingProperties.setScaledSize(scaledWidth, scaledHeight); int saveCount = outCanvas->save(SaveFlags::MatrixClip); - outCanvas->translate(mBounds.fLeft, mBounds.fTop); + outCanvas->translate(bounds.fLeft, bounds.fTop); // Handle RTL mirroring. if (needsMirroring) { - outCanvas->translate(mBounds.width(), 0); + outCanvas->translate(bounds.width(), 0); outCanvas->scale(-1.0f, 1.0f); } + mStagingProperties.setColorFilter(colorFilter); // At this point, canvas has been translated to the right position. // And we use this bound for the destination rect for the drawBitmap, so // we offset to (0, 0); - mBounds.offsetTo(0, 0); - createCachedBitmapIfNeeded(scaledWidth, scaledHeight); - + SkRect tmpBounds = bounds; + tmpBounds.offsetTo(0, 0); + mStagingProperties.setBounds(tmpBounds); outCanvas->drawVectorDrawable(this); - outCanvas->restoreToCount(saveCount); } +void Tree::drawStaging(Canvas* outCanvas) { + bool redrawNeeded = allocateBitmapIfNeeded(&mStagingCache.bitmap, + mStagingProperties.getScaledWidth(), mStagingProperties.getScaledHeight()); + // draw bitmap cache + if (redrawNeeded || mStagingCache.dirty) { + updateBitmapCache(&mStagingCache.bitmap, true); + mStagingCache.dirty = false; + } + + SkPaint tmpPaint; + SkPaint* paint = updatePaint(&tmpPaint, &mStagingProperties); + outCanvas->drawBitmap(mStagingCache.bitmap, 0, 0, + mStagingCache.bitmap.width(), mStagingCache.bitmap.height(), + mStagingProperties.getBounds().left(), mStagingProperties.getBounds().top(), + mStagingProperties.getBounds().right(), mStagingProperties.getBounds().bottom(), paint); +} + SkPaint* Tree::getPaint() { - SkPaint* paint; - if (mRootAlpha == 1.0f && mPaint.getColorFilter() == NULL) { - paint = NULL; + return updatePaint(&mPaint, &mProperties); +} + +// Update the given paint with alpha and color filter. Return nullptr if no color filter is +// specified and root alpha is 1. Otherwise, return updated paint. +SkPaint* Tree::updatePaint(SkPaint* outPaint, TreeProperties* prop) { + if (prop->getRootAlpha() == 1.0f && prop->getColorFilter() == nullptr) { + return nullptr; } else { - mPaint.setFilterQuality(kLow_SkFilterQuality); - mPaint.setAlpha(mRootAlpha * 255); - paint = &mPaint; + outPaint->setColorFilter(mStagingProperties.getColorFilter()); + outPaint->setFilterQuality(kLow_SkFilterQuality); + outPaint->setAlpha(prop->getRootAlpha() * 255); + return outPaint; } - return paint; } const SkBitmap& Tree::getBitmapUpdateIfDirty() { - mCachedBitmap.eraseColor(SK_ColorTRANSPARENT); - SkCanvas outCanvas(mCachedBitmap); - float scaleX = (float) mCachedBitmap.width() / mViewportWidth; - float scaleY = (float) mCachedBitmap.height() / mViewportHeight; - mRootNode->draw(&outCanvas, SkMatrix::I(), scaleX, scaleY); - mCacheDirty = false; - return mCachedBitmap; + bool redrawNeeded = allocateBitmapIfNeeded(&mCache.bitmap, mProperties.getScaledWidth(), + mProperties.getScaledHeight()); + if (redrawNeeded || mCache.dirty) { + updateBitmapCache(&mCache.bitmap, false); + mCache.dirty = false; + } + return mCache.bitmap; +} + +void Tree::updateBitmapCache(SkBitmap* outCache, bool useStagingData) { + outCache->eraseColor(SK_ColorTRANSPARENT); + SkCanvas outCanvas(*outCache); + float viewportWidth = useStagingData ? + mStagingProperties.getViewportWidth() : mProperties.getViewportWidth(); + float viewportHeight = useStagingData ? + mStagingProperties.getViewportHeight() : mProperties.getViewportHeight(); + float scaleX = outCache->width() / viewportWidth; + float scaleY = outCache->height() / viewportHeight; + mRootNode->draw(&outCanvas, SkMatrix::I(), scaleX, scaleY, useStagingData); } -void Tree::createCachedBitmapIfNeeded(int width, int height) { - if (!canReuseBitmap(width, height)) { +bool Tree::allocateBitmapIfNeeded(SkBitmap* outCache, int width, int height) { + if (!canReuseBitmap(*outCache, width, height)) { SkImageInfo info = SkImageInfo::Make(width, height, kN32_SkColorType, kPremul_SkAlphaType); - mCachedBitmap.setInfo(info); + outCache->setInfo(info); // TODO: Count the bitmap cache against app's java heap - mCachedBitmap.allocPixels(info); - mCacheDirty = true; + outCache->allocPixels(info); + return true; } + return false; } -bool Tree::canReuseBitmap(int width, int height) { - return width == mCachedBitmap.width() && height == mCachedBitmap.height(); +bool Tree::canReuseBitmap(const SkBitmap& bitmap, int width, int height) { + return width == bitmap.width() && height == bitmap.height(); +} + +void Tree::onPropertyChanged(TreeProperties* prop) { + if (prop == &mStagingProperties) { + mStagingCache.dirty = true; + } else { + mCache.dirty = true; + } } }; // namespace VectorDrawable diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h index 7a45bf5ca8a8..e4c7ed71f361 100644 --- a/libs/hwui/VectorDrawable.h +++ b/libs/hwui/VectorDrawable.h @@ -18,9 +18,11 @@ #define ANDROID_HWUI_VPATH_H #include "hwui/Canvas.h" +#include "DisplayList.h" #include <SkBitmap.h> #include <SkColor.h> +#include <SkColorFilter.h> #include <SkCanvas.h> #include <SkMatrix.h> #include <SkPaint.h> @@ -38,8 +40,11 @@ namespace android { namespace uirenderer { namespace VectorDrawable { -#define VD_SET_PROP_WITH_FLAG(field, value, flag) (VD_SET_PROP(field, value) ? (flag = true, true): false); +#define VD_SET_PROP_WITH_FLAG(field, value, flag) (VD_SET_PROP_AND_NOTIFY(field, value) ? (flag = true, true) : false) #define VD_SET_PROP(field, value) (value != field ? (field = value, true) : false) +#define VD_SET_PROP_AND_NOTIFY(field, value) ({ bool retVal = VD_SET_PROP(field, value);\ + onPropertyChanged(); retVal;}) +#define UPDATE_SKPROP(field, value) ({bool retVal = (field != value); if (field != value) SkRefCnt_SafeAssign(field, value); retVal;}) /* A VectorDrawable is composed of a tree of nodes. * Each node can be a group node, or a path. @@ -52,22 +57,65 @@ namespace VectorDrawable { * / \ | * Path Path Path * + * VectorDrawables are drawn into bitmap caches first, then the caches are drawn to the given + * canvas with root alpha applied. Two caches are maintained for VD, one in UI thread, the other in + * Render Thread. A generation id is used to keep track of changes in the vector drawable tree. + * Each cache has their own generation id to track whether they are up to date with the latest + * change in the tree. + * + * Any property change to the vector drawable coming from UI thread (such as bulk setters to update + * all the properties, and viewport change, etc.) are only modifying the staging properties. The + * staging properties will then be marked dirty and will be pushed over to render thread properties + * at sync point. If staging properties are not dirty at sync point, we sync backwards by updating + * staging properties with render thread properties to reflect the latest animation value. + * */ + +class PropertyChangedListener { +public: + PropertyChangedListener(bool* dirty, bool* stagingDirty) + : mDirty(dirty), mStagingDirty(stagingDirty) {} + void onPropertyChanged() { + *mDirty = true; + } + void onStagingPropertyChanged() { + *mStagingDirty = true; + } +private: + bool* mDirty; + bool* mStagingDirty; +}; + class ANDROID_API Node { public: + class Properties { + public: + Properties(Node* node) : mNode(node) {} + inline void onPropertyChanged() { + mNode->onPropertyChanged(this); + } + private: + Node* mNode; + }; Node(const Node& node) { mName = node.mName; } Node() {} virtual void draw(SkCanvas* outCanvas, const SkMatrix& currentMatrix, - float scaleX, float scaleY) = 0; + float scaleX, float scaleY, bool useStagingData) = 0; virtual void dump() = 0; void setName(const char* name) { mName = name; } + virtual void setPropertyChangedListener(PropertyChangedListener* listener) { + mPropertyChangedListener = listener; + } + virtual void onPropertyChanged(Properties* properties) = 0; virtual ~Node(){} + virtual void syncProperties() = 0; protected: std::string mName; + PropertyChangedListener* mPropertyChangedListener = nullptr; }; class ANDROID_API Path : public Node { @@ -81,150 +129,267 @@ public: && points == data.points; } }; - Path(const Data& nodes); + + class PathProperties : public Properties { + public: + PathProperties(Node* node) : Properties(node) {} + void syncProperties(const PathProperties& prop) { + mData = prop.mData; + onPropertyChanged(); + } + void setData(const Data& data) { + // Updates the path data. Note that we don't generate a new Skia path right away + // because there are cases where the animation is changing the path data, but the view + // that hosts the VD has gone off screen, in which case we won't even draw. So we + // postpone the Skia path generation to the draw time. + if (data == mData) { + return; + } + mData = data; + onPropertyChanged(); + + } + const Data& getData() const { + return mData; + } + private: + Data mData; + }; + Path(const Path& path); Path(const char* path, size_t strLength); Path() {} + void dump() override; - bool canMorph(const Data& path); - bool canMorph(const Path& path); void draw(SkCanvas* outCanvas, const SkMatrix& groupStackedMatrix, - float scaleX, float scaleY) override; - void setPath(const char* path, size_t strLength); - void setPathData(const Data& data); + float scaleX, float scaleY, bool useStagingData) override; static float getMatrixScale(const SkMatrix& groupStackedMatrix); + virtual void syncProperties() override; + virtual void onPropertyChanged(Properties* prop) override { + if (prop == &mStagingProperties) { + mStagingPropertiesDirty = true; + if (mPropertyChangedListener) { + mPropertyChangedListener->onStagingPropertyChanged(); + } + } else if (prop == &mProperties){ + mSkPathDirty = true; + if (mPropertyChangedListener) { + mPropertyChangedListener->onPropertyChanged(); + } + } + } + PathProperties* mutateStagingProperties() { return &mStagingProperties; } + const PathProperties* stagingProperties() { return &mStagingProperties; } + + // This should only be called from animations on RT + PathProperties* mutateProperties() { return &mProperties; } protected: virtual const SkPath& getUpdatedPath(); + virtual void getStagingPath(SkPath* outPath); virtual void drawPath(SkCanvas *outCanvas, SkPath& renderPath, - float strokeScale, const SkMatrix& matrix) = 0; - Data mData; - SkPath mSkPath; + float strokeScale, const SkMatrix& matrix, bool useStagingData) = 0; + + // Internal data, render thread only. bool mSkPathDirty = true; + SkPath mSkPath; + +private: + PathProperties mProperties = PathProperties(this); + PathProperties mStagingProperties = PathProperties(this); + bool mStagingPropertiesDirty = true; }; class ANDROID_API FullPath: public Path { public: + class FullPathProperties : public Properties { + public: + struct PrimitiveFields { + float strokeWidth = 0; + SkColor strokeColor = SK_ColorTRANSPARENT; + float strokeAlpha = 1; + SkColor fillColor = SK_ColorTRANSPARENT; + float fillAlpha = 1; + float trimPathStart = 0; + float trimPathEnd = 1; + float trimPathOffset = 0; + int32_t strokeLineCap = SkPaint::Cap::kButt_Cap; + int32_t strokeLineJoin = SkPaint::Join::kMiter_Join; + float strokeMiterLimit = 4; + int fillType = 0; /* non-zero or kWinding_FillType in Skia */ + }; + FullPathProperties(Node* mNode) : Properties(mNode), mTrimDirty(false) {} + void syncProperties(const FullPathProperties& prop) { + mPrimitiveFields = prop.mPrimitiveFields; + mTrimDirty = true; + fillGradient.reset(prop.fillGradient); + strokeGradient.reset(prop.strokeGradient); + onPropertyChanged(); + } + void setFillGradient(SkShader* gradient) { + if(fillGradient != gradient){ + fillGradient.reset(gradient); + onPropertyChanged(); + } + } + void setStrokeGradient(SkShader* gradient) { + if(strokeGradient != gradient){ + strokeGradient.reset(gradient); + onPropertyChanged(); + } + } + SkShader* getFillGradient() const { + return fillGradient; + } + SkShader* getStrokeGradient() const { + return strokeGradient; + } + float getStrokeWidth() const{ + return mPrimitiveFields.strokeWidth; + } + void setStrokeWidth(float strokeWidth) { + VD_SET_PROP_AND_NOTIFY(strokeWidth, strokeWidth); + } + SkColor getStrokeColor() const{ + return mPrimitiveFields.strokeColor; + } + void setStrokeColor(SkColor strokeColor) { + VD_SET_PROP_AND_NOTIFY(mPrimitiveFields.strokeColor, strokeColor); + } + float getStrokeAlpha() const{ + return mPrimitiveFields.strokeAlpha; + } + void setStrokeAlpha(float strokeAlpha) { + VD_SET_PROP_AND_NOTIFY(mPrimitiveFields.strokeAlpha, strokeAlpha); + } + SkColor getFillColor() const { + return mPrimitiveFields.fillColor; + } + void setFillColor(SkColor fillColor) { + VD_SET_PROP_AND_NOTIFY(mPrimitiveFields.fillColor, fillColor); + } + float getFillAlpha() const{ + return mPrimitiveFields.fillAlpha; + } + void setFillAlpha(float fillAlpha) { + VD_SET_PROP_AND_NOTIFY(mPrimitiveFields.fillAlpha, fillAlpha); + } + float getTrimPathStart() const{ + return mPrimitiveFields.trimPathStart; + } + void setTrimPathStart(float trimPathStart) { + VD_SET_PROP_WITH_FLAG(mPrimitiveFields.trimPathStart, trimPathStart, mTrimDirty); + } + float getTrimPathEnd() const{ + return mPrimitiveFields.trimPathEnd; + } + void setTrimPathEnd(float trimPathEnd) { + VD_SET_PROP_WITH_FLAG(mPrimitiveFields.trimPathEnd, trimPathEnd, mTrimDirty); + } + float getTrimPathOffset() const{ + return mPrimitiveFields.trimPathOffset; + } + void setTrimPathOffset(float trimPathOffset) { + VD_SET_PROP_WITH_FLAG(mPrimitiveFields.trimPathOffset, trimPathOffset, mTrimDirty); + } -struct Properties { - float strokeWidth = 0; - SkColor strokeColor = SK_ColorTRANSPARENT; - float strokeAlpha = 1; - SkColor fillColor = SK_ColorTRANSPARENT; - float fillAlpha = 1; - float trimPathStart = 0; - float trimPathEnd = 1; - float trimPathOffset = 0; - int32_t strokeLineCap = SkPaint::Cap::kButt_Cap; - int32_t strokeLineJoin = SkPaint::Join::kMiter_Join; - float strokeMiterLimit = 4; - int fillType = 0; /* non-zero or kWinding_FillType in Skia */ -}; + float getStrokeMiterLimit() const { + return mPrimitiveFields.strokeMiterLimit; + } + float getStrokeLineCap() const { + return mPrimitiveFields.strokeLineCap; + } + float getStrokeLineJoin() const { + return mPrimitiveFields.strokeLineJoin; + } + float getFillType() const { + return mPrimitiveFields.fillType; + } + bool copyProperties(int8_t* outProperties, int length) const; + void updateProperties(float strokeWidth, SkColor strokeColor, float strokeAlpha, + SkColor fillColor, float fillAlpha, float trimPathStart, float trimPathEnd, + float trimPathOffset, float strokeMiterLimit, int strokeLineCap, int strokeLineJoin, + int fillType) { + mPrimitiveFields.strokeWidth = strokeWidth; + mPrimitiveFields.strokeColor = strokeColor; + mPrimitiveFields.strokeAlpha = strokeAlpha; + mPrimitiveFields.fillColor = fillColor; + mPrimitiveFields.fillAlpha = fillAlpha; + mPrimitiveFields.trimPathStart = trimPathStart; + mPrimitiveFields.trimPathEnd = trimPathEnd; + mPrimitiveFields.trimPathOffset = trimPathOffset; + mPrimitiveFields.strokeMiterLimit = strokeMiterLimit; + mPrimitiveFields.strokeLineCap = strokeLineCap; + mPrimitiveFields.strokeLineJoin = strokeLineJoin; + mPrimitiveFields.fillType = fillType; + mTrimDirty = true; + onPropertyChanged(); + } + // Set property values during animation + void setColorPropertyValue(int propertyId, int32_t value); + void setPropertyValue(int propertyId, float value); + bool mTrimDirty; + private: + enum class Property { + strokeWidth = 0, + strokeColor, + strokeAlpha, + fillColor, + fillAlpha, + trimPathStart, + trimPathEnd, + trimPathOffset, + strokeLineCap, + strokeLineJoin, + strokeMiterLimit, + fillType, + count, + }; + PrimitiveFields mPrimitiveFields; + SkAutoTUnref<SkShader> fillGradient; + SkAutoTUnref<SkShader> strokeGradient; + }; + // Called from UI thread FullPath(const FullPath& path); // for cloning FullPath(const char* path, size_t strLength) : Path(path, strLength) {} FullPath() : Path() {} - FullPath(const Data& nodes) : Path(nodes) {} - - ~FullPath() { - SkSafeUnref(mFillGradient); - SkSafeUnref(mStrokeGradient); - } - - void updateProperties(float strokeWidth, SkColor strokeColor, - float strokeAlpha, SkColor fillColor, float fillAlpha, - float trimPathStart, float trimPathEnd, float trimPathOffset, - float strokeMiterLimit, int strokeLineCap, int strokeLineJoin, int fillType); - // TODO: Cleanup: Remove the setter and getters below, and their counterparts in java and JNI - float getStrokeWidth() { - return mProperties.strokeWidth; - } - void setStrokeWidth(float strokeWidth) { - mProperties.strokeWidth = strokeWidth; - } - SkColor getStrokeColor() { - return mProperties.strokeColor; - } - void setStrokeColor(SkColor strokeColor) { - mProperties.strokeColor = strokeColor; - } - float getStrokeAlpha() { - return mProperties.strokeAlpha; - } - void setStrokeAlpha(float strokeAlpha) { - mProperties.strokeAlpha = strokeAlpha; - } - SkColor getFillColor() { - return mProperties.fillColor; - } - void setFillColor(SkColor fillColor) { - mProperties.fillColor = fillColor; - } - float getFillAlpha() { - return mProperties.fillAlpha; - } - void setFillAlpha(float fillAlpha) { - mProperties.fillAlpha = fillAlpha; - } - float getTrimPathStart() { - return mProperties.trimPathStart; - } - void setTrimPathStart(float trimPathStart) { - VD_SET_PROP_WITH_FLAG(mProperties.trimPathStart, trimPathStart, mTrimDirty); - } - float getTrimPathEnd() { - return mProperties.trimPathEnd; - } - void setTrimPathEnd(float trimPathEnd) { - VD_SET_PROP_WITH_FLAG(mProperties.trimPathEnd, trimPathEnd, mTrimDirty); - } - float getTrimPathOffset() { - return mProperties.trimPathOffset; - } - void setTrimPathOffset(float trimPathOffset) { - VD_SET_PROP_WITH_FLAG(mProperties.trimPathOffset, trimPathOffset, mTrimDirty); + void dump() override; + FullPathProperties* mutateStagingProperties() { return &mStagingProperties; } + const FullPathProperties* stagingProperties() { return &mStagingProperties; } + + // This should only be called from animations on RT + FullPathProperties* mutateProperties() { return &mProperties; } + + virtual void syncProperties() override; + virtual void onPropertyChanged(Properties* properties) override { + Path::onPropertyChanged(properties); + if (properties == &mStagingProperties) { + mStagingPropertiesDirty = true; + if (mPropertyChangedListener) { + mPropertyChangedListener->onStagingPropertyChanged(); + } + } else if (properties == &mProperties) { + if (mPropertyChangedListener) { + mPropertyChangedListener->onPropertyChanged(); + } + } } - bool getProperties(int8_t* outProperties, int length); - void setColorPropertyValue(int propertyId, int32_t value); - void setPropertyValue(int propertyId, float value); - - void setFillGradient(SkShader* fillGradient) { - SkRefCnt_SafeAssign(mFillGradient, fillGradient); - }; - void setStrokeGradient(SkShader* strokeGradient) { - SkRefCnt_SafeAssign(mStrokeGradient, strokeGradient); - }; - protected: const SkPath& getUpdatedPath() override; + void getStagingPath(SkPath* outPath) override; void drawPath(SkCanvas* outCanvas, SkPath& renderPath, - float strokeScale, const SkMatrix& matrix) override; - + float strokeScale, const SkMatrix& matrix, bool useStagingData) override; private: - enum class Property { - StrokeWidth = 0, - StrokeColor, - StrokeAlpha, - FillColor, - FillAlpha, - TrimPathStart, - TrimPathEnd, - TrimPathOffset, - StrokeLineCap, - StrokeLineJoin, - StrokeMiterLimit, - FillType, - Count, - }; - // Applies trimming to the specified path. - void applyTrim(); - Properties mProperties; - bool mTrimDirty = true; + + FullPathProperties mProperties = FullPathProperties(this); + FullPathProperties mStagingProperties = FullPathProperties(this); + bool mStagingPropertiesDirty = true; + + // Intermediate data for drawing, render thread only SkPath mTrimmedSkPath; - SkPaint mPaint; - SkShader* mStrokeGradient = nullptr; - SkShader* mFillGradient = nullptr; + }; class ANDROID_API ClipPath: public Path { @@ -232,143 +397,316 @@ public: ClipPath(const ClipPath& path) : Path(path) {} ClipPath(const char* path, size_t strLength) : Path(path, strLength) {} ClipPath() : Path() {} - ClipPath(const Data& nodes) : Path(nodes) {} protected: void drawPath(SkCanvas* outCanvas, SkPath& renderPath, - float strokeScale, const SkMatrix& matrix) override; + float strokeScale, const SkMatrix& matrix, bool useStagingData) override; }; class ANDROID_API Group: public Node { public: - struct Properties { - float rotate = 0; - float pivotX = 0; - float pivotY = 0; - float scaleX = 1; - float scaleY = 1; - float translateX = 0; - float translateY = 0; + class GroupProperties : public Properties { + public: + GroupProperties(Node* mNode) : Properties(mNode) {} + struct PrimitiveFields { + float rotate = 0; + float pivotX = 0; + float pivotY = 0; + float scaleX = 1; + float scaleY = 1; + float translateX = 0; + float translateY = 0; + } mPrimitiveFields; + void syncProperties(const GroupProperties& prop) { + mPrimitiveFields = prop.mPrimitiveFields; + onPropertyChanged(); + } + float getRotation() const { + return mPrimitiveFields.rotate; + } + void setRotation(float rotation) { + VD_SET_PROP_AND_NOTIFY(mPrimitiveFields.rotate, rotation); + } + float getPivotX() const { + return mPrimitiveFields.pivotX; + } + void setPivotX(float pivotX) { + VD_SET_PROP_AND_NOTIFY(mPrimitiveFields.pivotX, pivotX); + } + float getPivotY() const { + return mPrimitiveFields.pivotY; + } + void setPivotY(float pivotY) { + VD_SET_PROP_AND_NOTIFY(mPrimitiveFields.pivotY, pivotY); + } + float getScaleX() const { + return mPrimitiveFields.scaleX; + } + void setScaleX(float scaleX) { + VD_SET_PROP_AND_NOTIFY(mPrimitiveFields.scaleX, scaleX); + } + float getScaleY() const { + return mPrimitiveFields.scaleY; + } + void setScaleY(float scaleY) { + VD_SET_PROP_AND_NOTIFY(mPrimitiveFields.scaleY, scaleY); + } + float getTranslateX() const { + return mPrimitiveFields.translateX; + } + void setTranslateX(float translateX) { + VD_SET_PROP_AND_NOTIFY(mPrimitiveFields.translateX, translateX); + } + float getTranslateY() const { + return mPrimitiveFields.translateY; + } + void setTranslateY(float translateY) { + VD_SET_PROP_AND_NOTIFY(translateY, translateY); + } + void updateProperties(float rotate, float pivotX, float pivotY, + float scaleX, float scaleY, float translateX, float translateY) { + mPrimitiveFields.rotate = rotate; + mPrimitiveFields.pivotX = pivotX; + mPrimitiveFields.pivotY = pivotY; + mPrimitiveFields.scaleX = scaleX; + mPrimitiveFields.scaleY = scaleY; + mPrimitiveFields.translateX = translateX; + mPrimitiveFields.translateY = translateY; + onPropertyChanged(); + } + void setPropertyValue(int propertyId, float value); + float getPropertyValue(int propertyId) const; + bool copyProperties(float* outProperties, int length) const; + static bool isValidProperty(int propertyId); + private: + enum class Property { + rotate = 0, + pivotX, + pivotY, + scaleX, + scaleY, + translateX, + translateY, + // Count of the properties, must be at the end. + count, + }; }; + Group(const Group& group); Group() {} - float getRotation() { - return mProperties.rotate; - } - void setRotation(float rotation) { - mProperties.rotate = rotation; - } - float getPivotX() { - return mProperties.pivotX; - } - void setPivotX(float pivotX) { - mProperties.pivotX = pivotX; - } - float getPivotY() { - return mProperties.pivotY; - } - void setPivotY(float pivotY) { - mProperties.pivotY = pivotY; - } - float getScaleX() { - return mProperties.scaleX; - } - void setScaleX(float scaleX) { - mProperties.scaleX = scaleX; - } - float getScaleY() { - return mProperties.scaleY; - } - void setScaleY(float scaleY) { - mProperties.scaleY = scaleY; - } - float getTranslateX() { - return mProperties.translateX; - } - void setTranslateX(float translateX) { - mProperties.translateX = translateX; - } - float getTranslateY() { - return mProperties.translateY; - } - void setTranslateY(float translateY) { - mProperties.translateY = translateY; + void addChild(Node* child); + virtual void setPropertyChangedListener(PropertyChangedListener* listener) override { + Node::setPropertyChangedListener(listener); + for (auto& child : mChildren) { + child->setPropertyChangedListener(listener); + } } + virtual void syncProperties() override; + GroupProperties* mutateStagingProperties() { return &mStagingProperties; } + const GroupProperties* stagingProperties() { return &mStagingProperties; } + + // This should only be called from animations on RT + GroupProperties* mutateProperties() { return &mProperties; } + + // Methods below could be called from either UI thread or Render Thread. virtual void draw(SkCanvas* outCanvas, const SkMatrix& currentMatrix, - float scaleX, float scaleY) override; - void updateLocalMatrix(float rotate, float pivotX, float pivotY, - float scaleX, float scaleY, float translateX, float translateY); - void getLocalMatrix(SkMatrix* outMatrix); - void addChild(Node* child); + float scaleX, float scaleY, bool useStagingData) override; + void getLocalMatrix(SkMatrix* outMatrix, const GroupProperties& properties); void dump() override; - bool getProperties(float* outProperties, int length); - float getPropertyValue(int propertyId) const; - void setPropertyValue(int propertyId, float value); static bool isValidProperty(int propertyId); + virtual void onPropertyChanged(Properties* properties) override { + if (properties == &mStagingProperties) { + mStagingPropertiesDirty = true; + if (mPropertyChangedListener) { + mPropertyChangedListener->onStagingPropertyChanged(); + } + } else { + if (mPropertyChangedListener) { + mPropertyChangedListener->onPropertyChanged(); + } + } + } + private: - enum class Property { - Rotate = 0, - PivotX, - PivotY, - ScaleX, - ScaleY, - TranslateX, - TranslateY, - // Count of the properties, must be at the end. - Count, - }; + GroupProperties mProperties = GroupProperties(this); + GroupProperties mStagingProperties = GroupProperties(this); + bool mStagingPropertiesDirty = true; std::vector< std::unique_ptr<Node> > mChildren; - Properties mProperties; }; class ANDROID_API Tree : public VirtualLightRefBase { public: - Tree(Group* rootNode) : mRootNode(rootNode) {} + Tree(Group* rootNode) : mRootNode(rootNode) { + mRootNode->setPropertyChangedListener(&mPropertyChangedListener); + } void draw(Canvas* outCanvas, SkColorFilter* colorFilter, const SkRect& bounds, bool needsMirroring, bool canReuseCache); + void drawStaging(Canvas* canvas); const SkBitmap& getBitmapUpdateIfDirty(); - void createCachedBitmapIfNeeded(int width, int height); - bool canReuseBitmap(int width, int height); void setAllowCaching(bool allowCaching) { mAllowCaching = allowCaching; } - bool setRootAlpha(float rootAlpha) { - return VD_SET_PROP(mRootAlpha, rootAlpha); - } - - float getRootAlpha() { - return mRootAlpha; - } - void setViewportSize(float viewportWidth, float viewportHeight) { - mViewportWidth = viewportWidth; - mViewportHeight = viewportHeight; - } SkPaint* getPaint(); - const SkRect& getBounds() const { - return mBounds; - } + void syncProperties() { + if (mStagingProperties.mNonAnimatablePropertiesDirty) { + mProperties.syncNonAnimatableProperties(mStagingProperties); + mStagingProperties.mNonAnimatablePropertiesDirty = false; + } + + if (mStagingProperties.mAnimatablePropertiesDirty) { + mProperties.syncAnimatableProperties(mStagingProperties); + } else { + mStagingProperties.syncAnimatableProperties(mProperties); + } + mStagingProperties.mAnimatablePropertiesDirty = false; + mRootNode->syncProperties(); + } + + class TreeProperties { + public: + TreeProperties(Tree* tree) : mTree(tree) {} + // Properties that can only be modified by UI thread, therefore sync should + // only go from UI to RT + struct NonAnimatableProperties { + float viewportWidth = 0; + float viewportHeight = 0; + SkRect bounds; + int scaledWidth = 0; + int scaledHeight = 0; + SkColorFilter* colorFilter = nullptr; + ~NonAnimatableProperties() { + SkSafeUnref(colorFilter); + } + } mNonAnimatableProperties; + bool mNonAnimatablePropertiesDirty = true; + + float mRootAlpha = 1.0f; + bool mAnimatablePropertiesDirty = true; + + void syncNonAnimatableProperties(const TreeProperties& prop) { + // Copy over the data that can only be changed in UI thread + if (mNonAnimatableProperties.colorFilter != prop.mNonAnimatableProperties.colorFilter) { + SkRefCnt_SafeAssign(mNonAnimatableProperties.colorFilter, + prop.mNonAnimatableProperties.colorFilter); + } + mNonAnimatableProperties = prop.mNonAnimatableProperties; + } + + void setViewportSize(float width, float height) { + if (mNonAnimatableProperties.viewportWidth != width + || mNonAnimatableProperties.viewportHeight != height) { + mNonAnimatablePropertiesDirty = true; + mNonAnimatableProperties.viewportWidth = width; + mNonAnimatableProperties.viewportHeight = height; + mTree->onPropertyChanged(this); + } + } + void setBounds(const SkRect& bounds) { + if (mNonAnimatableProperties.bounds != bounds) { + mNonAnimatableProperties.bounds = bounds; + mNonAnimatablePropertiesDirty = true; + mTree->onPropertyChanged(this); + } + } + + void setScaledSize(int width, int height) { + if (mNonAnimatableProperties.scaledWidth != width + || mNonAnimatableProperties.scaledHeight != height) { + mNonAnimatableProperties.scaledWidth = width; + mNonAnimatableProperties.scaledHeight = height; + mNonAnimatablePropertiesDirty = true; + mTree->onPropertyChanged(this); + } + } + void setColorFilter(SkColorFilter* filter) { + if (UPDATE_SKPROP(mNonAnimatableProperties.colorFilter, filter)) { + mNonAnimatablePropertiesDirty = true; + mTree->onPropertyChanged(this); + } + } + SkColorFilter* getColorFilter() const{ + return mNonAnimatableProperties.colorFilter; + } + + float getViewportWidth() const { + return mNonAnimatableProperties.viewportWidth; + } + float getViewportHeight() const { + return mNonAnimatableProperties.viewportHeight; + } + float getScaledWidth() const { + return mNonAnimatableProperties.scaledWidth; + } + float getScaledHeight() const { + return mNonAnimatableProperties.scaledHeight; + } + void syncAnimatableProperties(const TreeProperties& prop) { + mRootAlpha = prop.mRootAlpha; + } + bool setRootAlpha(float rootAlpha) { + if (rootAlpha != mRootAlpha) { + mAnimatablePropertiesDirty = true; + mRootAlpha = rootAlpha; + mTree->onPropertyChanged(this); + return true; + } + return false; + } + float getRootAlpha() const { return mRootAlpha;} + const SkRect& getBounds() const { + return mNonAnimatableProperties.bounds; + } + Tree* mTree; + }; + void onPropertyChanged(TreeProperties* prop); + TreeProperties* mutateStagingProperties() { return &mStagingProperties; } + const TreeProperties* stagingProperties() { return &mStagingProperties; } + PushStagingFunctor* getFunctor() { return &mFunctor;} + + // This should only be called from animations on RT + TreeProperties* mutateProperties() { return &mProperties; } private: + class VectorDrawableFunctor : public PushStagingFunctor { + public: + VectorDrawableFunctor(Tree* tree) : mTree(tree) {} + virtual void operator ()() { + mTree->syncProperties(); + } + private: + Tree* mTree; + }; + + SkPaint* updatePaint(SkPaint* outPaint, TreeProperties* prop); + bool allocateBitmapIfNeeded(SkBitmap* outCache, int width, int height); + bool canReuseBitmap(const SkBitmap&, int width, int height); + void updateBitmapCache(SkBitmap* outCache, bool useStagingData); // Cap the bitmap size, such that it won't hurt the performance too much // and it won't crash due to a very large scale. // The drawable will look blurry above this size. const static int MAX_CACHED_BITMAP_SIZE; - bool mCacheDirty = true; bool mAllowCaching = true; - float mViewportWidth = 0; - float mViewportHeight = 0; - float mRootAlpha = 1.0f; - std::unique_ptr<Group> mRootNode; - SkRect mBounds; - SkMatrix mCanvasMatrix; + + TreeProperties mProperties = TreeProperties(this); + TreeProperties mStagingProperties = TreeProperties(this); + + VectorDrawableFunctor mFunctor = VectorDrawableFunctor(this); + SkPaint mPaint; - SkPathMeasure mPathMeasure; - SkBitmap mCachedBitmap; + struct Cache { + SkBitmap bitmap; + bool dirty = true; + }; + + Cache mStagingCache; + Cache mCache; + PropertyChangedListener mPropertyChangedListener + = PropertyChangedListener(&mCache.dirty, &mStagingCache.dirty); }; } // namespace VectorDrawable diff --git a/libs/hwui/renderstate/OffscreenBufferPool.cpp b/libs/hwui/renderstate/OffscreenBufferPool.cpp index bb1a044a8369..73b6c02a3fdc 100644 --- a/libs/hwui/renderstate/OffscreenBufferPool.cpp +++ b/libs/hwui/renderstate/OffscreenBufferPool.cpp @@ -127,7 +127,7 @@ int OffscreenBufferPool::Entry::compare(const Entry& lhs, const Entry& rhs) { } void OffscreenBufferPool::clear() { - for (auto entry : mPool) { + for (auto& entry : mPool) { delete entry.layer; } mPool.clear(); diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp index 7dfafb9117de..0ea246f00fb7 100644 --- a/libs/hwui/tests/unit/FrameBuilderTests.cpp +++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp @@ -49,9 +49,12 @@ class TestRendererBase { public: virtual ~TestRendererBase() {} virtual OffscreenBuffer* startTemporaryLayer(uint32_t, uint32_t) { - ADD_FAILURE() << "Layer creation not expected in this test"; + ADD_FAILURE() << "Temporary layers not expected in this test"; return nullptr; } + virtual void recycleTemporaryLayer(OffscreenBuffer*) { + ADD_FAILURE() << "Temporary layers not expected in this test"; + } virtual void startRepaintLayer(OffscreenBuffer*, const Rect& repaintRect) { ADD_FAILURE() << "Layer repaint not expected in this test"; } @@ -298,7 +301,6 @@ RENDERTHREAD_TEST(FrameBuilder, avoidOverdraw_bitmaps) { class AvoidOverdrawBitmapsTestRenderer : public TestRendererBase { public: void onBitmapOp(const BitmapOp& op, const BakedOpState& state) override { - EXPECT_LT(mIndex++, 2) << "Should be two bitmaps"; switch(mIndex++) { case 0: EXPECT_EQ(opaqueBitmap.pixelRef(), op.bitmap->pixelRef()); @@ -331,7 +333,7 @@ RENDERTHREAD_TEST(FrameBuilder, avoidOverdraw_bitmaps) { AvoidOverdrawBitmapsTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); - EXPECT_EQ(2, renderer.getIndex()) << "Expect exactly one op"; + EXPECT_EQ(2, renderer.getIndex()) << "Expect exactly two ops"; } RENDERTHREAD_TEST(FrameBuilder, clippedMerging) { @@ -711,6 +713,10 @@ RENDERTHREAD_TEST(FrameBuilder, saveLayer_simple) { EXPECT_EQ(Rect(200, 200), state.computedState.clipRect()); EXPECT_TRUE(state.computedState.transform.isIdentity()); } + void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override { + EXPECT_EQ(4, mIndex++); + EXPECT_EQ(nullptr, offscreenBuffer); + } }; auto node = TestUtils::createNode(0, 0, 200, 200, @@ -723,7 +729,7 @@ RENDERTHREAD_TEST(FrameBuilder, saveLayer_simple) { TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); SaveLayerSimpleTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); - EXPECT_EQ(4, renderer.getIndex()); + EXPECT_EQ(5, renderer.getIndex()); } RENDERTHREAD_TEST(FrameBuilder, saveLayer_nested) { @@ -775,6 +781,15 @@ RENDERTHREAD_TEST(FrameBuilder, saveLayer_nested) { EXPECT_EQ(Rect(800, 800), op.unmappedBounds); // outer layer } else { ADD_FAILURE(); } } + void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override { + const int index = mIndex++; + // order isn't important, but we need to see both + if (index == 10) { + EXPECT_EQ((OffscreenBuffer*)0x400, offscreenBuffer); + } else if (index == 11) { + EXPECT_EQ((OffscreenBuffer*)0x800, offscreenBuffer); + } else { ADD_FAILURE(); } + } }; auto node = TestUtils::createNode(0, 0, 800, 800, @@ -795,7 +810,7 @@ RENDERTHREAD_TEST(FrameBuilder, saveLayer_nested) { TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); SaveLayerNestedTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); - EXPECT_EQ(10, renderer.getIndex()); + EXPECT_EQ(12, renderer.getIndex()); } RENDERTHREAD_TEST(FrameBuilder, saveLayer_contentRejection) { @@ -1010,10 +1025,15 @@ RENDERTHREAD_TEST(FrameBuilder, saveLayerUnclipped_complex) { } void onLayerOp(const LayerOp& op, const BakedOpState& state) override { EXPECT_EQ(9, mIndex++); + EXPECT_EQ((OffscreenBuffer*)0xabcd, *op.layerHandle); } void endFrame(const Rect& repaintRect) override { EXPECT_EQ(11, mIndex++); } + void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override { + EXPECT_EQ(12, mIndex++); + EXPECT_EQ((OffscreenBuffer*)0xabcd, offscreenBuffer); + } }; auto node = TestUtils::createNode(0, 0, 600, 600, // 500x500 triggers clipping @@ -1030,7 +1050,7 @@ RENDERTHREAD_TEST(FrameBuilder, saveLayerUnclipped_complex) { TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance()); SaveLayerUnclippedComplexTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); - EXPECT_EQ(12, renderer.getIndex()); + EXPECT_EQ(13, renderer.getIndex()); } RENDERTHREAD_TEST(FrameBuilder, hwLayer_simple) { @@ -1152,6 +1172,9 @@ RENDERTHREAD_TEST(FrameBuilder, hwLayer_complex) { void endFrame(const Rect& repaintRect) override { EXPECT_EQ(12, mIndex++); } + void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override { + EXPECT_EQ(13, mIndex++); + } }; auto child = TestUtils::createNode(50, 50, 150, 150, @@ -1189,7 +1212,7 @@ RENDERTHREAD_TEST(FrameBuilder, hwLayer_complex) { syncedList, sLightGeometry, Caches::getInstance()); HwLayerComplexTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); - EXPECT_EQ(13, renderer.getIndex()); + EXPECT_EQ(14, renderer.getIndex()); // clean up layer pointers, so we can safely destruct RenderNodes *(child->getLayerHandle()) = nullptr; @@ -1593,6 +1616,9 @@ RENDERTHREAD_TEST(FrameBuilder, shadowSaveLayer) { void onLayerOp(const LayerOp& op, const BakedOpState& state) override { EXPECT_EQ(4, mIndex++); } + void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override { + EXPECT_EQ(5, mIndex++); + } }; auto parent = TestUtils::createNode(0, 0, 200, 200, @@ -1611,7 +1637,7 @@ RENDERTHREAD_TEST(FrameBuilder, shadowSaveLayer) { (FrameBuilder::LightGeometry) {{ 100, 100, 100 }, 50}, Caches::getInstance()); ShadowSaveLayerTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); - EXPECT_EQ(5, renderer.getIndex()); + EXPECT_EQ(6, renderer.getIndex()); } RENDERTHREAD_TEST(FrameBuilder, shadowHwLayer) { @@ -1840,6 +1866,9 @@ void testSaveLayerAlphaClip(SaveLayerAlphaData* outObservedData, void onLayerOp(const LayerOp& op, const BakedOpState& state) override { EXPECT_EQ(3, mIndex++); } + void recycleTemporaryLayer(OffscreenBuffer* offscreenBuffer) override { + EXPECT_EQ(4, mIndex++); + } private: SaveLayerAlphaData* mOutData; }; @@ -1865,7 +1894,7 @@ void testSaveLayerAlphaClip(SaveLayerAlphaData* outObservedData, frameBuilder.replayBakedOps<TestDispatcher>(renderer); // assert, since output won't be valid if we haven't seen a save layer triggered - ASSERT_EQ(4, renderer.getIndex()) << "Test must trigger saveLayer alpha behavior."; + ASSERT_EQ(5, renderer.getIndex()) << "Test must trigger saveLayer alpha behavior."; } RENDERTHREAD_TEST(FrameBuilder, renderPropSaveLayerAlphaClipBig) { diff --git a/libs/hwui/tests/unit/LeakCheckTests.cpp b/libs/hwui/tests/unit/LeakCheckTests.cpp index 9161f90b54aa..e2fc376db50d 100644 --- a/libs/hwui/tests/unit/LeakCheckTests.cpp +++ b/libs/hwui/tests/unit/LeakCheckTests.cpp @@ -30,6 +30,25 @@ const LayerUpdateQueue sEmptyLayerUpdateQueue; const FrameBuilder::LightGeometry sLightGeometery = { {100, 100, 100}, 50}; const BakedOpRenderer::LightInfo sLightInfo = { 128, 128 }; +RENDERTHREAD_TEST(LeakCheck, saveLayer_overdrawRejection) { + auto node = TestUtils::createNode(0, 0, 100, 100, + [](RenderProperties& props, RecordingCanvas& canvas) { + canvas.saveLayerAlpha(0, 0, 100, 100, 128, SaveFlags::ClipToLayer); + canvas.drawRect(0, 0, 100, 100, SkPaint()); + canvas.restore(); + + // opaque draw, rejects saveLayer beneath + canvas.drawRect(0, 0, 100, 100, SkPaint()); + }); + RenderState& renderState = renderThread.renderState(); + Caches& caches = Caches::getInstance(); + + FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 100), 100, 100, + TestUtils::createSyncedNodeList(node), sLightGeometery, Caches::getInstance()); + BakedOpRenderer renderer(caches, renderState, true, sLightInfo); + frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); +} + RENDERTHREAD_TEST(LeakCheck, saveLayerUnclipped_simple) { auto node = TestUtils::createNode(0, 0, 200, 200, [](RenderProperties& props, RecordingCanvas& canvas) { diff --git a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp index 37a485e3a9ac..b7950aab5662 100644 --- a/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp +++ b/libs/hwui/tests/unit/OffscreenBufferPoolTests.cpp @@ -30,119 +30,126 @@ TEST(OffscreenBuffer, computeIdealDimension) { EXPECT_EQ(1024u, OffscreenBuffer::computeIdealDimension(1000)); } -TEST(OffscreenBuffer, construct) { - TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) { - OffscreenBuffer layer(thread.renderState(), Caches::getInstance(), 49u, 149u); - EXPECT_EQ(49u, layer.viewportWidth); - EXPECT_EQ(149u, layer.viewportHeight); +RENDERTHREAD_TEST(OffscreenBuffer, construct) { + OffscreenBuffer layer(renderThread.renderState(), Caches::getInstance(), 49u, 149u); + EXPECT_EQ(49u, layer.viewportWidth); + EXPECT_EQ(149u, layer.viewportHeight); - EXPECT_EQ(64u, layer.texture.width()); - EXPECT_EQ(192u, layer.texture.height()); + EXPECT_EQ(64u, layer.texture.width()); + EXPECT_EQ(192u, layer.texture.height()); - EXPECT_EQ(64u * 192u * 4u, layer.getSizeInBytes()); - }); + EXPECT_EQ(64u * 192u * 4u, layer.getSizeInBytes()); } -TEST(OffscreenBuffer, getTextureCoordinates) { - TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) { - OffscreenBuffer layerAligned(thread.renderState(), Caches::getInstance(), 256u, 256u); - EXPECT_EQ(Rect(0, 1, 1, 0), - layerAligned.getTextureCoordinates()); +RENDERTHREAD_TEST(OffscreenBuffer, getTextureCoordinates) { + OffscreenBuffer layerAligned(renderThread.renderState(), Caches::getInstance(), 256u, 256u); + EXPECT_EQ(Rect(0, 1, 1, 0), + layerAligned.getTextureCoordinates()); - OffscreenBuffer layerUnaligned(thread.renderState(), Caches::getInstance(), 200u, 225u); - EXPECT_EQ(Rect(0, 225.0f / 256.0f, 200.0f / 256.0f, 0), - layerUnaligned.getTextureCoordinates()); - }); + OffscreenBuffer layerUnaligned(renderThread.renderState(), Caches::getInstance(), 200u, 225u); + EXPECT_EQ(Rect(0, 225.0f / 256.0f, 200.0f / 256.0f, 0), + layerUnaligned.getTextureCoordinates()); } -TEST(OffscreenBuffer, dirty) { - TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) { - OffscreenBuffer buffer(thread.renderState(), Caches::getInstance(), 256u, 256u); - buffer.dirty(Rect(-100, -100, 100, 100)); - EXPECT_EQ(android::Rect(100, 100), buffer.region.getBounds()); - }); +RENDERTHREAD_TEST(OffscreenBuffer, dirty) { + OffscreenBuffer buffer(renderThread.renderState(), Caches::getInstance(), 256u, 256u); + buffer.dirty(Rect(-100, -100, 100, 100)); + EXPECT_EQ(android::Rect(100, 100), buffer.region.getBounds()); } -TEST(OffscreenBufferPool, construct) { - TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) { - OffscreenBufferPool pool; - EXPECT_EQ(0u, pool.getCount()) << "pool must be created empty"; - EXPECT_EQ(0u, pool.getSize()) << "pool must be created empty"; - EXPECT_EQ((uint32_t) Properties::layerPoolSize, pool.getMaxSize()) - << "pool must read size from Properties"; - }); +RENDERTHREAD_TEST(OffscreenBufferPool, construct) { + OffscreenBufferPool pool; + EXPECT_EQ(0u, pool.getCount()) << "pool must be created empty"; + EXPECT_EQ(0u, pool.getSize()) << "pool must be created empty"; + EXPECT_EQ((uint32_t) Properties::layerPoolSize, pool.getMaxSize()) + << "pool must read size from Properties"; } -TEST(OffscreenBufferPool, getPutClear) { - TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) { - OffscreenBufferPool pool; +RENDERTHREAD_TEST(OffscreenBufferPool, getPutClear) { + OffscreenBufferPool pool; - auto layer = pool.get(thread.renderState(), 100u, 200u); - EXPECT_EQ(100u, layer->viewportWidth); - EXPECT_EQ(200u, layer->viewportHeight); + auto layer = pool.get(renderThread.renderState(), 100u, 200u); + EXPECT_EQ(100u, layer->viewportWidth); + EXPECT_EQ(200u, layer->viewportHeight); - ASSERT_LT(layer->getSizeInBytes(), pool.getMaxSize()); + ASSERT_LT(layer->getSizeInBytes(), pool.getMaxSize()); - pool.putOrDelete(layer); - ASSERT_EQ(layer->getSizeInBytes(), pool.getSize()); + pool.putOrDelete(layer); + ASSERT_EQ(layer->getSizeInBytes(), pool.getSize()); - auto layer2 = pool.get(thread.renderState(), 102u, 202u); - EXPECT_EQ(layer, layer2) << "layer should be recycled"; - ASSERT_EQ(0u, pool.getSize()) << "pool should have been emptied by removing only layer"; + auto layer2 = pool.get(renderThread.renderState(), 102u, 202u); + EXPECT_EQ(layer, layer2) << "layer should be recycled"; + ASSERT_EQ(0u, pool.getSize()) << "pool should have been emptied by removing only layer"; - pool.putOrDelete(layer); - EXPECT_EQ(1u, pool.getCount()); - pool.clear(); - EXPECT_EQ(0u, pool.getSize()); - EXPECT_EQ(0u, pool.getCount()); - }); + pool.putOrDelete(layer); + EXPECT_EQ(1u, pool.getCount()); + pool.clear(); + EXPECT_EQ(0u, pool.getSize()); + EXPECT_EQ(0u, pool.getCount()); } -TEST(OffscreenBufferPool, resize) { - TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) { - OffscreenBufferPool pool; - - auto layer = pool.get(thread.renderState(), 64u, 64u); - layer->dirty(Rect(64, 64)); - - // resize in place - ASSERT_EQ(layer, pool.resize(layer, 60u, 55u)); - EXPECT_TRUE(layer->region.isEmpty()) << "In place resize should clear usage region"; - EXPECT_EQ(60u, layer->viewportWidth); - EXPECT_EQ(55u, layer->viewportHeight); - EXPECT_EQ(64u, layer->texture.width()); - EXPECT_EQ(64u, layer->texture.height()); - - // resized to use different object in pool - auto layer2 = pool.get(thread.renderState(), 128u, 128u); - layer2->dirty(Rect(128, 128)); - EXPECT_FALSE(layer2->region.isEmpty()); - pool.putOrDelete(layer2); - ASSERT_EQ(1u, pool.getCount()); - - ASSERT_EQ(layer2, pool.resize(layer, 120u, 125u)); - EXPECT_TRUE(layer2->region.isEmpty()) << "Swap resize should clear usage region"; - EXPECT_EQ(120u, layer2->viewportWidth); - EXPECT_EQ(125u, layer2->viewportHeight); - EXPECT_EQ(128u, layer2->texture.width()); - EXPECT_EQ(128u, layer2->texture.height()); - - // original allocation now only thing in pool - EXPECT_EQ(1u, pool.getCount()); - EXPECT_EQ(layer->getSizeInBytes(), pool.getSize()); - - pool.putOrDelete(layer2); - }); +RENDERTHREAD_TEST(OffscreenBufferPool, resize) { + OffscreenBufferPool pool; + + auto layer = pool.get(renderThread.renderState(), 64u, 64u); + layer->dirty(Rect(64, 64)); + + // resize in place + ASSERT_EQ(layer, pool.resize(layer, 60u, 55u)); + EXPECT_TRUE(layer->region.isEmpty()) << "In place resize should clear usage region"; + EXPECT_EQ(60u, layer->viewportWidth); + EXPECT_EQ(55u, layer->viewportHeight); + EXPECT_EQ(64u, layer->texture.width()); + EXPECT_EQ(64u, layer->texture.height()); + + // resized to use different object in pool + auto layer2 = pool.get(renderThread.renderState(), 128u, 128u); + layer2->dirty(Rect(128, 128)); + EXPECT_FALSE(layer2->region.isEmpty()); + pool.putOrDelete(layer2); + ASSERT_EQ(1u, pool.getCount()); + + ASSERT_EQ(layer2, pool.resize(layer, 120u, 125u)); + EXPECT_TRUE(layer2->region.isEmpty()) << "Swap resize should clear usage region"; + EXPECT_EQ(120u, layer2->viewportWidth); + EXPECT_EQ(125u, layer2->viewportHeight); + EXPECT_EQ(128u, layer2->texture.width()); + EXPECT_EQ(128u, layer2->texture.height()); + + // original allocation now only thing in pool + EXPECT_EQ(1u, pool.getCount()); + EXPECT_EQ(layer->getSizeInBytes(), pool.getSize()); + + pool.putOrDelete(layer2); } -TEST(OffscreenBufferPool, putAndDestroy) { - TestUtils::runOnRenderThread([] (renderthread::RenderThread& thread) { - OffscreenBufferPool pool; - // layer too big to return to the pool - // Note: this relies on the fact that the pool won't reject based on max texture size - auto hugeLayer = pool.get(thread.renderState(), pool.getMaxSize() / 64, 64); - EXPECT_GT(hugeLayer->getSizeInBytes(), pool.getMaxSize()); - pool.putOrDelete(hugeLayer); - EXPECT_EQ(0u, pool.getCount()); // failed to put (so was destroyed instead) - }); +RENDERTHREAD_TEST(OffscreenBufferPool, putAndDestroy) { + OffscreenBufferPool pool; + // layer too big to return to the pool + // Note: this relies on the fact that the pool won't reject based on max texture size + auto hugeLayer = pool.get(renderThread.renderState(), pool.getMaxSize() / 64, 64); + EXPECT_GT(hugeLayer->getSizeInBytes(), pool.getMaxSize()); + pool.putOrDelete(hugeLayer); + EXPECT_EQ(0u, pool.getCount()); // failed to put (so was destroyed instead) +} + +RENDERTHREAD_TEST(OffscreenBufferPool, clear) { + EXPECT_EQ(0, GpuMemoryTracker::getInstanceCount(GpuObjectType::OffscreenBuffer)); + OffscreenBufferPool pool; + + // Create many buffers, with several at each size + std::vector<OffscreenBuffer*> buffers; + for (int size = 32; size <= 128; size += 32) { + for (int i = 0; i < 10; i++) { + buffers.push_back(pool.get(renderThread.renderState(), size, size)); + } + } + EXPECT_EQ(0u, pool.getCount()) << "Expect nothing inside"; + for (auto& buffer : buffers) pool.putOrDelete(buffer); + EXPECT_EQ(40u, pool.getCount()) << "Expect all items added"; + EXPECT_EQ(40, GpuMemoryTracker::getInstanceCount(GpuObjectType::OffscreenBuffer)); + pool.clear(); + EXPECT_EQ(0u, pool.getCount()) << "Expect all items cleared"; + + EXPECT_EQ(0, GpuMemoryTracker::getInstanceCount(GpuObjectType::OffscreenBuffer)); } diff --git a/media/java/android/media/DrmInitData.java b/media/java/android/media/DrmInitData.java index 06fe6ffb0d06..170d9de9d50a 100644 --- a/media/java/android/media/DrmInitData.java +++ b/media/java/android/media/DrmInitData.java @@ -28,6 +28,12 @@ import java.util.UUID; public abstract class DrmInitData { /** + * Prevent public constuctor access + */ + /* package private */ DrmInitData() { + } + + /** * Retrieves initialization data for a given DRM scheme, specified by its UUID. * * @param schemeUuid The DRM scheme's UUID. diff --git a/media/java/android/media/MediaActionSound.java b/media/java/android/media/MediaActionSound.java index 1fee58707613..983ca754acd1 100644 --- a/media/java/android/media/MediaActionSound.java +++ b/media/java/android/media/MediaActionSound.java @@ -45,8 +45,7 @@ public class MediaActionSound { private static final int NUM_MEDIA_SOUND_STREAMS = 1; private SoundPool mSoundPool; - private int[] mSoundIds; - private int mSoundIdToPlay; + private SoundState[] mSounds; private static final String[] SOUND_FILES = { "/system/media/audio/ui/camera_click.ogg", @@ -88,22 +87,57 @@ public class MediaActionSound { */ public static final int STOP_VIDEO_RECORDING = 3; - private static final int SOUND_NOT_LOADED = -1; + /** + * States for SoundState. + * STATE_NOT_LOADED : sample not loaded + * STATE_LOADING : sample being loaded: waiting for load completion callback + * STATE_LOADING_PLAY_REQUESTED : sample being loaded and playback request received + * STATE_LOADED : sample loaded, ready for playback + */ + private static final int STATE_NOT_LOADED = 0; + private static final int STATE_LOADING = 1; + private static final int STATE_LOADING_PLAY_REQUESTED = 2; + private static final int STATE_LOADED = 3; + + private class SoundState { + public final int name; + public int id; + public int state; + public SoundState(int name) { + this.name = name; + id = 0; // 0 is an invalid sample ID. + state = STATE_NOT_LOADED; + } + } /** * Construct a new MediaActionSound instance. Only a single instance is * needed for playing any platform media action sound; you do not need a * separate instance for each sound type. */ public MediaActionSound() { - mSoundPool = new SoundPool(NUM_MEDIA_SOUND_STREAMS, - AudioManager.STREAM_SYSTEM_ENFORCED, 0); + mSoundPool = new SoundPool.Builder() + .setMaxStreams(NUM_MEDIA_SOUND_STREAMS) + .setAudioAttributes(new AudioAttributes.Builder() + .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION) + .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED) + .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION) + .build()) + .build(); mSoundPool.setOnLoadCompleteListener(mLoadCompleteListener); - mSoundIds = new int[SOUND_FILES.length]; - for (int i = 0; i < mSoundIds.length; i++) { - mSoundIds[i] = SOUND_NOT_LOADED; + mSounds = new SoundState[SOUND_FILES.length]; + for (int i = 0; i < mSounds.length; i++) { + mSounds[i] = new SoundState(i); } - mSoundIdToPlay = SOUND_NOT_LOADED; + } + + private int loadSound(SoundState sound) { + int id = mSoundPool.load(SOUND_FILES[sound.name], 1); + if (id > 0) { + sound.state = STATE_LOADING; + sound.id = id; + } + return id; } /** @@ -118,13 +152,22 @@ public class MediaActionSound { * @see #START_VIDEO_RECORDING * @see #STOP_VIDEO_RECORDING */ - public synchronized void load(int soundName) { + public void load(int soundName) { if (soundName < 0 || soundName >= SOUND_FILES.length) { throw new RuntimeException("Unknown sound requested: " + soundName); } - if (mSoundIds[soundName] == SOUND_NOT_LOADED) { - mSoundIds[soundName] = - mSoundPool.load(SOUND_FILES[soundName], 1); + SoundState sound = mSounds[soundName]; + synchronized (sound) { + switch (sound.state) { + case STATE_NOT_LOADED: + if (loadSound(sound) <= 0) { + Log.e(TAG, "load() error loading sound: " + soundName); + } + break; + default: + Log.e(TAG, "load() called in wrong state: " + sound + " for sound: "+ soundName); + break; + } } } @@ -159,16 +202,31 @@ public class MediaActionSound { * @see #START_VIDEO_RECORDING * @see #STOP_VIDEO_RECORDING */ - public synchronized void play(int soundName) { + public void play(int soundName) { if (soundName < 0 || soundName >= SOUND_FILES.length) { throw new RuntimeException("Unknown sound requested: " + soundName); } - if (mSoundIds[soundName] == SOUND_NOT_LOADED) { - mSoundIdToPlay = - mSoundPool.load(SOUND_FILES[soundName], 1); - mSoundIds[soundName] = mSoundIdToPlay; - } else { - mSoundPool.play(mSoundIds[soundName], 1.0f, 1.0f, 0, 0, 1.0f); + SoundState sound = mSounds[soundName]; + synchronized (sound) { + switch (sound.state) { + case STATE_NOT_LOADED: + loadSound(sound); + if (loadSound(sound) <= 0) { + Log.e(TAG, "play() error loading sound: " + soundName); + break; + } + // FALL THROUGH + + case STATE_LOADING: + sound.state = STATE_LOADING_PLAY_REQUESTED; + break; + case STATE_LOADED: + mSoundPool.play(sound.id, 1.0f, 1.0f, 0, 0, 1.0f); + break; + default: + Log.e(TAG, "play() called in wrong state: " + sound.state + " for sound: "+ soundName); + break; + } } } @@ -176,14 +234,37 @@ public class MediaActionSound { new SoundPool.OnLoadCompleteListener() { public void onLoadComplete(SoundPool soundPool, int sampleId, int status) { - if (status == 0) { - if (mSoundIdToPlay == sampleId) { - soundPool.play(sampleId, 1.0f, 1.0f, 0, 0, 1.0f); - mSoundIdToPlay = SOUND_NOT_LOADED; + for (SoundState sound : mSounds) { + if (sound.id != sampleId) { + continue; } - } else { - Log.e(TAG, "Unable to load sound for playback (status: " + - status + ")"); + int playSoundId = 0; + synchronized (sound) { + if (status != 0) { + sound.state = STATE_NOT_LOADED; + sound.id = 0; + Log.e(TAG, "OnLoadCompleteListener() error: " + status + + " loading sound: "+ sound.name); + return; + } + switch (sound.state) { + case STATE_LOADING: + sound.state = STATE_LOADED; + break; + case STATE_LOADING_PLAY_REQUESTED: + playSoundId = sound.id; + sound.state = STATE_LOADED; + break; + default: + Log.e(TAG, "OnLoadCompleteListener() called in wrong state: " + + sound.state + " for sound: "+ sound.name); + break; + } + } + if (playSoundId != 0) { + soundPool.play(playSoundId, 1.0f, 1.0f, 0, 0, 1.0f); + } + break; } } }; @@ -195,6 +276,12 @@ public class MediaActionSound { */ public void release() { if (mSoundPool != null) { + for (SoundState sound : mSounds) { + synchronized (sound) { + sound.state = STATE_NOT_LOADED; + sound.id = 0; + } + } mSoundPool.release(); mSoundPool = null; } diff --git a/media/java/android/media/MediaExtractor.java b/media/java/android/media/MediaExtractor.java index 177344a0ed4c..24a400e48189 100644 --- a/media/java/android/media/MediaExtractor.java +++ b/media/java/android/media/MediaExtractor.java @@ -275,16 +275,23 @@ final public class MediaExtractor { return initDataMap.get(schemeUuid); } }; - } else if (formatMap.containsKey("crypto-key")) { - ByteBuffer buf = (ByteBuffer) formatMap.get("crypto-key"); - buf.rewind(); - final byte[] data = new byte[buf.remaining()]; - buf.get(data); - return new DrmInitData() { - public SchemeInitData get(UUID schemeUuid) { - return new DrmInitData.SchemeInitData("webm", data); + } else { + int numTracks = getTrackCount(); + for (int i = 0; i < numTracks; ++i) { + Map<String, Object> trackFormatMap = getTrackFormatNative(i); + if (!trackFormatMap.containsKey("crypto-key")) { + continue; } - }; + ByteBuffer buf = (ByteBuffer) trackFormatMap.get("crypto-key"); + buf.rewind(); + final byte[] data = new byte[buf.remaining()]; + buf.get(data); + return new DrmInitData() { + public SchemeInitData get(UUID schemeUuid) { + return new DrmInitData.SchemeInitData("webm", data); + } + }; + } } return null; } diff --git a/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java index c1805cb5713f..7c6adadc2c6a 100644 --- a/media/java/android/media/browse/MediaBrowser.java +++ b/media/java/android/media/browse/MediaBrowser.java @@ -72,7 +72,7 @@ public final class MediaBrowser { /** * Used as an int extra field to denote the page number to subscribe. - * The value of {@code EXTRA_PAGE} should be greater than or equal to 1. + * The value of {@code EXTRA_PAGE} should be greater than or equal to 0. * * @see #EXTRA_PAGE_SIZE */ diff --git a/media/java/android/media/browse/MediaBrowserUtils.java b/media/java/android/media/browse/MediaBrowserUtils.java index b06e598a63d1..2943e60dbbbd 100644 --- a/media/java/android/media/browse/MediaBrowserUtils.java +++ b/media/java/android/media/browse/MediaBrowserUtils.java @@ -50,7 +50,7 @@ public class MediaBrowserUtils { startIndex1 = 0; endIndex1 = Integer.MAX_VALUE; } else { - startIndex1 = pageSize1 * (page1 - 1); + startIndex1 = pageSize1 * page1; endIndex1 = startIndex1 + pageSize1 - 1; } @@ -58,7 +58,7 @@ public class MediaBrowserUtils { startIndex2 = 0; endIndex2 = Integer.MAX_VALUE; } else { - startIndex2 = pageSize2 * (page2 - 1); + startIndex2 = pageSize2 * page2; endIndex2 = startIndex2 + pageSize2 - 1; } diff --git a/media/java/android/media/midi/IMidiDeviceServer.aidl b/media/java/android/media/midi/IMidiDeviceServer.aidl index c2cc2b9f9379..d5115de4a048 100644 --- a/media/java/android/media/midi/IMidiDeviceServer.aidl +++ b/media/java/android/media/midi/IMidiDeviceServer.aidl @@ -28,7 +28,8 @@ interface IMidiDeviceServer void closeDevice(); // connects the input port pfd to the specified output port - void connectPorts(IBinder token, in ParcelFileDescriptor pfd, int outputPortNumber); + // Returns the PID of the called process. + int connectPorts(IBinder token, in ParcelFileDescriptor pfd, int outputPortNumber); MidiDeviceInfo getDeviceInfo(); void setDeviceInfo(in MidiDeviceInfo deviceInfo); diff --git a/media/java/android/media/midi/MidiDevice.java b/media/java/android/media/midi/MidiDevice.java index e1990cd6fbbb..e4588fe3abc5 100644 --- a/media/java/android/media/midi/MidiDevice.java +++ b/media/java/android/media/midi/MidiDevice.java @@ -19,6 +19,7 @@ package android.media.midi; import android.os.Binder; import android.os.IBinder; import android.os.ParcelFileDescriptor; +import android.os.Process; import android.os.RemoteException; import android.util.Log; @@ -181,9 +182,16 @@ public final class MidiDevice implements Closeable { } try { IBinder token = new Binder(); - mDeviceServer.connectPorts(token, pfd, outputPortNumber); - // close our copy of the file descriptor - IoUtils.closeQuietly(pfd); + int calleePid = mDeviceServer.connectPorts(token, pfd, outputPortNumber); + // If the service is a different Process then it will duplicate the pfd + // and we can safely close this one. + // But if the service is in the same Process then closing the pfd will + // kill the connection. So don't do that. + if (calleePid != Process.myPid()) { + // close our copy of the file descriptor + IoUtils.closeQuietly(pfd); + } + return new MidiConnection(token, inputPort); } catch (RemoteException e) { Log.e(TAG, "RemoteException in connectPorts"); diff --git a/media/java/android/media/midi/MidiDeviceServer.java b/media/java/android/media/midi/MidiDeviceServer.java index 19ff62460155..f0abf711ba16 100644 --- a/media/java/android/media/midi/MidiDeviceServer.java +++ b/media/java/android/media/midi/MidiDeviceServer.java @@ -254,7 +254,7 @@ public final class MidiDeviceServer implements Closeable { } @Override - public void connectPorts(IBinder token, ParcelFileDescriptor pfd, + public int connectPorts(IBinder token, ParcelFileDescriptor pfd, int outputPortNumber) { MidiInputPort inputPort = new MidiInputPort(pfd, outputPortNumber); MidiDispatcher dispatcher = mOutputPortDispatchers[outputPortNumber]; @@ -270,6 +270,7 @@ public final class MidiDeviceServer implements Closeable { synchronized (mPortClients) { mPortClients.put(token, client); } + return Process.myPid(); // for caller to detect same process ID } @Override diff --git a/media/java/android/service/media/MediaBrowserService.java b/media/java/android/service/media/MediaBrowserService.java index ae8663269bd3..6954045574a5 100644 --- a/media/java/android/service/media/MediaBrowserService.java +++ b/media/java/android/service/media/MediaBrowserService.java @@ -657,9 +657,9 @@ public abstract class MediaBrowserService extends Service { if (page == -1 && pageSize == -1) { return list; } - int fromIndex = pageSize * (page - 1); + int fromIndex = pageSize * page; int toIndex = fromIndex + pageSize; - if (page < 1 || pageSize < 1 || fromIndex >= list.size()) { + if (page < 0 || pageSize < 1 || fromIndex >= list.size()) { return Collections.EMPTY_LIST; } if (toIndex > list.size()) { diff --git a/media/jni/android_mtp_MtpDatabase.cpp b/media/jni/android_mtp_MtpDatabase.cpp index 5722cb013026..39f2a326f543 100644 --- a/media/jni/android_mtp_MtpDatabase.cpp +++ b/media/jni/android_mtp_MtpDatabase.cpp @@ -882,7 +882,7 @@ MtpResponseCode MyMtpDatabase::getObjectInfo(MtpObjectHandle handle, break; } - info.mThumbCompressedSize = image_data.thumbnail_length; + info.mThumbCompressedSize = image_data.thumbnail.length; info.mThumbFormat = MTP_FORMAT_EXIF_JPEG; info.mImagePixWidth = image_data.full_width; info.mImagePixHeight = image_data.full_height; @@ -932,19 +932,19 @@ void* MyMtpDatabase::getThumbnail(MtpObjectHandle handle, size_t& outThumbSize) break; } - if (image_data.thumbnail_length == 0) { + if (image_data.thumbnail.length == 0) { // No thumbnail. break; } - result = malloc(image_data.thumbnail_length); + result = malloc(image_data.thumbnail.length); if (result) { piex::Error err = stream.get()->GetData( - image_data.thumbnail_offset, - image_data.thumbnail_length, + image_data.thumbnail.offset, + image_data.thumbnail.length, (std::uint8_t *)result); if (err == piex::Error::kOk) { - outThumbSize = image_data.thumbnail_length; + outThumbSize = image_data.thumbnail.length; } else { free(result); } diff --git a/packages/CtsShim/Android.mk b/packages/CtsShim/Android.mk new file mode 100644 index 000000000000..537b1714ba71 --- /dev/null +++ b/packages/CtsShim/Android.mk @@ -0,0 +1,61 @@ +# +# Copyright (C) 2016 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. +# + +LOCAL_PATH := $(call my-dir) + +########################################################### +# Variant: Privileged app + +include $(CLEAR_VARS) +# this needs to be a privileged application +LOCAL_PRIVILEGED_MODULE := true + +LOCAL_MODULE_TAGS := optional +LOCAL_SDK_VERSION := current +LOCAL_PROGUARD_ENABLED := disabled +LOCAL_DEX_PREOPT := false + +LOCAL_PACKAGE_NAME := CtsShimPriv + +#TODO need to find the correct certificate +#Change in conjunction with cts/hostsidetests/appsecurity/test-apps/IntentFilterApp +LOCAL_CERTIFICATE := platform +LOCAL_MANIFEST_FILE := priv_shim/AndroidManifest.xml + +include $(BUILD_PACKAGE) + + + +########################################################### +# Variant: System app + +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := optional +LOCAL_SDK_VERSION := current +LOCAL_PROGUARD_ENABLED := disabled +LOCAL_DEX_PREOPT := false + +LOCAL_PACKAGE_NAME := CtsShim + +#TODO need to find the correct certificate +#Change in conjunction with cts/hostsidetests/appsecurity/test-apps/IntentFilterApp +LOCAL_CERTIFICATE := platform +LOCAL_MANIFEST_FILE := shim/AndroidManifest.xml + +include $(BUILD_PACKAGE) + + diff --git a/packages/CtsShim/priv_shim/AndroidManifest.xml b/packages/CtsShim/priv_shim/AndroidManifest.xml new file mode 100644 index 000000000000..0a3f8235948c --- /dev/null +++ b/packages/CtsShim/priv_shim/AndroidManifest.xml @@ -0,0 +1,157 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 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. +--> + +<!-- Manifest for the privileged CTS shim --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.cts.priv.ctsshim"> + <application android:label="CtsShim"> + + <!-- These activities don't actually exist; define them just to test the filters !--> + + <!-- install test; [some] high priority filters granted --> + <activity android:name=".InstallPriority"> + <!-- normal actions; priority will be granted --> + <intent-filter android:priority="100"> + <action android:name="android.intent.action.SEARCH" /> + <category android:name="android.intent.category.INFO" /> + </intent-filter> + + <!-- protected actions; priority will be denied --> + <intent-filter android:priority="100"> + <action android:name="android.intent.action.VIEW" /> + <category android:name="android.intent.category.BROWSABLE" /> + </intent-filter> + <intent-filter android:priority="100"> + <action android:name="android.intent.action.SEND" /> + </intent-filter> + <intent-filter android:priority="100"> + <action android:name="android.intent.action.SEND_MULTIPLE" /> + </intent-filter> + <intent-filter android:priority="100"> + <action android:name="android.intent.action.SENDTO" /> + </intent-filter> + </activity> + + <!-- upgrade test; single, equivalent filter --> + <activity android:name=".UpgradeMatch"> + <intent-filter android:priority="100"> + <action android:name="com.android.cts.action.MATCH" /> + <category android:name="android.intent.category.INFO" /> + </intent-filter> + </activity> + + <!-- upgrade test; multiple, equivalent filters --> + <activity android:name=".UpgradeMatchMultiple"> + <intent-filter android:priority="100"> + <action android:name="com.android.cts.action.MATCH_MULTIPLE" /> + <category android:name="android.intent.category.INFO" /> + </intent-filter> + + <intent-filter android:priority="150"> + <action android:name="com.android.cts.action.MATCH_MULTIPLE" /> + <category android:name="android.intent.category.DEFAULT" /> + <data android:scheme="http" /> + <data android:scheme="https" /> + <data android:host="www.google.com" android:port="80" /> + <data android:host="www.google.com" android:port="8080" /> + <data android:host="goo.gl" android:port="443" /> + </intent-filter> + </activity> + + <!-- upgrade test; lower priority --> + <activity android:name=".UpgradeLowerPriority"> + <intent-filter android:priority="100"> + <action android:name="com.android.cts.action.LOWER_PRIORITY" /> + <category android:name="android.intent.category.INFO" /> + </intent-filter> + </activity> + + <!-- upgrade test; action subset --> + <activity android:name=".UpgradeActionSubset"> + <intent-filter android:priority="100"> + <action android:name="com.android.cts.action.ACTION_SUB" /> + <action android:name="com.android.cts.action.ACTION_SUB_2" /> + <action android:name="com.android.cts.action.ACTION_SUB_3" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + <!-- upgrade test; category subset --> + <activity android:name=".UpgradeCategorySubset"> + <intent-filter android:priority="100"> + <action android:name="com.android.cts.action.CATEGORY_SUB" /> + <category android:name="android.intent.category.INFO" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + <!-- upgrade test; scheme subset --> + <activity android:name=".UpgradeSchemeSubset"> + <intent-filter android:priority="100"> + <action android:name="com.android.cts.action.SCHEME_SUB" /> + <data android:scheme="content" /> + <data android:scheme="flubber" /> + <data android:scheme="zoodle" /> + </intent-filter> + </activity> + + <!-- upgrade test; authority subset --> + <activity android:name=".UpgradeAuthoritySubset"> + <intent-filter android:priority="100"> + <action android:name="com.android.cts.action.AUTHORITY_SUB" /> + <data android:host="www.google.com" android:port="80" /> + <data android:host="www.google.com" android:port="8080" /> + <data android:host="mail.google.com" android:port="80" /> + <data android:host="goo.gl" android:port="443" /> + </intent-filter> + </activity> + + + <!-- upgrade test; new action --> + <activity android:name=".UpgradeNewAction"> + <intent-filter android:priority="100"> + <action android:name="com.android.cts.action.NEW_ACTION" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + <!-- upgrade test; new category --> + <activity android:name=".UpgradeNewCategory"> + <intent-filter android:priority="100"> + <action android:name="com.android.cts.action.NEW_CATEGORY" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + </activity> + + <!-- upgrade test; new scheme --> + <activity android:name=".UpgradeNewScheme"> + <intent-filter android:priority="100"> + <action android:name="com.android.cts.action.NEW_SCHEME" /> + <data android:scheme="content" /> + </intent-filter> + </activity> + + <!-- upgrade test; new authority --> + <activity android:name=".UpgradeNewAuthority"> + <intent-filter android:priority="100"> + <action android:name="com.android.cts.action.NEW_AUTHORITY" /> + <data android:host="www.google.com" android:port="80" /> + </intent-filter> + </activity> + + </application> +</manifest> + diff --git a/packages/CtsShim/shim/AndroidManifest.xml b/packages/CtsShim/shim/AndroidManifest.xml new file mode 100644 index 000000000000..ee4b547ddc97 --- /dev/null +++ b/packages/CtsShim/shim/AndroidManifest.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 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. +--> + +<!-- Manifest for the system CTS shim --> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.cts.system.ctsshim"> + <application android:label="CtsShim"> + + <!-- These activities don't actually exist; define them just to test the filters !--> + + <!-- install test; high priority filter DENIED --> + <activity android:name=".InstallPriority"> + <intent-filter android:priority="100"> + <action android:name="android.intent.action.SEARCH" /> + <category android:name="android.intent.category.INFO" /> + </intent-filter> + <intent-filter android:priority="100"> + <action android:name="android.intent.action.VIEW" /> + <category android:name="android.intent.category.BROWSABLE" /> + </intent-filter> + <intent-filter android:priority="100"> + <action android:name="android.intent.action.SEND" /> + </intent-filter> + <intent-filter android:priority="100"> + <action android:name="android.intent.action.SEND_MULTIPLE" /> + </intent-filter> + <intent-filter android:priority="100"> + <action android:name="android.intent.action.SENDTO" /> + </intent-filter> + </activity> + + </application> +</manifest> + diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml index 14609b21d19d..69912ab12098 100644 --- a/packages/DocumentsUI/AndroidManifest.xml +++ b/packages/DocumentsUI/AndroidManifest.xml @@ -43,9 +43,9 @@ <activity android:name=".LauncherActivity" - android:theme="@android:style/Theme.NoDisplay" - android:icon="@mipmap/ic_launcher_download" - android:label="@string/downloads_label"> + android:label="@string/downloads_label" + android:icon="@mipmap/ic_launcher_downloads" + android:theme="@android:style/Theme.NoDisplay"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> @@ -54,21 +54,21 @@ <activity android:name=".FilesActivity" - android:theme="@style/DocumentsTheme" - android:icon="@mipmap/ic_launcher_download" android:label="@string/downloads_label" - android:documentLaunchMode="intoExisting"> + android:icon="@mipmap/ic_launcher_downloads" + android:documentLaunchMode="intoExisting" + android:theme="@style/DocumentsTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> </intent-filter> <intent-filter> - <action android:name="android.intent.action.VIEW_DOWNLOADS" /> + <action android:name="android.provider.action.BROWSE" /> <category android:name="android.intent.category.DEFAULT" /> + <data android:mimeType="vnd.android.document/root" /> </intent-filter> <intent-filter> - <action android:name="android.provider.action.BROWSE" /> + <action android:name="android.intent.action.VIEW_DOWNLOADS" /> <category android:name="android.intent.category.DEFAULT" /> - <data android:mimeType="vnd.android.document/root" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> diff --git a/packages/DocumentsUI/app-perf-tests/AndroidManifest.xml b/packages/DocumentsUI/app-perf-tests/AndroidManifest.xml index 1c3ed80adc2f..0013b6b7be7e 100644 --- a/packages/DocumentsUI/app-perf-tests/AndroidManifest.xml +++ b/packages/DocumentsUI/app-perf-tests/AndroidManifest.xml @@ -2,6 +2,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.documentsui.appperftests"> + <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" /> + <application> <uses-library android:name="android.test.runner" /> diff --git a/packages/DocumentsUI/app-perf-tests/src/com/android/documentsui/FilesAppPerfTest.java b/packages/DocumentsUI/app-perf-tests/src/com/android/documentsui/FilesAppPerfTest.java index d6e8a96f3ad1..ce2fc13bc55a 100644 --- a/packages/DocumentsUI/app-perf-tests/src/com/android/documentsui/FilesAppPerfTest.java +++ b/packages/DocumentsUI/app-perf-tests/src/com/android/documentsui/FilesAppPerfTest.java @@ -17,6 +17,8 @@ package com.android.documentsui; import android.app.Activity; +import android.app.ActivityManager; +import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; @@ -91,12 +93,15 @@ public class FilesAppPerfTest extends InstrumentationTestCase { } private void killProviders() throws Exception { - final PackageManager pm = getInstrumentation().getContext().getPackageManager(); + final Context context = getInstrumentation().getContext(); + final PackageManager pm = context.getPackageManager(); + final ActivityManager am = (ActivityManager) context.getSystemService( + Context.ACTIVITY_SERVICE); final Intent intent = new Intent(DocumentsContract.PROVIDER_INTERFACE); final List<ResolveInfo> providers = pm.queryIntentContentProviders(intent, 0); for (ResolveInfo info : providers) { final String packageName = info.providerInfo.packageName; - mDevice.executeShellCommand("am force-stop " + packageName); + am.killBackgroundProcesses(packageName); } } } diff --git a/packages/DocumentsUI/res/drawable/drag_shadow_background.xml b/packages/DocumentsUI/res/drawable/drag_shadow_background.xml new file mode 100644 index 000000000000..49465cbabe3c --- /dev/null +++ b/packages/DocumentsUI/res/drawable/drag_shadow_background.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 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. +--> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:shape="rectangle"> + <solid android:color="@color/item_doc_background" /> + <stroke + android:width="1dp" + android:color="#ff9f9f9f" /> + <corners + android:bottomRightRadius="3dp" + android:bottomLeftRadius="3dp" + android:topLeftRadius="3dp" + android:topRightRadius="3dp"/> +</shape> diff --git a/packages/DocumentsUI/res/layout/drag_shadow_layout.xml b/packages/DocumentsUI/res/layout/drag_shadow_layout.xml new file mode 100644 index 000000000000..26613efddf14 --- /dev/null +++ b/packages/DocumentsUI/res/layout/drag_shadow_layout.xml @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 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. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingStart="8dp" + android:paddingEnd="8dp" + android:orientation="horizontal" + android:gravity="center_vertical|left" + android:background="@drawable/drag_shadow_background"> + + <ImageView + android:id="@android:id/icon" + android:layout_width="@dimen/root_icon_size" + android:layout_height="@dimen/root_icon_size" + android:scaleType="centerInside" + android:contentDescription="@null" + android:duplicateParentState="true"/> + + <TextView + android:id="@android:id/title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:maxLines="1" + android:ellipsize="end" + android:textAlignment="viewStart" + android:textColor="@color/item_title" + android:paddingStart="8dp"/> + +</LinearLayout> diff --git a/packages/DocumentsUI/res/mipmap-hdpi/ic_launcher_download.png b/packages/DocumentsUI/res/mipmap-hdpi/ic_launcher_downloads.png Binary files differindex f958bbd3c255..f958bbd3c255 100644 --- a/packages/DocumentsUI/res/mipmap-hdpi/ic_launcher_download.png +++ b/packages/DocumentsUI/res/mipmap-hdpi/ic_launcher_downloads.png diff --git a/packages/DocumentsUI/res/mipmap-mdpi/ic_launcher_download.png b/packages/DocumentsUI/res/mipmap-mdpi/ic_launcher_downloads.png Binary files differindex f2e937663c2c..f2e937663c2c 100644 --- a/packages/DocumentsUI/res/mipmap-mdpi/ic_launcher_download.png +++ b/packages/DocumentsUI/res/mipmap-mdpi/ic_launcher_downloads.png diff --git a/packages/DocumentsUI/res/mipmap-xhdpi/ic_launcher_download.png b/packages/DocumentsUI/res/mipmap-xhdpi/ic_launcher_downloads.png Binary files differindex 4dc533638757..4dc533638757 100644 --- a/packages/DocumentsUI/res/mipmap-xhdpi/ic_launcher_download.png +++ b/packages/DocumentsUI/res/mipmap-xhdpi/ic_launcher_downloads.png diff --git a/packages/DocumentsUI/res/mipmap-xxhdpi/ic_launcher_download.png b/packages/DocumentsUI/res/mipmap-xxhdpi/ic_launcher_downloads.png Binary files differindex 8716290969da..8716290969da 100644 --- a/packages/DocumentsUI/res/mipmap-xxhdpi/ic_launcher_download.png +++ b/packages/DocumentsUI/res/mipmap-xxhdpi/ic_launcher_downloads.png diff --git a/packages/DocumentsUI/res/mipmap-xxxhdpi/ic_launcher_download.png b/packages/DocumentsUI/res/mipmap-xxxhdpi/ic_launcher_downloads.png Binary files differindex f5be21991761..f5be21991761 100644 --- a/packages/DocumentsUI/res/mipmap-xxxhdpi/ic_launcher_download.png +++ b/packages/DocumentsUI/res/mipmap-xxxhdpi/ic_launcher_downloads.png diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml index 75d9b4b63b2e..1a7c6205cd2c 100644 --- a/packages/DocumentsUI/res/values-af/strings.xml +++ b/packages/DocumentsUI/res/values-af/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Kon nie dokument hernoem nie"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sommige lêers is omgeskakel"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-gids op <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-gids?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Gee <xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang tot jou data, insluitend foto\'s en video\'s, op <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Moenie weer vra nie"</string> <string name="allow" msgid="7225948811296386551">"Laat toe"</string> diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml index 922b9cae0489..ca43dab34477 100644 --- a/packages/DocumentsUI/res/values-am/strings.xml +++ b/packages/DocumentsUI/res/values-am/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"ሰነዱን ዳግም መሰየም አልተሳካም"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"አንዳንድ ፋይሎች ተለውጠዋል"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> በ<xliff:g id="STORAGE"><i>^3</i></xliff:g> ላይ የ<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ማውጫ መደረሻ ይሰጠው?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"የ<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ማውጫ መዳረሻ ለ<xliff:g id="APPNAME"><b>^1</b></xliff:g> ይሰጠው?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"በ<xliff:g id="STORAGE"><i>^2</i></xliff:g> ላይ ያሉትን ፎቶዎች እና ቪዲዮዎች ጨምሮ የውሂብዎ መዳረሻ ለ<xliff:g id="APPNAME"><b>^1</b></xliff:g> ይሰጥ?"</string> <string name="never_ask_again" msgid="4295278542972859268">"ዳግም አትጠይቅ"</string> <string name="allow" msgid="7225948811296386551">"ይፍቀዱ"</string> diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml index f48c542ce3af..e6fac5093698 100644 --- a/packages/DocumentsUI/res/values-ar/strings.xml +++ b/packages/DocumentsUI/res/values-ar/strings.xml @@ -139,6 +139,7 @@ <string name="rename_error" msgid="4203041674883412606">"أخفقت إعادة تسمية المستند."</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"تم تحويل بعض الملفات"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"هل تريد منح التطبيق <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى الدليل <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> على <xliff:g id="STORAGE"><i>^3</i></xliff:g>؟"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"هل تريد تمكين <xliff:g id="APPNAME"><b>^1</b></xliff:g> من الدخول إلى دليل <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>؟"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"هل تريد منح <xliff:g id="APPNAME"><b>^1</b></xliff:g> حق الوصول إلى بياناتك، بما في ذلك الصور ومقاطع الفيديو على <xliff:g id="STORAGE"><i>^2</i></xliff:g>؟"</string> <string name="never_ask_again" msgid="4295278542972859268">"عدم السؤال مرة أخرى"</string> <string name="allow" msgid="7225948811296386551">"السماح"</string> diff --git a/packages/DocumentsUI/res/values-az-rAZ/strings.xml b/packages/DocumentsUI/res/values-az-rAZ/strings.xml index a4d6f518dd63..75a0686c7ffd 100644 --- a/packages/DocumentsUI/res/values-az-rAZ/strings.xml +++ b/packages/DocumentsUI/res/values-az-rAZ/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Sənəd adını dəyişmək uğursuz oldu"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Bəzi fayllar konvertasiya edilib"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> yaddaşında <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kataloquna <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təqdim edilsin?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kataloquna <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təqdim edilsin?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> yaddaşında foto və videolar daxil olmaqla datanıza <xliff:g id="APPNAME"><b>^1</b></xliff:g> girişi təmin edilsin?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Bir daha soruşmayın"</string> <string name="allow" msgid="7225948811296386551">"İcazə verin"</string> diff --git a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml index 2c4fe5c89c2f..34c08bddfc14 100644 --- a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml +++ b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml @@ -118,6 +118,7 @@ <string name="rename_error" msgid="4203041674883412606">"Preimenovanje dokumenta nije uspelo"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke datoteke su konvertovane"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Želite li da aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobrite pristup direktorijumu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> na memorijskom prostoru <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Želite da dozvolite da <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristupa direktorijumu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Želite da li da dozvolite da aplikacija <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristupa podacima, uključujući slike i video snimke, na lokaciji <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Ne pitaj ponovo"</string> <string name="allow" msgid="7225948811296386551">"Dozvoli"</string> diff --git a/packages/DocumentsUI/res/values-be-rBY/strings.xml b/packages/DocumentsUI/res/values-be-rBY/strings.xml index 6e4113e8e0b1..8493c4772039 100644 --- a/packages/DocumentsUI/res/values-be-rBY/strings.xml +++ b/packages/DocumentsUI/res/values-be-rBY/strings.xml @@ -125,6 +125,7 @@ <string name="rename_error" msgid="4203041674883412606">"Не атрымалася перайменаваць дакумент"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Некаторыя файлы былі сканвертаваныя"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Даць праграме <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да дырэкторыі <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> у <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Даць праграме <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да дырэкторыі <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Даць <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ да вашых даных, у тым ліку фатаграфій і відэа, на <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Больш не пытацца"</string> <string name="allow" msgid="7225948811296386551">"Дазволіць"</string> diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml index 4b24a0e43e88..1914bf52bbbb 100644 --- a/packages/DocumentsUI/res/values-bg/strings.xml +++ b/packages/DocumentsUI/res/values-bg/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Преименуването на документа не бе успешно"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Някои файлове бяха преобразувани"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до директорията „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ в/ъв <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до директорията „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Да се предостави ли на <xliff:g id="APPNAME"><b>^1</b></xliff:g> достъп до данните ви в хранилището (<xliff:g id="STORAGE"><i>^2</i></xliff:g>), включително снимки и видеоклипове?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Без повторно питане"</string> <string name="allow" msgid="7225948811296386551">"Разрешаване"</string> diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml index 79cd38264be8..d931c2b094c2 100644 --- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml +++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"দস্তাবেজের পুনঃনামকরণ ব্যর্থ হয়েছে৷"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"কিছু ফাইল রূপান্তরিত হয়েছে"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> কে <xliff:g id="STORAGE"><i>^3</i></xliff:g> এ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> সংগ্রহ অ্যাক্সেস করার মঞ্জুরি দিতে চান?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> কে <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> সংগ্রহ অ্যাক্সেস করার অনুমতি দেবেন?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> এ থাকা ফটো ও ভিডিওগুলি সমেত <xliff:g id="APPNAME"><b>^1</b></xliff:g> কে আপনার ডেটা অ্যাক্সেস করার অনুমতি দেবেন?"</string> <string name="never_ask_again" msgid="4295278542972859268">"আর জিজ্ঞাসা করবেন না"</string> <string name="allow" msgid="7225948811296386551">"অনুমতি দিন"</string> diff --git a/packages/DocumentsUI/res/values-bs-rBA/strings.xml b/packages/DocumentsUI/res/values-bs-rBA/strings.xml index 14d6716abd3c..47ff43697c9c 100644 --- a/packages/DocumentsUI/res/values-bs-rBA/strings.xml +++ b/packages/DocumentsUI/res/values-bs-rBA/strings.xml @@ -118,6 +118,7 @@ <string name="rename_error" msgid="4203041674883412606">"Nije uspjelo preimenovanje dokumenta"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke od datoteka su pretvorene"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Omogućiti <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sa <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Odobriti aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Želite li odobriti aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> pristup svojim podacima, uključujući fotografije i video zapise, na <xliff:g id="STORAGE"><i>^2</i></xliff:g> ?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Ne pitaj ponovo"</string> <string name="allow" msgid="7225948811296386551">"Dozvoli"</string> diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml index 73998b17cf1b..09af97d88c7e 100644 --- a/packages/DocumentsUI/res/values-ca/strings.xml +++ b/packages/DocumentsUI/res/values-ca/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"No s\'ha pogut canviar el nom del document"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"S\'han convertit alguns fitxers"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés al directori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> de l\'emmagatzematge <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés al directori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vols que l\'aplicació <xliff:g id="APPNAME"><b>^1</b></xliff:g> tingui accés a les dades de <xliff:g id="STORAGE"><i>^2</i></xliff:g>, incloses les fotos i els vídeos?"</string> <string name="never_ask_again" msgid="4295278542972859268">"No m\'ho demanis més"</string> <string name="allow" msgid="7225948811296386551">"Permet"</string> diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml index ffabe77fe98e..cba2e0edb6bd 100644 --- a/packages/DocumentsUI/res/values-cs/strings.xml +++ b/packages/DocumentsUI/res/values-cs/strings.xml @@ -125,6 +125,7 @@ <string name="rename_error" msgid="4203041674883412606">"Dokument se nepodařilo přejmenovat."</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Některé soubory byly převedeny"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup k adresáři <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v úložišti <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup k adresáři <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Chcete aplikaci <xliff:g id="APPNAME"><b>^1</b></xliff:g> udělit přístup ke svým datům v úložišti <xliff:g id="STORAGE"><i>^2</i></xliff:g>, včetně fotek a videí?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Příště se neptat"</string> <string name="allow" msgid="7225948811296386551">"Povolit"</string> diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml index bf328ab0c8d6..f048e34863d2 100644 --- a/packages/DocumentsUI/res/values-da/strings.xml +++ b/packages/DocumentsUI/res/values-da/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Dokumentet kunne ikke omdøbes"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Nogle filer er konverteret"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til mappen <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til indekset <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vil du give <xliff:g id="APPNAME"><b>^1</b></xliff:g> adgang til dine data, herunder billeder og videoer på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Spørg ikke igen"</string> <string name="allow" msgid="7225948811296386551">"Tillad"</string> diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml index 9ccb56490512..a6eae703c198 100644 --- a/packages/DocumentsUI/res/values-de/strings.xml +++ b/packages/DocumentsUI/res/values-de/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Dokument konnte nicht umbenannt werden"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Einige Dateien wurden konvertiert"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf das Verzeichnis <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> auf <xliff:g id="STORAGE"><i>^3</i></xliff:g> geben?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Möchtest du <xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf das Verzeichnis <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> geben?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Möchtest du <xliff:g id="APPNAME"><b>^1</b></xliff:g> Zugriff auf deine Daten auf <xliff:g id="STORAGE"><i>^2</i></xliff:g> geben, einschließlich Fotos und Videos?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Nicht mehr fragen"</string> <string name="allow" msgid="7225948811296386551">"Zulassen"</string> diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml index f23a35d539d4..7dc20670aed8 100644 --- a/packages/DocumentsUI/res/values-el/strings.xml +++ b/packages/DocumentsUI/res/values-el/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Αποτυχία μετονομασίας εγγράφου"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Ορισμένα αρχεία μετατράπηκαν"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Να εκχωρηθεί στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g> πρόσβαση στον κατάλογο <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> στον αποθηκευτικό χώρο <xliff:g id="STORAGE"><i>^3</i></xliff:g>;"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Εκχώρηση πρόσβασης στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g> στον κατάλογο <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>;"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Θέλετε να εκχωρήσετε πρόσβαση στα δεδομένα σας στην εφαρμογή <xliff:g id="APPNAME"><b>^1</b></xliff:g>, συμπεριλαμβανομένων των φωτογραφιών και των βίντεό σας, στον αποθηκευτικό χώρο <xliff:g id="STORAGE"><i>^2</i></xliff:g>;"</string> <string name="never_ask_again" msgid="4295278542972859268">"Να μην ερωτηθώ ξανά"</string> <string name="allow" msgid="7225948811296386551">"Να επιτρέπεται"</string> diff --git a/packages/DocumentsUI/res/values-en-rAU/strings.xml b/packages/DocumentsUI/res/values-en-rAU/strings.xml index f82f988afadc..8524de5d67cc 100644 --- a/packages/DocumentsUI/res/values-en-rAU/strings.xml +++ b/packages/DocumentsUI/res/values-en-rAU/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Some files were converted"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Don\'t ask again"</string> <string name="allow" msgid="7225948811296386551">"Allow"</string> diff --git a/packages/DocumentsUI/res/values-en-rGB/strings.xml b/packages/DocumentsUI/res/values-en-rGB/strings.xml index f82f988afadc..8524de5d67cc 100644 --- a/packages/DocumentsUI/res/values-en-rGB/strings.xml +++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Some files were converted"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Don\'t ask again"</string> <string name="allow" msgid="7225948811296386551">"Allow"</string> diff --git a/packages/DocumentsUI/res/values-en-rIN/strings.xml b/packages/DocumentsUI/res/values-en-rIN/strings.xml index f82f988afadc..8524de5d67cc 100644 --- a/packages/DocumentsUI/res/values-en-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Failed to rename document"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Some files were converted"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory on <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> directory?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Grant <xliff:g id="APPNAME"><b>^1</b></xliff:g> access to your data, including photos and videos, on <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Don\'t ask again"</string> <string name="allow" msgid="7225948811296386551">"Allow"</string> diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml index 5c823d0a2661..87641a73c065 100644 --- a/packages/DocumentsUI/res/values-es-rUS/strings.xml +++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"No se pudo cambiar el nombre del documento"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Se convirtieron algunos archivos"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"¿Otorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> en <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"¿Quieres otorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"¿Quieres otorgar acceso a la app de <xliff:g id="APPNAME"><b>^1</b></xliff:g> a tus datos, incluidas tus fotos y videos en <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"No volver a preguntar"</string> <string name="allow" msgid="7225948811296386551">"Permitir"</string> diff --git a/packages/DocumentsUI/res/values-es/strings.xml b/packages/DocumentsUI/res/values-es/strings.xml index 60d1d1c91146..9054561c3c45 100644 --- a/packages/DocumentsUI/res/values-es/strings.xml +++ b/packages/DocumentsUI/res/values-es/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Error al cambiar el nombre del documento"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Se han convertido algunos archivos"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> (<xliff:g id="STORAGE"><i>^3</i></xliff:g>)?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda al directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"¿Permitir que <xliff:g id="APPNAME"><b>^1</b></xliff:g> acceda a tus datos, incluidos los vídeos y las fotos, de <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"No volver a preguntar"</string> <string name="allow" msgid="7225948811296386551">"Permitir"</string> diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml index 0fdc435c0c4f..4bb2a9b79843 100644 --- a/packages/DocumentsUI/res/values-et-rEE/strings.xml +++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Dokumendi ümbernimetamine ebaõnnestus"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Mõned failid teisendati"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs kataloogile <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> salvestusruumis <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs kataloogile <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Kas anda rakendusele <xliff:g id="APPNAME"><b>^1</b></xliff:g> juurdepääs teie andmetele (sh fotod ja videod) salvestusruumis <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Ära enam küsi"</string> <string name="allow" msgid="7225948811296386551">"Luba"</string> diff --git a/packages/DocumentsUI/res/values-eu-rES/strings.xml b/packages/DocumentsUI/res/values-eu-rES/strings.xml index b54e542e289e..d2bf89dc4806 100644 --- a/packages/DocumentsUI/res/values-eu-rES/strings.xml +++ b/packages/DocumentsUI/res/values-eu-rES/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Ezin izan zaio aldatu izena dokumentuari"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Artxibo batzuk bihurtu dira"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari <xliff:g id="STORAGE"><i>^3</i></xliff:g> unitateko <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> direktorioa atzitzeko baimena eman nahi diozu?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> direktoriorako sarbidea eman nahi diozu?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> aplikazioari zure datuak atzitzea baimendu nahi diozu, besteak beste, <xliff:g id="STORAGE"><i>^2</i></xliff:g> biltegian dituzun argazkiak eta bideoak?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Ez galdetu berriro"</string> <string name="allow" msgid="7225948811296386551">"Onartu"</string> diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml index cc7eeb553da3..1a4c035371dd 100644 --- a/packages/DocumentsUI/res/values-fa/strings.xml +++ b/packages/DocumentsUI/res/values-fa/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"نام سند تغییر نکرد"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"بعضی از فایلها تبدیل شدند"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه داده شود به فهرست راهنمای <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> در <xliff:g id="STORAGE"><i>^3</i></xliff:g> دسترسی داشته باشد؟"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه دسترسی به دایرکتوری <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> داده شود؟"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"به <xliff:g id="APPNAME"><b>^1</b></xliff:g> اجازه میدهید به دادههایتان دسترسی پیدا کند، از جمله عکسها و ویدیوهایتان در <xliff:g id="STORAGE"><i>^2</i></xliff:g>؟"</string> <string name="never_ask_again" msgid="4295278542972859268">"دوباره سؤال نشود"</string> <string name="allow" msgid="7225948811296386551">"ارزیابیشده"</string> diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml index 17e4d759c6b0..dfcfe89f384e 100644 --- a/packages/DocumentsUI/res/values-fi/strings.xml +++ b/packages/DocumentsUI/res/values-fi/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Dokumentin nimen muuttaminen epäonnistui."</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Joitakin tiedostoja muunnettiin."</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Myönnetäänkö sovellukselle <xliff:g id="APPNAME"><b>^1</b></xliff:g> sijainnissa <xliff:g id="STORAGE"><i>^3</i></xliff:g> olevan hakemiston <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> käyttöoikeus?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Saako <xliff:g id="APPNAME"><b>^1</b></xliff:g> käyttää hakemistoa <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Myönnetäänkö sovellukselle <xliff:g id="APPNAME"><b>^1</b></xliff:g> sijainnissa <xliff:g id="STORAGE"><i>^2</i></xliff:g> olevien tietojesi, mukaan lukien valokuviesi ja videoidesi, käyttöoikeus?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Älä kysy uudestaan"</string> <string name="allow" msgid="7225948811296386551">"Salli"</string> diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml index 5dbf5ebe2295..543e2260cff3 100644 --- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml +++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Impossible de renommer le document"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Certains fichiers ont été convertis"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Accorder à <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accès au répertoire <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sur <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Accorder à <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accès au répertoire <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Voulez-vous accorder l\'accès à vos données à <xliff:g id="APPNAME"><b>^1</b></xliff:g>, y compris vos photos et vos vidéos, sur <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Ne plus me demander"</string> <string name="allow" msgid="7225948811296386551">"Autoriser"</string> diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml index 127d0da93f46..05716d7f4587 100644 --- a/packages/DocumentsUI/res/values-fr/strings.xml +++ b/packages/DocumentsUI/res/values-fr/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Échec du changement de nom du document."</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Certains fichiers ont été convertis"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à l\'annuaire \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" sur <xliff:g id="STORAGE"><i>^3</i></xliff:g> ?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à l\'annuaire \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" ?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Autoriser <xliff:g id="APPNAME"><b>^1</b></xliff:g> à accéder à vos données, y compris les photos et les vidéos, sur <xliff:g id="STORAGE"><i>^2</i></xliff:g> ?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Ne plus demander"</string> <string name="allow" msgid="7225948811296386551">"Autoriser"</string> diff --git a/packages/DocumentsUI/res/values-gl-rES/strings.xml b/packages/DocumentsUI/res/values-gl-rES/strings.xml index 4cce3c96e16a..5797a9600eea 100644 --- a/packages/DocumentsUI/res/values-gl-rES/strings.xml +++ b/packages/DocumentsUI/res/values-gl-rES/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Non se puido cambiar o nome do documento"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Convertéronse algúns ficheiros"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Queres outorgar acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> ao directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no almacenamento de <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Queres darlle acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> ao directorio <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Queres darlle acceso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> aos teus datos almacenados en <xliff:g id="STORAGE"><i>^2</i></xliff:g>, incluídos vídeos e fotos?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Non preguntar de novo"</string> <string name="allow" msgid="7225948811296386551">"Permitir"</string> diff --git a/packages/DocumentsUI/res/values-gu-rIN/strings.xml b/packages/DocumentsUI/res/values-gu-rIN/strings.xml index 1db54f94c29a..48e43c492023 100644 --- a/packages/DocumentsUI/res/values-gu-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-gu-rIN/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"દસ્તાવેજનું નામ બદલવામાં નિષ્ફળ થયાં"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"કેટલીક ફાઇલો રૂપાંતરિત કરી હતી"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^3</i></xliff:g> પર <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> નિર્દેશિકાની ઍક્સેસ આપીએ?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> નિર્દેશિકાની ઍક્સેસ આપીએ?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ને <xliff:g id="STORAGE"><i>^2</i></xliff:g> પર ફોટા અને વિડિઓઝ સહિત તમારા ડેટાની અૅક્સેસ આપીએ?"</string> <string name="never_ask_again" msgid="4295278542972859268">"ફરીથી પૂછશો નહીં"</string> <string name="allow" msgid="7225948811296386551">"મંજૂરી આપો"</string> diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml index de1e25e568ef..fa82ee8d13e3 100644 --- a/packages/DocumentsUI/res/values-hi/strings.xml +++ b/packages/DocumentsUI/res/values-hi/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"दस्तावेज़ का नाम बदलना विफल रहा"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"कुछ फ़ाइलें रूपांतरित हो गई थीं"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^3</i></xliff:g> पर <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिका का एक्सेस दें?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिका का एक्सेस प्रदान करें?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> को <xliff:g id="STORAGE"><i>^2</i></xliff:g> पर मौजूद फ़ोटो और वीडियो सहित, अपने डेटा का एक्सेस प्रदान करें?"</string> <string name="never_ask_again" msgid="4295278542972859268">"फिर से ना पूछें"</string> <string name="allow" msgid="7225948811296386551">"अनुमति दें"</string> diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml index bf91c6a5a402..7988c719cf51 100644 --- a/packages/DocumentsUI/res/values-hr/strings.xml +++ b/packages/DocumentsUI/res/values-hr/strings.xml @@ -118,6 +118,7 @@ <string name="rename_error" msgid="4203041674883412606">"Naziv dokumenta nije promijenjen"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Neke su datoteke konvertirane"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobriti pristup direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> na pohrani <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> odobriti da pristupa direktoriju <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Želite li aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dopustiti pristup podacima, uključujući fotografije i videozapise na vanjskoj pohrani (<xliff:g id="STORAGE"><i>^2</i></xliff:g>)?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Više me ne pitaj"</string> <string name="allow" msgid="7225948811296386551">"Dopusti"</string> diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml index f9553189820c..fb666b51088b 100644 --- a/packages/DocumentsUI/res/values-hu/strings.xml +++ b/packages/DocumentsUI/res/values-hu/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Nem sikerült átnevezni a dokumentumot"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Egyes fájlokat konvertált a rendszer"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Hozzáférést biztosít a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> számára a(z) <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> könyvtárhoz itt: <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Hozzáférést biztosít a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> alkalmazásnak a(z) <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> könyvtárhoz?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Hozzáférést biztosít a(z) <xliff:g id="APPNAME"><b>^1</b></xliff:g> számára az Ön adataihoz, beleértve a következő tárhelyen található képekhez és videókhoz: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Ne jelenjen meg többé"</string> <string name="allow" msgid="7225948811296386551">"Engedélyezés"</string> diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml index b1af92c1f4eb..f6c3ad5aa55e 100644 --- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml +++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Չհաջողվեց վերանվանել փաստաթուղթը"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Որոշ ֆայլեր փոխարկվել են"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="STORAGE"><i>^3</i></xliff:g>-ի <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> գրացուցակն օգտագործելու թույլտվություն:"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> գրացուցակն օգտագործելու թույլտվություն:"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> հավելվածին տրամադրե՞լ <xliff:g id="STORAGE"><i>^2</i></xliff:g>-ում պահվող ձեր տվյալները, այդ թվում նաև լուսանկարները և տեսանյութերը, օգտագործելու թույլտվություն:"</string> <string name="never_ask_again" msgid="4295278542972859268">"Այլևս չհարցնել"</string> <string name="allow" msgid="7225948811296386551">"Թույլատրել"</string> diff --git a/packages/DocumentsUI/res/values-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml index 87576fb3946e..a8aee5297462 100644 --- a/packages/DocumentsUI/res/values-in/strings.xml +++ b/packages/DocumentsUI/res/values-in/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Gagal mengganti nama dokumen"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Beberapa file dikonversi"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> di <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses ke data Anda, termasuk foto dan video, di <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Jangan tanya lagi"</string> <string name="allow" msgid="7225948811296386551">"Izinkan"</string> diff --git a/packages/DocumentsUI/res/values-is-rIS/strings.xml b/packages/DocumentsUI/res/values-is-rIS/strings.xml index d3be73a04ec9..88aaced592e4 100644 --- a/packages/DocumentsUI/res/values-is-rIS/strings.xml +++ b/packages/DocumentsUI/res/values-is-rIS/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Ekki tókst að endurnefna skjalið"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sumum skrám var umbreytt"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að skráasafninu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> á <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Viltu veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að skráasafninu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Veita <xliff:g id="APPNAME"><b>^1</b></xliff:g> aðgang að gögnunum þínum, þar á meðal myndum og myndskeiðum, á <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Ekki spyrja aftur"</string> <string name="allow" msgid="7225948811296386551">"Leyfa"</string> diff --git a/packages/DocumentsUI/res/values-it/strings.xml b/packages/DocumentsUI/res/values-it/strings.xml index 736d31c1530b..b7497dbd4f99 100644 --- a/packages/DocumentsUI/res/values-it/strings.xml +++ b/packages/DocumentsUI/res/values-it/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Ridenominazione documento non riuscita"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alcuni file sono stati convertiti"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso alla directory <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> su <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso alla directory <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Concedere all\'app <xliff:g id="APPNAME"><b>^1</b></xliff:g> l\'accesso ai tuoi dati, inclusi video e foto, sull\'unità <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Non chiedermelo più"</string> <string name="allow" msgid="7225948811296386551">"Consenti"</string> diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml index 2446a4b81ef4..4498f8c01dec 100644 --- a/packages/DocumentsUI/res/values-iw/strings.xml +++ b/packages/DocumentsUI/res/values-iw/strings.xml @@ -125,6 +125,7 @@ <string name="rename_error" msgid="4203041674883412606">"ניסיון שינוי שם המסמך נכשל"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"קבצים מסוימים הומרו"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה לספריה <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> באחסון <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה אל ספריית <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"האם להעניק לאפליקציה <xliff:g id="APPNAME"><b>^1</b></xliff:g> גישה לנתונים שלך, כולל תמונות וסרטונים, השמורים ב<xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"אל תשאל שוב"</string> <string name="allow" msgid="7225948811296386551">"אפשר"</string> diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml index dc39b999f8dd..bfb1c3a040c1 100644 --- a/packages/DocumentsUI/res/values-ja/strings.xml +++ b/packages/DocumentsUI/res/values-ja/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"ドキュメントの名前を変更できませんでした"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"一部のファイルが変換されました"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"「<xliff:g id="STORAGE"><i>^3</i></xliff:g>」の「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」ディレクトリに「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」へのアクセスを許可しますか?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」アプリに「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」ディレクトリへのアクセスを許可しますか?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>の写真や動画などのデータへのアクセスを「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」に許可しますか?"</string> <string name="never_ask_again" msgid="4295278542972859268">"今後表示しない"</string> <string name="allow" msgid="7225948811296386551">"許可"</string> diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml index 0af8dd93ec3a..f0e9e86f5a63 100644 --- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml +++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"დოკუმენტის გადარქმევა ვერ მოხერხდა"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ზოგიერთი ფაილი გარდაქმნილია"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს <xliff:g id="STORAGE"><i>^3</i></xliff:g>-ის დირექტორიაზე „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ წვდომის უფლებით?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს დირექტორიაზე „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ წვდომის უფლებით?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"გსურთ, <xliff:g id="APPNAME"><b>^1</b></xliff:g> სარგებლობდეს <xliff:g id="STORAGE"><i>^2</i></xliff:g>-ზე არსებულ მონაცემებზე, მათ შორის, ფოტოებსა და ვიდეოებზე, წვდომის უფლებით?"</string> <string name="never_ask_again" msgid="4295278542972859268">"აღარ მკითხოთ"</string> <string name="allow" msgid="7225948811296386551">"უფლების მიცემა"</string> diff --git a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml index 3d6b758ace83..26879000713f 100644 --- a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml +++ b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Құжат қайта аталмады"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Кейбір файлдар түрлендірілді"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> қолданбасына <xliff:g id="STORAGE"><i>^3</i></xliff:g> қоймасындағы <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> каталогына өтуге рұқсат беру керек пе?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> қолданбасына <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> каталогына қатынас беру керек пе?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> <xliff:g id="STORAGE"><i>^2</i></xliff:g> қоймасындағы деректерге, соның ішінде фотосуреттерге және бейнелерге кіру мүмкіндігін беру керек пе?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Қайта сұралмасын"</string> <string name="allow" msgid="7225948811296386551">"Рұқсат беру"</string> diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml index 0eb13961858e..ea240432260a 100644 --- a/packages/DocumentsUI/res/values-km-rKH/strings.xml +++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"បានបរាជ័យក្នុងការប្តូរឈ្មោះឯកសារ"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ឯកសារមួយចំនួនត្រូវបានបម្លែង"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"ផ្តល់សិទ្ធិឲ្យ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ចូលដំណើរការថត <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> នៅលើ <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"ផ្តល់សិទ្ធិឲ្យ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ចូលដំណើរការថត <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ឬ?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ផ្តល់សិទ្ធិអនុញ្ញាតដល់ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ដើម្បីចូលដំណើរការទិន្នន័យរបស់អ្នក រាប់បញ្ចូលទាំងរូបថត និងវីដេអូ នៅលើ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ឬទេ?"</string> <string name="never_ask_again" msgid="4295278542972859268">"កុំសួរទៀត"</string> <string name="allow" msgid="7225948811296386551">"អនុញ្ញាត"</string> diff --git a/packages/DocumentsUI/res/values-kn-rIN/strings.xml b/packages/DocumentsUI/res/values-kn-rIN/strings.xml index a5a8ab2c51f3..c756009faabd 100644 --- a/packages/DocumentsUI/res/values-kn-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-kn-rIN/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"ಡಾಕ್ಯುಮೆಂಟ್ ಮರುಹೆಸರಿಸಲು ವಿಫಲವಾಗಿದೆ"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ಕೆಲವು ಫೈಲ್ಗಳನ್ನು ಪರಿವರ್ತಿಸಲಾಗಿದೆ"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> ರಲ್ಲಿ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ಡೈರೆಕ್ಟರಿಗೆ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಪ್ರವೇಶ ನೀಡುವುದೇ?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g><xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ಡೈರೆಕ್ಟರಿ ಪ್ರವೇಶಿಸಲು ಅನುಮತಿಸುವುದೇ?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> ಸಂಗ್ರಹಣೆಯಲ್ಲಿನ ಪೋಟೋಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳು ಸೇರಿದಂತೆ ನಿಮ್ಮ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು <xliff:g id="APPNAME"><b>^1</b></xliff:g> ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುವುದೇ?"</string> <string name="never_ask_again" msgid="4295278542972859268">"ಮತ್ತೆ ಕೇಳಬೇಡಿ"</string> <string name="allow" msgid="7225948811296386551">"ಅನುಮತಿಸು"</string> diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml index 9975ce0646e8..4d5dcf979a8c 100644 --- a/packages/DocumentsUI/res/values-ko/strings.xml +++ b/packages/DocumentsUI/res/values-ko/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"문서 이름을 변경하지 못했습니다."</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"일부 파일이 변환되었습니다."</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>이(가) <xliff:g id="STORAGE"><i>^3</i></xliff:g>에서 <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> 디렉토리에 액세스하도록 허용하시겠습니까?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>이(가) <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> 디렉토리에 액세스하도록 허용하시겠습니까?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>에서 사진, 동영상 등 <xliff:g id="STORAGE"><i>^2</i></xliff:g>의 내 데이터에 액세스하도록 허용하시겠습니까?"</string> <string name="never_ask_again" msgid="4295278542972859268">"다시 묻지 않음"</string> <string name="allow" msgid="7225948811296386551">"허용"</string> diff --git a/packages/DocumentsUI/res/values-ky-rKG/strings.xml b/packages/DocumentsUI/res/values-ky-rKG/strings.xml index be2aca8b90fc..1b39039e6f29 100644 --- a/packages/DocumentsUI/res/values-ky-rKG/strings.xml +++ b/packages/DocumentsUI/res/values-ky-rKG/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Документтин аталышы өзгөртүлбөй калды"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Айрым файлдардын форматы өзгөртүлдү"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="STORAGE"><i>^3</i></xliff:g> түзмөгүндөгү <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> папканы пайдалануу мүмкүнчүлүгү берилсинби?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> каталогун пайдалануу мүмкүнчүлүгү берилсинби?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> колдонмосуна <xliff:g id="STORAGE"><i>^2</i></xliff:g> түзмөгүндөгү дайындарыңыз, сүрөттөрүңүз жана видеолоруңузду пайдалануу мүмкүнчүлүгү берилсинби?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Экинчи суралбасын"</string> <string name="allow" msgid="7225948811296386551">"Уруксат берүү"</string> @@ -130,7 +131,7 @@ <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> куржун мазмуну менен жок кылынсынбы?</item> </plurals> <plurals name="delete_items_confirmation_message" formatted="false" msgid="5376214433530243459"> - <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> нерсе жок кылынчынбы?</item> - <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> нерсе жок кылынчынбы?</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> нерсе жок кылынсынбы?</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> нерсе жок кылынсынбы?</item> </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml index ed9646416e2a..a4f381db5e5d 100644 --- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml +++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"ປ່ຽນຊື່ເອກະສານບໍ່ສຳເລັດ"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ປ່ຽນແປງບາງໄຟລ໌ແລ້ວ"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"ອະນຸຍາດສິດເຂົ້າເຖິງໃຫ້ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ເພື່ອເຂົ້າໄດເຣກທໍຣີ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ຢູ່ <xliff:g id="STORAGE"><i>^3</i></xliff:g> ບໍ?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"ອະນຸມັດ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ໃຫ້ເຂົ້າຫາໄດເຣັກທໍຣີ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ບໍ?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ອະນຸມັດໃຫ້ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ເຂົ້າເຖິງຂໍ້ມູນຂອງທ່ານ ເຊິ່ງຮວມເຖິງຮູບພາບ ແລະ ວິດີໂອໃນ <xliff:g id="STORAGE"><i>^2</i></xliff:g> ໄດ້ບໍ?"</string> <string name="never_ask_again" msgid="4295278542972859268">"ບໍ່ຕ້ອງຖາມຄືນ"</string> <string name="allow" msgid="7225948811296386551">"ອະນຸຍາດ"</string> diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml index 0e95ea00abf9..2e0df93dfaeb 100644 --- a/packages/DocumentsUI/res/values-lt/strings.xml +++ b/packages/DocumentsUI/res/values-lt/strings.xml @@ -125,6 +125,7 @@ <string name="rename_error" msgid="4203041674883412606">"Nepavyko pervardyti dokumento"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Kai kurie failai buvo konvertuoti"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Suteikti „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie katalogo „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“ <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Suteikti „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie katalogo „<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>“?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Suteikti programai „<xliff:g id="APPNAME"><b>^1</b></xliff:g>“ prieigą prie duomenų, įskaitant nuotraukas ir vaizdo įrašus, <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Daugiau neklausti"</string> <string name="allow" msgid="7225948811296386551">"Leisti"</string> diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml index 9f39f2edd61b..fb81aa002e9f 100644 --- a/packages/DocumentsUI/res/values-lv/strings.xml +++ b/packages/DocumentsUI/res/values-lv/strings.xml @@ -118,6 +118,7 @@ <string name="rename_error" msgid="4203041674883412606">"Neizdevās pārdēvēt dokumentu"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Daži faili tika pārveidoti."</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Vai atļaut lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļūt direktorijam <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> šajā krātuvē: <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Vai piešķirt lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļuvi direktorijam <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vai atļaut lietotnei <xliff:g id="APPNAME"><b>^1</b></xliff:g> piekļūt jūsu datiem, tostarp fotoattēliem un videoklipiem, šajā krātuvē: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Turpmāk vairs nejautāt"</string> <string name="allow" msgid="7225948811296386551">"Atļaut"</string> diff --git a/packages/DocumentsUI/res/values-mk-rMK/strings.xml b/packages/DocumentsUI/res/values-mk-rMK/strings.xml index bc3b7fa7dd38..ad428a0696ec 100644 --- a/packages/DocumentsUI/res/values-mk-rMK/strings.xml +++ b/packages/DocumentsUI/res/values-mk-rMK/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Не успеа да се преименува документот"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Некои датотеки беа конвертирани"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Овозможете пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до директориумот <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Овозможете пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до директориумот <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Да се овозможи пристап на <xliff:g id="APPNAME"><b>^1</b></xliff:g> до вашите податоци, вклучувајќи фотографии и видеа, на <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Не прашувај повторно"</string> <string name="allow" msgid="7225948811296386551">"Дозволи"</string> diff --git a/packages/DocumentsUI/res/values-ml-rIN/strings.xml b/packages/DocumentsUI/res/values-ml-rIN/strings.xml index 9a7509f65071..5a1651260779 100644 --- a/packages/DocumentsUI/res/values-ml-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-ml-rIN/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"ഡോക്യുമെന്റിന്റെ പേരുമാറ്റുന്നത് പരാജയപ്പെട്ടു"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ചില ഫയലുകൾ പരിവർത്തനം ചെയ്യപ്പെട്ടു"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> സ്റ്റോറേജിലെ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> എന്ന ഡയറക്റ്ററിയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ് അനുവദിക്കണോ?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> എന്ന ഡയറക്ടറിയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ് അനുവദിക്കണോ?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> സ്റ്റോറേജിലെ ഫോട്ടോകളും വീഡിയോകളും ഉൾപ്പെടെ, നിങ്ങളുടെ ഡാറ്റയിലേക്ക് <xliff:g id="APPNAME"><b>^1</b></xliff:g> ആപ്പിന് ആക്സസ്സ് അനുവദിക്കണോ?"</string> <string name="never_ask_again" msgid="4295278542972859268">"വീണ്ടും ആവശ്യപ്പെടരുത്"</string> <string name="allow" msgid="7225948811296386551">"അനുവദിക്കുക"</string> diff --git a/packages/DocumentsUI/res/values-mn-rMN/strings.xml b/packages/DocumentsUI/res/values-mn-rMN/strings.xml index f424f8ea6f86..cf2c2d47f356 100644 --- a/packages/DocumentsUI/res/values-mn-rMN/strings.xml +++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Баримт бичгийн нэрийн өөрчилж чадсангүй"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Зарим файлыг хөрвүүлсэн"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g>-д байгаа <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> лавлагаанд хандахыг <xliff:g id="APPNAME"><b>^1</b></xliff:g>-д зөвшөөрөх үү?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> лавлагаанд хандах эрхийг <xliff:g id="APPNAME"><b>^1</b></xliff:g>-д олгох уу?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>-д байгаа зураг, видео гэх мэт таны өгөгдөлд <xliff:g id="APPNAME"><b>^1</b></xliff:g> хандахыг зөвшөөрөх үү?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Дахин бүү асуу"</string> <string name="allow" msgid="7225948811296386551">"Зөвшөөрөх"</string> diff --git a/packages/DocumentsUI/res/values-mr-rIN/strings.xml b/packages/DocumentsUI/res/values-mr-rIN/strings.xml index 556c1e620e74..09dd1334cb5c 100644 --- a/packages/DocumentsUI/res/values-mr-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-mr-rIN/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"दस्तऐवज पुनर्नामित करण्यात अयशस्वी झाले"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"काही फायली रूपांतरित केल्या होत्या"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> वर <xliff:g id="APPNAME"><b>^1</b></xliff:g> ला <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकेवर प्रवेशाची मंजूरी द्यायची?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ला <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकमध्ये प्रवेश मंजूर करायचा?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ला <xliff:g id="STORAGE"><i>^2</i></xliff:g> वर फोटो आणि व्हिडिओंसह, आपल्या डेटामध्ये प्रवेश करण्याची मंजूरी द्यायची?"</string> <string name="never_ask_again" msgid="4295278542972859268">"पुन्हा विचारू नका"</string> <string name="allow" msgid="7225948811296386551">"अनुमती द्या"</string> diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml index 0f2af2f75190..9eb3d49720f5 100644 --- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml +++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Gagal menamakan semula dokumen"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sesetengah fail telah ditukarkan"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> di <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada direktori <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Beri <xliff:g id="APPNAME"><b>^1</b></xliff:g> akses kepada data anda, termasuk foto dan video pada <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Jangan tanya lagi"</string> <string name="allow" msgid="7225948811296386551">"Benarkan"</string> diff --git a/packages/DocumentsUI/res/values-my-rMM/strings.xml b/packages/DocumentsUI/res/values-my-rMM/strings.xml index 6acbc806a747..7c637c4cfd74 100644 --- a/packages/DocumentsUI/res/values-my-rMM/strings.xml +++ b/packages/DocumentsUI/res/values-my-rMM/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"စာရွက်စာတမ်းကို အမည်ပြောင်းခြင်း မအောင်မြင်ပါ"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"အချို့ဖိုင်များကို ပြောင်းလဲထားသည်"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ကို <xliff:g id="STORAGE"><i>^3</i></xliff:g> ရှိ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> လမ်းညွှန်အား အသုံးပြုခွင့်ပေးမလား။"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> အား <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> စာရင်းကို အသုံးပြုခွင့်ပေးမလား။"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> ရှိဓာတ်ပုံများနှင့် ဗီဒီယိုများအပါအဝင် သင့်ဒေတာများကို <xliff:g id="APPNAME"><b>^1</b></xliff:g> အားအသုံးပြုခွင့်ပေးမလား။"</string> <string name="never_ask_again" msgid="4295278542972859268">"နောက်ထပ်မမေးပါနှင့်"</string> <string name="allow" msgid="7225948811296386551">"ခွင့်ပြုသည်"</string> diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml index c2c983e1ee76..3c344eb14be9 100644 --- a/packages/DocumentsUI/res/values-nb/strings.xml +++ b/packages/DocumentsUI/res/values-nb/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Kunne ikke gi dokumentet nytt navn"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Noen filer er konvertert"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-katalogen på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>-katalogen?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vil du gi <xliff:g id="APPNAME"><b>^1</b></xliff:g> tilgang til dataene dine – inkludert bilder og videoer – på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Ikke spør igjen"</string> <string name="allow" msgid="7225948811296386551">"Tillat"</string> diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml index 31c4c2c30fed..9fef037a10c9 100644 --- a/packages/DocumentsUI/res/values-ne-rNP/strings.xml +++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"कागजात पुन: नामाकरण गर्न असफल भयो"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"केही फाइलहरू परिवर्तन गरिएका थिए"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="STORAGE"><i>^3</i></xliff:g> मा भएको <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकामा पहुँच गर्न अनुमति दिने हो?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> निर्देशिकामाथि पहुँच गर्न अनुमति प्रदान गर्ने हो?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> लाई <xliff:g id="STORAGE"><i>^2</i></xliff:g> मा भएका तस्बिर र भिडियोहरू लगायत तपाईँको डेटामा पहुँच गर्नका लागि अनुमति दिने हो?"</string> <string name="never_ask_again" msgid="4295278542972859268">"फेरि नसोध्नुहोस्"</string> <string name="allow" msgid="7225948811296386551">"अनुमति दिनुहोस्"</string> diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml index 385b5079ff2c..c5b9d76899b1 100644 --- a/packages/DocumentsUI/res/values-nl/strings.xml +++ b/packages/DocumentsUI/res/values-nl/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Kan naam van document niet wijzigen"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Sommige bestanden zijn geconverteerd"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot de map <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> op <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot de map <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> toegang verlenen tot je gegevens, waaronder foto\'s en video\'s, op <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Niet meer vragen"</string> <string name="allow" msgid="7225948811296386551">"Toestaan"</string> diff --git a/packages/DocumentsUI/res/values-pa-rIN/strings.xml b/packages/DocumentsUI/res/values-pa-rIN/strings.xml index 7603f5879c22..7d5e14a75d90 100644 --- a/packages/DocumentsUI/res/values-pa-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-pa-rIN/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"ਦਸਤਾਵੇਜ਼ ਦਾ ਮੁੜ-ਨਾਮਕਰਨ ਕਰਨਾ ਅਸਫਲ ਰਿਹਾ"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"ਕੁਝ ਫ਼ਾਈਲਾਂ ਤਬਦੀਲ ਕੀਤੀਆਂ ਗਈਆਂ ਸਨ"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^3</i></xliff:g> \'ਤੇ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ਡਾਇਰੈਕਟਰੀ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ਡਾਇਰੈਕਟਰੀ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ਕੀ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ਨੂੰ <xliff:g id="STORAGE"><i>^2</i></xliff:g> \'ਤੇ ਫੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓ ਸਮੇਤ, ਤੁਹਾਡੇ ਡੈਟੇ \'ਤੇ ਪਹੁੰਚ ਦੇਣੀ ਹੈ?"</string> <string name="never_ask_again" msgid="4295278542972859268">"ਦੁਬਾਰਾ ਨਾ ਪੁੱਛੋ"</string> <string name="allow" msgid="7225948811296386551">"ਆਗਿਆ ਦਿਓ"</string> diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml index b234a9ec8605..ca007d7f858e 100644 --- a/packages/DocumentsUI/res/values-pl/strings.xml +++ b/packages/DocumentsUI/res/values-pl/strings.xml @@ -125,6 +125,7 @@ <string name="rename_error" msgid="4203041674883412606">"Nie udało się zmienić nazwy dokumentu"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Niektóre pliki zostały przekonwertowane"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Zezwolić aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> na dostęp do katalogu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> w pamięci masowej <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Przyznać aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dostęp do katalogu <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Zezwolić aplikacji <xliff:g id="APPNAME"><b>^1</b></xliff:g> na dostęp do Twoich danych, w tym zdjęć i filmów, zapisanych w pamięci <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Nie pytaj ponownie"</string> <string name="allow" msgid="7225948811296386551">"Zezwól"</string> diff --git a/packages/DocumentsUI/res/values-pt-rBR/strings.xml b/packages/DocumentsUI/res/values-pt-rBR/strings.xml index 634ac963dec4..21359c7dbca1 100644 --- a/packages/DocumentsUI/res/values-pt-rBR/strings.xml +++ b/packages/DocumentsUI/res/values-pt-rBR/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Falha ao renomear documento"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alguns arquivos foram convertidos"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Conceder ao <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Conceder acesso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no/na <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Não perguntar novamente"</string> <string name="allow" msgid="7225948811296386551">"Permitir"</string> diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml index 54408015ee68..aea1249ab353 100644 --- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml +++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Falha ao mudar o nome do documento"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alguns ficheiros foram convertidos"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no(a) <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Pretende conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no(a) <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Não perguntar novamente"</string> <string name="allow" msgid="7225948811296386551">"Permitir"</string> diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml index 634ac963dec4..21359c7dbca1 100644 --- a/packages/DocumentsUI/res/values-pt/strings.xml +++ b/packages/DocumentsUI/res/values-pt/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Falha ao renomear documento"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Alguns arquivos foram convertidos"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Conceder ao <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> no <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Conceder acesso a <xliff:g id="APPNAME"><b>^1</b></xliff:g> ao diretório <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Conceder a <xliff:g id="APPNAME"><b>^1</b></xliff:g> acesso aos seus dados, incluindo fotos e vídeos, no/na <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Não perguntar novamente"</string> <string name="allow" msgid="7225948811296386551">"Permitir"</string> diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml index 3dc93ef92cc3..4b833b18a24c 100644 --- a/packages/DocumentsUI/res/values-ro/strings.xml +++ b/packages/DocumentsUI/res/values-ro/strings.xml @@ -118,6 +118,7 @@ <string name="rename_error" msgid="4203041674883412606">"Documentul nu a putut fi redenumit"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Unele fișiere au fost convertite"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> accesul la directorul <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> de pe <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> să acceseze directorul <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Permiteți aplicației <xliff:g id="APPNAME"><b>^1</b></xliff:g> să vă acceseze datele, inclusiv fotografiile și videoclipurile, de pe <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Nu mai întreba"</string> <string name="allow" msgid="7225948811296386551">"Permiteți"</string> diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml index fef3015d830e..6ba635d7aadc 100644 --- a/packages/DocumentsUI/res/values-ru/strings.xml +++ b/packages/DocumentsUI/res/values-ru/strings.xml @@ -125,6 +125,7 @@ <string name="rename_error" msgid="4203041674883412606">"Не удалось переименовать документ"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Формат некоторых файлов изменен"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к папке \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\" на устройстве \"<xliff:g id="STORAGE"><i>^3</i></xliff:g>\"?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к папке \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\"?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Открыть приложению \"<xliff:g id="APPNAME"><b>^1</b></xliff:g>\" доступ к вашим данным, включая фото и видео, на носителе: <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Больше не спрашивать"</string> <string name="allow" msgid="7225948811296386551">"Разрешить"</string> diff --git a/packages/DocumentsUI/res/values-si-rLK/strings.xml b/packages/DocumentsUI/res/values-si-rLK/strings.xml index d49c2f37032f..41c9d4a87704 100644 --- a/packages/DocumentsUI/res/values-si-rLK/strings.xml +++ b/packages/DocumentsUI/res/values-si-rLK/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"ලේඛනය යළි නම් කිරීම අසාර්ථක විය"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"සමහර ගොනු පරිවර්තනය කරන ලදී"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> හට <xliff:g id="STORAGE"><i>^3</i></xliff:g> මත <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> නාමාවලිය වෙත ප්රවේශය දෙන්නද?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ප්රවේශය <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> නාමාවලිය වෙත ලබා දෙන්නද?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> හි, ඡායාරූප සහ වීඩියෝ ඇතුළුව, ඔබේ දත්තවලට <xliff:g id="APPNAME"><b>^1</b></xliff:g> හට ප්රවේශය ලබා දෙන්නද?"</string> <string name="never_ask_again" msgid="4295278542972859268">"නැවත අසන්න එපා"</string> <string name="allow" msgid="7225948811296386551">"අවසර දෙන්න"</string> diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml index bd75175c487c..1ff01b054d23 100644 --- a/packages/DocumentsUI/res/values-sk/strings.xml +++ b/packages/DocumentsUI/res/values-sk/strings.xml @@ -125,6 +125,7 @@ <string name="rename_error" msgid="4203041674883412606">"Premenovanie dokumentu zlyhalo"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Niektoré súbory boli konvertované"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Udeliť aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> prístup k adresáru <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v úložisku <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Udeliť aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> prístup k adresáru <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Chcete aplikácii <xliff:g id="APPNAME"><b>^1</b></xliff:g> udeliť prístup k dátam (vrátane fotiek a videí) v úložisku <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Nabudúce sa nepýtať"</string> <string name="allow" msgid="7225948811296386551">"Povoliť"</string> diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml index 78ec8fed5321..d8b983cc7bdb 100644 --- a/packages/DocumentsUI/res/values-sl/strings.xml +++ b/packages/DocumentsUI/res/values-sl/strings.xml @@ -125,6 +125,7 @@ <string name="rename_error" msgid="4203041674883412606">"Dokumenta ni bilo mogoče preimenovati"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Nekatere datoteke so bile pretvorjene"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Želite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dovoliti dostop do imenika <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> v shrambi <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Želite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dovoliti dostop do imenika <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Odobrite aplikaciji <xliff:g id="APPNAME"><b>^1</b></xliff:g> dostop do podatkov, vključno s fotografijami in videoposnetki, v shrambi <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Ne sprašuj več"</string> <string name="allow" msgid="7225948811296386551">"Dovoli"</string> diff --git a/packages/DocumentsUI/res/values-sq-rAL/strings.xml b/packages/DocumentsUI/res/values-sq-rAL/strings.xml index 662e7f09f1cd..933a537f20cc 100644 --- a/packages/DocumentsUI/res/values-sq-rAL/strings.xml +++ b/packages/DocumentsUI/res/values-sq-rAL/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Riemërtimi i dokumentit dështoi"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Disa skedarë u konvertuan"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Jepi aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te direktoria <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> në <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"T\'i jepet aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te direktoria <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"T\'i jepet aplikacionit <xliff:g id="APPNAME"><b>^1</b></xliff:g> qasje te të dhënat, duke përfshirë fotografitë dhe videot, në <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Mos pyet përsëri"</string> <string name="allow" msgid="7225948811296386551">"Lejo"</string> diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml index 690f81cc8581..0505f423c1b0 100644 --- a/packages/DocumentsUI/res/values-sr/strings.xml +++ b/packages/DocumentsUI/res/values-sr/strings.xml @@ -118,6 +118,7 @@ <string name="rename_error" msgid="4203041674883412606">"Преименовање документа није успело"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Неке датотеке су конвертоване"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Желите ли да апликацији <xliff:g id="APPNAME"><b>^1</b></xliff:g> одобрите приступ директоријуму <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на меморијском простору <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Желите да дозволите да <xliff:g id="APPNAME"><b>^1</b></xliff:g> приступа директоријуму <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Желите да ли да дозволите да апликација <xliff:g id="APPNAME"><b>^1</b></xliff:g> приступа подацима, укључујући слике и видео снимке, на локацији <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Не питај поново"</string> <string name="allow" msgid="7225948811296386551">"Дозволи"</string> diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml index 18497828a7ed..99f334b4f473 100644 --- a/packages/DocumentsUI/res/values-sv/strings.xml +++ b/packages/DocumentsUI/res/values-sv/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Det gick inte att byta namn på dokumentet"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Vissa filer konverterades"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till katalogen <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> på <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till katalogen <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Vill du ge <xliff:g id="APPNAME"><b>^1</b></xliff:g> åtkomst till din data (inklusive foton och videor) på <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Fråga inte igen"</string> <string name="allow" msgid="7225948811296386551">"Tillåt"</string> diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml index bf4b744a9204..566e6a462fef 100644 --- a/packages/DocumentsUI/res/values-sw/strings.xml +++ b/packages/DocumentsUI/res/values-sw/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Imeshindwa kubadilisha jina la hati"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Baadhi ya faili zimebadilishwa muundo"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie saraka ya <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> kwenye <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie saraka ya <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Ungependa kuruhusu <xliff:g id="APPNAME"><b>^1</b></xliff:g> ifikie data yako, ikiwa ni pamoja na picha na video kwenye <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Usiniulize tena"</string> <string name="allow" msgid="7225948811296386551">"Ruhusu"</string> diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml index 43d29e22afdf..9a8b4ec71118 100644 --- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"ஆவணத்திற்கு மறுபெயரிடுவதில் தோல்வி"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"சில கோப்புகள் மாற்றப்பட்டன"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="STORAGE"><i>^3</i></xliff:g> இல் உள்ள <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> கோப்பகத்தை அணுக <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> கோப்பகத்தை அணுக, <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g> இல் உள்ள படங்கள், வீடியோக்கள் உட்பட எல்லா தரவையும் அணுக, <xliff:g id="APPNAME"><b>^1</b></xliff:g>ஐ அனுமதிக்கவா?"</string> <string name="never_ask_again" msgid="4295278542972859268">"மீண்டும் கேட்காதே"</string> <string name="allow" msgid="7225948811296386551">"அனுமதி"</string> diff --git a/packages/DocumentsUI/res/values-te-rIN/strings.xml b/packages/DocumentsUI/res/values-te-rIN/strings.xml index c9233eca7d05..224d0db288eb 100644 --- a/packages/DocumentsUI/res/values-te-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-te-rIN/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"పత్రం పేరు మార్చడంలో విఫలమైంది"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"కొన్ని పైల్లు మార్చబడ్డాయి"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>కి <xliff:g id="STORAGE"><i>^3</i></xliff:g>లో <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> డైరెక్టరీ ప్రాప్యతను మంజూరు చేయాలా?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g>కి <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> డైరెక్టరీ ప్రాప్యతను మంజూరు చేయాలా?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="STORAGE"><i>^2</i></xliff:g>లో ఫోటోలు మరియు వీడియోలతో సహా మీ డేటా ప్రాప్యతను <xliff:g id="APPNAME"><b>^1</b></xliff:g>కి మంజూరు చేయాలా?"</string> <string name="never_ask_again" msgid="4295278542972859268">"మళ్లీ అడగవద్దు"</string> <string name="allow" msgid="7225948811296386551">"అనుమతించండి"</string> diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml index 491e984c7e2c..af07584d48eb 100644 --- a/packages/DocumentsUI/res/values-th/strings.xml +++ b/packages/DocumentsUI/res/values-th/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"ไม่สามารถเปลี่ยนชื่อเอกสาร"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"แปลงบางไฟล์แล้ว"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> ในการเข้าถึงไดเรกทอรี <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ใน <xliff:g id="STORAGE"><i>^3</i></xliff:g> ไหม"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> เข้าถึงไดเรกทอรี <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ไหม"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"ให้สิทธิ์ <xliff:g id="APPNAME"><b>^1</b></xliff:g> เข้าถึงข้อมูลของคุณ รวมถึงรูปภาพและวิดีโอใน <xliff:g id="STORAGE"><i>^2</i></xliff:g> ไหม"</string> <string name="never_ask_again" msgid="4295278542972859268">"ไม่ต้องถามอีก"</string> <string name="allow" msgid="7225948811296386551">"อนุญาต"</string> diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml index 27d667108be3..b2acf05459cc 100644 --- a/packages/DocumentsUI/res/values-tl/strings.xml +++ b/packages/DocumentsUI/res/values-tl/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Hindi napalitan ang pangalan ng dokumento"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Na-convert ang ilang file"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Bigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa directory ng <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> sa <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Bibigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa direktoryong <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Bigyan ang <xliff:g id="APPNAME"><b>^1</b></xliff:g> ng access sa iyong data, kabilang ang mga larawan at video, sa <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Huwag nang tatanunging muli"</string> <string name="allow" msgid="7225948811296386551">"Payagan"</string> diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml index dda9f28d99ec..c5653c9ffe31 100644 --- a/packages/DocumentsUI/res/values-tr/strings.xml +++ b/packages/DocumentsUI/res/values-tr/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Dokümanın adı değiştirilemedi"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Bazı dosyalar dönüştürüldü"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasına <xliff:g id="STORAGE"><i>^3</i></xliff:g> depolama alanındaki <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> dizinine erişim izni verilsin mi?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> dizinine erişmek için <xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasına izin verilsin mi?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> uygulamasının, fotoğraflar ve videolar dahil olmak üzere <xliff:g id="STORAGE"><i>^2</i></xliff:g> üzerindeki verilerinize erişmesine izin verilsin mi?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Tekrar sorma"</string> <string name="allow" msgid="7225948811296386551">"İzin Ver"</string> diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml index ec7e1d60c317..21532b675437 100644 --- a/packages/DocumentsUI/res/values-uk/strings.xml +++ b/packages/DocumentsUI/res/values-uk/strings.xml @@ -125,6 +125,7 @@ <string name="rename_error" msgid="4203041674883412606">"Не вдалося перейменувати документ"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Деякі файли конвертовано"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до каталогу <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> на пристрої пам’яті <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до каталогу \"<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>\"?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Надати додатку <xliff:g id="APPNAME"><b>^1</b></xliff:g> доступ до ваших даних, зокрема до фотографій і відео, які містить <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Не запитувати знову"</string> <string name="allow" msgid="7225948811296386551">"Дозвол."</string> diff --git a/packages/DocumentsUI/res/values-ur-rPK/strings.xml b/packages/DocumentsUI/res/values-ur-rPK/strings.xml index 4ea998526124..eb0cfc8e7b54 100644 --- a/packages/DocumentsUI/res/values-ur-rPK/strings.xml +++ b/packages/DocumentsUI/res/values-ur-rPK/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"دستاویز کا نام تبدیل کرنے میں ناکام"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"کچھ فائلوں کو تبدیل کیا گیا تھا"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو <xliff:g id="STORAGE"><i>^3</i></xliff:g> پر <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ڈائرکٹری تک رسائی عطا کریں؟"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ڈائرکٹری تک رسائی دیں؟"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> کو اپنے ڈیٹا بشمول <xliff:g id="STORAGE"><i>^2</i></xliff:g> پر موجود تصاویر اور ویڈیوز تک رسائی عطا کریں؟"</string> <string name="never_ask_again" msgid="4295278542972859268">"دوبارہ نہ پوچھیں"</string> <string name="allow" msgid="7225948811296386551">"اجازت دیں"</string> diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml index dffbba5e359c..2654308970b7 100644 --- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml +++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml @@ -110,7 +110,8 @@ <string name="menu_rename" msgid="7678802479104285353">"Qayta nomlash"</string> <string name="rename_error" msgid="4203041674883412606">"Hujjatni qayta nomlab bo‘lmadi"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Bir nechta fayllar o‘girildi"</string> - <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasining <xliff:g id="STORAGE"><i>^3</i></xliff:g> xotirasidagi “<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>” jildiga kirishiga ruxsat berilsinmi?"</string> + <string name="open_external_dialog_request" msgid="5789329484285817629">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasiga <xliff:g id="STORAGE"><i>^3</i></xliff:g> xotirasidagi “<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>” jildidan foydalanishiga ruxsat berilsinmi?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasiga “<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>” jildidan foydalanishiga ruxsat berilsinmi?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"<xliff:g id="APPNAME"><b>^1</b></xliff:g> ilovasiga <xliff:g id="STORAGE"><i>^2</i></xliff:g> xotirasidagi ma’lumotlardan, jumladan, rasmlar va videolardan foydalanishiga ruxsat berilsinmi?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Boshqa so‘ralmasin"</string> <string name="allow" msgid="7225948811296386551">"Ruxsat berish"</string> diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml index 127c2d322575..9af7db08cf8c 100644 --- a/packages/DocumentsUI/res/values-vi/strings.xml +++ b/packages/DocumentsUI/res/values-vi/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Không đổi được tên tài liệu"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Đã chuyển đổi một số tệp"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập vào thư mục <xliff:g id="DIRECTORY"><i>^2</i></xliff:g> trong <xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập thư mục <xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Cấp cho <xliff:g id="APPNAME"><b>^1</b></xliff:g> quyền truy cập vào dữ liệu của bạn, kể cả ảnh và video trên <xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Không hỏi lại"</string> <string name="allow" msgid="7225948811296386551">"Cho phép"</string> diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml index 45d22a303aab..e3db1a07749a 100644 --- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml +++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"无法重命名文档"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"部分文件已转换成其他格式"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的“<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>”目录吗?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>目录吗?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"要授权<xliff:g id="APPNAME"><b>^1</b></xliff:g>访问您 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的数据(包括照片和视频)吗?"</string> <string name="never_ask_again" msgid="4295278542972859268">"不再询问"</string> <string name="allow" msgid="7225948811296386551">"允许"</string> diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml index 08aefdd53c96..f13a4bd12b57 100644 --- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml +++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"無法重新命名文件"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"部分檔案已轉換成其他格式"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"要為「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄存取權嗎?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"要為「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄的存取權嗎?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"要向「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」開放 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的相片和影片等資料的存取權嗎?"</string> <string name="never_ask_again" msgid="4295278542972859268">"不要再詢問"</string> <string name="allow" msgid="7225948811296386551">"允許"</string> diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml index 90c932cda872..f8f82820f0d5 100644 --- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml +++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"無法重新命名文件"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"部分檔案已轉換成其他格式"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"要允許<xliff:g id="APPNAME"><b>^1</b></xliff:g>存取 <xliff:g id="STORAGE"><i>^3</i></xliff:g>上的「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄嗎?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"要允許<xliff:g id="APPNAME"><b>^1</b></xliff:g>存取「<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>」目錄嗎?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"要允許「<xliff:g id="APPNAME"><b>^1</b></xliff:g>」存取 <xliff:g id="STORAGE"><i>^2</i></xliff:g>上的資料 (包括相片和影片) 嗎?"</string> <string name="never_ask_again" msgid="4295278542972859268">"不要再詢問"</string> <string name="allow" msgid="7225948811296386551">"允許"</string> diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml index e83bb3dee48e..a0b9f7f7c526 100644 --- a/packages/DocumentsUI/res/values-zu/strings.xml +++ b/packages/DocumentsUI/res/values-zu/strings.xml @@ -111,6 +111,7 @@ <string name="rename_error" msgid="4203041674883412606">"Yehlulekile ukuqamba kabusha idokhumenti"</string> <string name="notification_copy_files_converted_title" msgid="3153573223054275181">"Amanye amafayela aguqulelwe"</string> <string name="open_external_dialog_request" msgid="5789329484285817629">"Nika i-<xliff:g id="APPNAME"><b>^1</b></xliff:g> ukufinyelela ekuqondiseni kwe-<xliff:g id="DIRECTORY"><i>^2</i></xliff:g> ku-<xliff:g id="STORAGE"><i>^3</i></xliff:g>?"</string> + <string name="open_external_dialog_request_primary_volume" msgid="6635562535713428688">"Nika ukufinyelela kwe-<xliff:g id="APPNAME"><b>^1</b></xliff:g> kwinkomba ye-<xliff:g id="DIRECTORY"><i>^2</i></xliff:g>?"</string> <string name="open_external_dialog_root_request" msgid="8899108702926347720">"Nikeza i-<xliff:g id="APPNAME"><b>^1</b></xliff:g> ukufinyelela kudatha yakho, okufaka izithombe namavidiyo, ku-<xliff:g id="STORAGE"><i>^2</i></xliff:g>?"</string> <string name="never_ask_again" msgid="4295278542972859268">"Ungaphindi ubuze"</string> <string name="allow" msgid="7225948811296386551">"Vumela"</string> diff --git a/packages/DocumentsUI/res/values/colors.xml b/packages/DocumentsUI/res/values/colors.xml index 1660e26af4f8..cf0643d8ceaa 100644 --- a/packages/DocumentsUI/res/values/colors.xml +++ b/packages/DocumentsUI/res/values/colors.xml @@ -31,6 +31,7 @@ <color name="accent">@*android:color/accent_material_light</color> <color name="accent_dark">@*android:color/accent_material_dark</color> <color name="action_mode">@color/material_grey_400</color> + <color name="status_bar_color">@*android:color/material_blue_grey_950</color> <color name="band_select_background">#88ffffff</color> <color name="band_select_border">#44000000</color> diff --git a/packages/DocumentsUI/res/values/config.xml b/packages/DocumentsUI/res/values/config.xml index 6590bbeda892..f0cab08723a8 100644 --- a/packages/DocumentsUI/res/values/config.xml +++ b/packages/DocumentsUI/res/values/config.xml @@ -20,13 +20,15 @@ <!-- Intentionally unset. Vendors should set this in an overlay. --> <string name="trusted_quick_viewer_package" translatable="false"></string> + + <!-- overridden for RTL langs --> <bool name="list_divider_inset_left">true</bool> - <!-- Indicates if the home directory should be hidden in the roots list, that is presented - in the drawer/left side panel ) --> - <bool name="home_root_hidden">true</bool> - <!-- Indicates if the advanced roots like internal storage should be shown in the roots list. - When enabled there is no menu option to toggle internal storage visibility. --> - <bool name="advanced_roots_shown">false</bool> + + <!-- Flags setup as productivity oriented in which case Downloads app will be presented + as Files app. Including showing of the Documents and "advanced" roots. --> + <bool name="productivity_device">false</bool> + <!-- Indicates if search view is taking the whole toolbar space --> <bool name="full_bar_search_view">true</bool> + </resources> diff --git a/packages/DocumentsUI/res/values/dimens.xml b/packages/DocumentsUI/res/values/dimens.xml index 5af7da33d997..e682994749b9 100644 --- a/packages/DocumentsUI/res/values/dimens.xml +++ b/packages/DocumentsUI/res/values/dimens.xml @@ -38,4 +38,8 @@ <dimen name="drag_shadow_size">120dp</dimen> <dimen name="grid_item_elevation">2dp</dimen> <dimen name="max_drawer_width">280dp</dimen> + + <dimen name="drag_shadow_width">160dp</dimen> + <dimen name="drag_shadow_height">48dp</dimen> + </resources> diff --git a/packages/DocumentsUI/res/values/strings.xml b/packages/DocumentsUI/res/values/strings.xml index fb557caf84f2..eb99a0d6f879 100644 --- a/packages/DocumentsUI/res/values/strings.xml +++ b/packages/DocumentsUI/res/values/strings.xml @@ -18,9 +18,6 @@ <!-- Title of the documents application [CHAR LIMIT=32] --> <string name="app_label">Documents</string> - <!-- Title of the standalone files activity. [CHAR LIMIT=32] --> - <string name="files_label">Files</string> - <!-- Title of the standalone downloads activity. [CHAR LIMIT=32] --> <string name="downloads_label">Downloads</string> @@ -223,6 +220,12 @@ <item quantity="other"><xliff:g id="count" example="3">%1$d</xliff:g> selected</item> </plurals> + <!-- Label text showing user how many items are being dragged. Can be one or more elements. --> + <plurals name="elements_dragged"> + <item quantity="one"><xliff:g id="count" example="1">%1$d</xliff:g> item</item> + <item quantity="other"><xliff:g id="count" example="3">%1$d</xliff:g> items</item> + </plurals> + <!-- Dialog text shown to users when asking if they want to delete a file (a confirmation) --> <string name="delete_filename_confirmation_message">Delete \"<xliff:g id="name" example="cat.jpg">%1$s</xliff:g>\"?</string> <!-- Dialog text shown to users when asking if they want to delete a folder (a confirmation) --> diff --git a/packages/DocumentsUI/res/values/styles.xml b/packages/DocumentsUI/res/values/styles.xml index b0996aa6941c..9f09ebc480e5 100644 --- a/packages/DocumentsUI/res/values/styles.xml +++ b/packages/DocumentsUI/res/values/styles.xml @@ -30,6 +30,7 @@ <item name="android:colorAccent">@color/accent</item> <item name="colorActionMode">@color/action_mode</item> <item name="android:queryBackground">@color/menu_search_background</item> + <item name="android:statusBarColor">@color/status_bar_color</item> <item name="android:listDivider">@*android:drawable/list_divider_material</item> diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java index 87136ef35bc9..4ee37a5988cd 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java @@ -19,10 +19,9 @@ package com.android.documentsui; import static com.android.documentsui.Shared.DEBUG; import static com.android.documentsui.Shared.EXTRA_BENCHMARK; import static com.android.documentsui.State.ACTION_CREATE; +import static com.android.documentsui.State.ACTION_GET_CONTENT; import static com.android.documentsui.State.ACTION_OPEN; import static com.android.documentsui.State.ACTION_OPEN_TREE; -import static com.android.documentsui.State.ACTION_GET_CONTENT; -import static com.android.documentsui.State.ACTION_PICK_COPY_DESTINATION; import static com.android.documentsui.State.MODE_GRID; import android.app.Activity; @@ -37,14 +36,12 @@ import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; -import android.os.MessageQueue; import android.os.MessageQueue.IdleHandler; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Root; import android.support.annotation.CallSuper; import android.support.annotation.LayoutRes; import android.support.annotation.Nullable; -import android.support.annotation.VisibleForTesting; import android.util.Log; import android.view.KeyEvent; import android.view.Menu; @@ -104,16 +101,6 @@ public abstract class BaseActivity extends Activity @CallSuper @Override public void onCreate(Bundle icicle) { - // This flag is being set here as a result of the bug. When the flag was set in the - // styles.xml keyboard was messing the layout of dialogs (create dir, rename). - // Attempts were made to keep the flag in the main theme and to override it in the dialog - // layout xml or to create separate style for dialog and assign it in styles.xml. - // None of this brought successful results. - // Setting the flag works here most probably because of the timing when it is set. Also the - // setting might not affect the dialogs that are created in new windows or it affects them - // in the different way that having this in the style. - getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); - // Record the time when onCreate is invoked for metric. mStartTime = new Date().getTime(); @@ -143,7 +130,6 @@ public abstract class BaseActivity extends Activity mSearchManager = new SearchViewManager(this, icicle); DocumentsToolbar toolbar = (DocumentsToolbar) findViewById(R.id.toolbar); - Display.adjustToolbar(toolbar, this); setActionBar(toolbar); mNavigator = new NavigationView( mDrawer, @@ -228,8 +214,7 @@ public abstract class BaseActivity extends Activity includeState(state); // Advanced roots are shown by deafult without menu option if forced by config or intent. - state.showAdvanced = getResources().getBoolean(R.bool.advanced_roots_shown) - || intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, false); + state.showAdvanced = Shared.shouldShowDeviceRoot(this, intent); // Menu option is shown for whitelisted intents if advanced roots are not shown by default. state.showAdvancedOption = !state.showAdvanced && (state.action == ACTION_OPEN || @@ -478,11 +463,11 @@ public abstract class BaseActivity extends Activity * Method can be overridden if the change of the behavior of the the child activity is needed. */ public Uri getDefaultRoot() { - return Shared.isHomeRootHidden(this) - ? DocumentsContract.buildRootUri("com.android.providers.downloads.documents", - "downloads") - : DocumentsContract.buildHomeUri(); - } + return Shared.shouldShowDocumentsRoot(this, getIntent()) + ? DocumentsContract.buildHomeUri() + : DocumentsContract.buildRootUri( + "com.android.providers.downloads.documents", "downloads"); + } void setDisplayAdvancedDevices(boolean display) { mState.showAdvanced = display; @@ -636,12 +621,12 @@ public abstract class BaseActivity extends Activity return true; } } else if (keyCode == KeyEvent.KEYCODE_TAB) { - Metrics.logKeyboardAction(this, keyCode); + Metrics.logKeyboardAction(this, Metrics.ACTION_KEYBOARD_SWITCH_FOCUS); // Tab toggles focus on the navigation drawer. toggleNavDrawerFocus(); return true; } else if (keyCode == KeyEvent.KEYCODE_DEL) { - Metrics.logKeyboardAction(this, keyCode); + Metrics.logKeyboardAction(this, Metrics.ACTION_KEYBOARD_BACK); popDir(); return true; } diff --git a/packages/DocumentsUI/src/com/android/documentsui/Display.java b/packages/DocumentsUI/src/com/android/documentsui/Display.java index d46a3eac94e9..8b13222dcce7 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/Display.java +++ b/packages/DocumentsUI/src/com/android/documentsui/Display.java @@ -20,8 +20,6 @@ import android.app.Activity; import android.content.Context; import android.graphics.Point; import android.util.TypedValue; -import android.view.WindowManager; -import android.widget.Toolbar; /* * Convenience class for getting display related attributes @@ -47,41 +45,12 @@ public final class Display { * Returns action bar height in raw pixels. */ public static float actionBarHeight(Context context) { - int height = 0; + int actionBarHeight = 0; TypedValue tv = new TypedValue(); if (context.getTheme().resolveAttribute(android.R.attr.actionBarSize, tv, true)) { - height = TypedValue.complexToDimensionPixelSize(tv.data, + actionBarHeight = TypedValue.complexToDimensionPixelSize(tv.data, context.getResources().getDisplayMetrics()); } - return height; - } - - /* - * Returns status bar height in raw pixels. - */ - private static int statusBarHeight(Context context) { - int height = 0; - int resourceId = context.getResources().getIdentifier("status_bar_height", "dimen", - "android"); - if (resourceId > 0) { - height = context.getResources().getDimensionPixelSize(resourceId); - } - return height; - } - - /* - * Adjusts toolbar for the layout with translucent status bar. Increases the - * height of the toolbar and adds padding at the top to accommodate status bar visible above - * toolbar. - */ - public static void adjustToolbar(Toolbar toolbar, Activity activity) { - if ((activity.getWindow().getAttributes().flags - & WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS) != 0) { - int statusBarHeight = Display.statusBarHeight(activity); - toolbar.getLayoutParams().height = (int) (Display.actionBarHeight(activity) - + statusBarHeight); - toolbar.setPadding(toolbar.getPaddingLeft(), statusBarHeight, toolbar.getPaddingRight(), - toolbar.getPaddingBottom()); - } + return actionBarHeight; } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java index 5788420a053c..40b54d34eb03 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -203,8 +203,8 @@ public class DocumentsActivity extends BaseActivity { mState.action == ACTION_PICK_COPY_DESTINATION) { title = getResources().getString(R.string.title_save); } else { - // If all else fails, just call it "Downloads". - title = getResources().getString(R.string.downloads_label); + // If all else fails, just call it "Documents". + title = getResources().getString(R.string.app_label); } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java index 900544220cce..5ea6cfa73fcd 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsApplication.java @@ -69,7 +69,7 @@ public class DocumentsApplication extends Application { final int memoryClassBytes = am.getMemoryClass() * 1024 * 1024; mRoots = new RootsCache(this); - mRoots.updateAsync(); + mRoots.updateAsync(false); mThumbnails = new ThumbnailCache(memoryClassBytes / 4); @@ -105,7 +105,7 @@ public class DocumentsApplication extends Application { final String packageName = data.getSchemeSpecificPart(); mRoots.updatePackageAsync(packageName); } else { - mRoots.updateAsync(); + mRoots.updateAsync(true); } } }; diff --git a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java index 7a4099ae791e..14e6b69bfc19 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DrawerController.java @@ -84,7 +84,7 @@ abstract class DrawerController implements DrawerListener { View drawer = activity.findViewById(R.id.drawer_roots); Toolbar toolbar = (Toolbar) activity.findViewById(R.id.roots_toolbar); - Display.adjustToolbar(toolbar, activity); + drawer.getLayoutParams().width = calculateDrawerWidth(activity); ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java index d4439d8b480f..527eb7804fb7 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java @@ -180,7 +180,10 @@ public class FilesActivity extends BaseActivity { @Override public String getDrawerTitle() { - return getResources().getString(R.string.downloads_label); + Intent intent = getIntent(); + return (intent != null && intent.hasExtra(Intent.EXTRA_TITLE)) + ? intent.getStringExtra(Intent.EXTRA_TITLE) + : getTitle().toString(); } @Override @@ -349,21 +352,21 @@ public class FilesActivity extends BaseActivity { case KeyEvent.KEYCODE_A: dir = getDirectoryFragment(); if (dir != null) { - Metrics.logKeyboardAction(this, keyCode); + Metrics.logKeyboardAction(this, Metrics.ACTION_KEYBOARD_SELECT_ALL); dir.selectAllFiles(); } return true; case KeyEvent.KEYCODE_C: dir = getDirectoryFragment(); if (dir != null) { - Metrics.logKeyboardAction(this, keyCode); + Metrics.logKeyboardAction(this, Metrics.ACTION_KEYBOARD_COPY); dir.copySelectedToClipboard(); } return true; case KeyEvent.KEYCODE_V: dir = getDirectoryFragment(); if (dir != null) { - Metrics.logKeyboardAction(this, keyCode); + Metrics.logKeyboardAction(this, Metrics.ACTION_KEYBOARD_PASTE); dir.pasteFromClipboard(); } return true; diff --git a/packages/DocumentsUI/src/com/android/documentsui/LauncherActivity.java b/packages/DocumentsUI/src/com/android/documentsui/LauncherActivity.java index 7930c28fc6c2..5cb6ca347896 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/LauncherActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/LauncherActivity.java @@ -87,9 +87,24 @@ public class LauncherActivity extends Activity { startActivity(intent); } - static final Intent createLaunchIntent(Context context) { - Intent intent = new Intent(context, FilesActivity.class); + static final Intent createLaunchIntent(Activity activity) { + Intent intent = new Intent(activity, FilesActivity.class); intent.setData(buildLaunchUri()); + + // Relay any config overrides bits present in the original intent. + Intent original = activity.getIntent(); + if (original != null) { + if (original.hasExtra(Shared.EXTRA_PRODUCTIVITY_MODE)) { + intent.putExtra( + Shared.EXTRA_PRODUCTIVITY_MODE, + original.getBooleanExtra(Shared.EXTRA_PRODUCTIVITY_MODE, false)); + } + if (original.hasExtra(Intent.EXTRA_TITLE)) { + intent.putExtra( + Intent.EXTRA_TITLE, + original.getStringExtra(Intent.EXTRA_TITLE)); + } + } return intent; } diff --git a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java index a4a67f96a3ee..05cc7e66f98c 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java +++ b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java @@ -296,13 +296,13 @@ public final class Metrics { // Do not change or rearrange these values, that will break historical data. Only add to the // list. // Do not use negative numbers or zero; clearcut only handles positive integers. - private static final int ACTION_KEYBOARD_OTHER = 1; - private static final int ACTION_KEYBOARD_PASTE = 2; - private static final int ACTION_KEYBOARD_COPY = 3; - private static final int ACTION_KEYBOARD_DELETE = 4; - private static final int ACTION_KEYBOARD_SELECT_ALL = 5; - private static final int ACTION_KEYBOARD_BACK = 6; - private static final int ACTION_KEYBOARD_SWITCH_FOCUS = 7; + public static final int ACTION_KEYBOARD_OTHER = 1; + public static final int ACTION_KEYBOARD_PASTE = 2; + public static final int ACTION_KEYBOARD_COPY = 3; + public static final int ACTION_KEYBOARD_DELETE = 4; + public static final int ACTION_KEYBOARD_SELECT_ALL = 5; + public static final int ACTION_KEYBOARD_BACK = 6; + public static final int ACTION_KEYBOARD_SWITCH_FOCUS = 7; @IntDef(flag = false, value = { ACTION_KEYBOARD_OTHER, @@ -525,31 +525,8 @@ public final class Metrics { * @param context * @param keyCode */ - public static void logKeyboardAction(Context context, int keyCode) { - @KeyboardAction int keyboardAction = ACTION_KEYBOARD_OTHER; - switch (keyCode) { - case KeyEvent.KEYCODE_V: - keyboardAction = ACTION_KEYBOARD_PASTE; - break; - case KeyEvent.KEYCODE_C: - keyboardAction = ACTION_KEYBOARD_COPY; - break; - case KeyEvent.KEYCODE_FORWARD_DEL: - keyboardAction = ACTION_KEYBOARD_DELETE; - break; - case KeyEvent.KEYCODE_A: - keyboardAction = ACTION_KEYBOARD_SELECT_ALL; - break; - case KeyEvent.KEYCODE_DEL: - keyboardAction = ACTION_KEYBOARD_BACK; - break; - case KeyEvent.KEYCODE_TAB: - keyboardAction = ACTION_KEYBOARD_SWITCH_FOCUS; - break; - default: - break; - } - logHistogram(context, COUNT_KEYBOARD_ACTION, keyboardAction); + public static void logKeyboardAction(Context context, @KeyboardAction int action) { + logHistogram(context, COUNT_KEYBOARD_ACTION, action); } /** diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java index 09fadc98a7e0..594e02f0a01d 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java +++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java @@ -122,7 +122,7 @@ public class RootsCache { /** * Gather roots from all known storage providers. */ - public void updateAsync() { + public void updateAsync(boolean forceRefreshAll) { // NOTE: This method is called when the UI language changes. // For that reason we update our RecentsRoot to reflect @@ -139,14 +139,15 @@ public class RootsCache { | Root.FLAG_SUPPORTS_CREATE)); assert(mRecentsRoot.availableBytes == -1); - new UpdateTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new UpdateTask(forceRefreshAll, null) + .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } /** * Gather roots from storage providers belonging to given package name. */ public void updatePackageAsync(String packageName) { - new UpdateTask(packageName).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + new UpdateTask(false, packageName).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); } /** @@ -223,23 +224,22 @@ public class RootsCache { } private class UpdateTask extends AsyncTask<Void, Void, Void> { + private final boolean mForceRefreshAll; private final String mForceRefreshPackage; private final Multimap<String, RootInfo> mTaskRoots = ArrayListMultimap.create(); private final HashSet<String> mTaskStoppedAuthorities = new HashSet<>(); /** - * Update all roots. + * Create task to update roots cache. + * + * @param forceRefreshAll when true, all previously cached values for + * all packages should be ignored. + * @param forceRefreshPackage when non-null, all previously cached + * values for this specific package should be ignored. */ - public UpdateTask() { - this(null); - } - - /** - * Force update roots belonging to given package name. Other roots will - * be copied from cached {@link #mRoots} values. - */ - public UpdateTask(String forceRefreshPackage) { + public UpdateTask(boolean forceRefreshAll, String forceRefreshPackage) { + mForceRefreshAll = forceRefreshAll; mForceRefreshPackage = forceRefreshPackage; } @@ -247,14 +247,6 @@ public class RootsCache { protected Void doInBackground(Void... params) { final long start = SystemClock.elapsedRealtime(); - if (mForceRefreshPackage != null) { - // We must have previously cached values to fill in non-matching - // packages, so wait around for successful first load. - if (!waitForFirstLoad()) { - return null; - } - } - mTaskRoots.put(mRecentsRoot.authority, mRecentsRoot); final ContentResolver resolver = mContext.getContentResolver(); @@ -300,7 +292,8 @@ public class RootsCache { return; } - final boolean forceRefresh = Objects.equals(mForceRefreshPackage, info.packageName); + final boolean forceRefresh = mForceRefreshAll + || Objects.equals(info.packageName, mForceRefreshPackage); mTaskRoots.putAll(info.authority, loadRootsForAuthority(mContext.getContentResolver(), info.authority, forceRefresh)); } diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java index 5f665c0e4dd5..8bbcc306af9a 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/RootsFragment.java @@ -17,8 +17,8 @@ package com.android.documentsui; import static com.android.documentsui.Shared.DEBUG; -import static com.android.documentsui.State.ACTION_OPEN_TREE; +import android.app.Activity; import android.app.Fragment; import android.app.FragmentManager; import android.app.FragmentTransaction; @@ -319,7 +319,8 @@ public class RootsFragment extends Fragment { for (final RootInfo root : roots) { final RootItem item = new RootItem(root); - if (root.isHome() && Shared.isHomeRootHidden(context)) { + if (root.isHome() && + !Shared.shouldShowDocumentsRoot(context, ((Activity) context).getIntent())) { continue; } else if (root.isLibrary()) { if (DEBUG) Log.d(TAG, "Adding " + root + " as library."); diff --git a/packages/DocumentsUI/src/com/android/documentsui/Shared.java b/packages/DocumentsUI/src/com/android/documentsui/Shared.java index 2c60d4a3212f..1ba836a7fa4a 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/Shared.java +++ b/packages/DocumentsUI/src/com/android/documentsui/Shared.java @@ -16,19 +16,16 @@ package com.android.documentsui; +import android.app.AlertDialog; import android.content.Context; +import android.content.Intent; import android.content.res.Configuration; +import android.provider.DocumentsContract; import android.text.TextUtils; import android.text.format.DateUtils; import android.text.format.Time; import android.view.WindowManager; -import com.android.documentsui.State.ActionType; - -import static com.android.documentsui.State.ACTION_OPEN_TREE; - -import android.app.AlertDialog; - import java.text.Collator; import java.util.ArrayList; import java.util.List; @@ -45,10 +42,21 @@ public final class Shared { "com.android.documentsui.PICK_COPY_DESTINATION"; /** + * Extra flag allowing app to be opened in productivity mode (less downloadsy). + * Useful developers and the likes. When set to true overrides the default + * config value of productivity_device. + */ + public static final String EXTRA_PRODUCTIVITY_MODE = "com.android.documentsui.PRODUCTIVITY"; + + /** * Extra boolean flag for {@link ACTION_PICK_COPY_DESTINATION}, which * specifies if the destination directory needs to create new directory or not. */ public static final String EXTRA_DIRECTORY_COPY = "com.android.documentsui.DIRECTORY_COPY"; + + /** + * Extra flag used to store the current stack so user opens in right spot. + */ public static final String EXTRA_STACK = "com.android.documentsui.STACK"; /** @@ -175,10 +183,33 @@ public final class Shared { } /* - * Indicates if the home directory should be hidden in the roots list. + * Returns true if app is running in "productivity mode". */ - public static boolean isHomeRootHidden(Context context) { - return context.getResources().getBoolean(R.bool.home_root_hidden); + public static boolean productivityMode(Context context) { + return context.getResources().getBoolean(R.bool.productivity_device); } + /* + * Returns true if app is running in "productivity mode". + */ + private static boolean isProductivityMode(Context context, Intent intent) { + return intent.getBooleanExtra( + Shared.EXTRA_PRODUCTIVITY_MODE, + context.getResources().getBoolean(R.bool.productivity_device)); + } + + /* + * Returns true if "Documents" root should be shown. + */ + public static boolean shouldShowDocumentsRoot(Context context, Intent intent) { + return isProductivityMode(context, intent); + } + + /* + * Returns true if device root should be shown. + */ + public static boolean shouldShowDeviceRoot(Context context, Intent intent) { + return isProductivityMode(context, intent) + || intent.getBooleanExtra(DocumentsContract.EXTRA_SHOW_ADVANCED, false); + } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/State.java b/packages/DocumentsUI/src/com/android/documentsui/State.java index c7d60e3d1133..f239eb45552b 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/State.java +++ b/packages/DocumentsUI/src/com/android/documentsui/State.java @@ -123,9 +123,6 @@ public class State implements android.os.Parcelable { /** Instance state for every shown directory */ public HashMap<String, SparseArray<Parcelable>> dirState = new HashMap<>(); - /** UI selection */ - public Selection selectedDocuments = new Selection(); - /** Currently copying file */ public List<DocumentInfo> selectedDocumentsForCopy = new ArrayList<>(); @@ -202,7 +199,6 @@ public class State implements android.os.Parcelable { out.writeInt(external ? 1 : 0); DurableUtils.writeToParcel(out, stack); out.writeMap(dirState); - out.writeParcelable(selectedDocuments, 0); out.writeList(selectedDocumentsForCopy); out.writeList(excludedAuthorities); out.writeInt(openableOnly ? 1 : 0); @@ -233,7 +229,6 @@ public class State implements android.os.Parcelable { state.external = in.readInt() != 0; DurableUtils.readFromParcel(in, state.stack); in.readMap(state.dirState, loader); - state.selectedDocuments = in.readParcelable(loader); in.readList(state.selectedDocumentsForCopy, loader); in.readList(state.excludedAuthorities, loader); state.openableOnly = in.readInt() != 0; diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java index 20316fff31b4..1c85a8aba0b1 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java @@ -40,10 +40,12 @@ import android.content.Loader; import android.database.Cursor; import android.graphics.Canvas; import android.graphics.Point; +import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; +import android.os.Parcel; import android.os.Parcelable; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Document; @@ -72,8 +74,8 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; -import android.widget.Toolbar; import android.widget.TextView; +import android.widget.Toolbar; import com.android.documentsui.BaseActivity; import com.android.documentsui.DirectoryLoader; @@ -106,6 +108,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.Objects; @@ -224,7 +227,8 @@ public class DirectoryFragment extends Fragment mStateKey = buildStateKey(mRoot, mDocument); mQuery = args.getString(Shared.EXTRA_QUERY); mType = args.getInt(Shared.EXTRA_TYPE); - mSelection = args.getParcelable(Shared.EXTRA_SELECTION); + final Selection selection = args.getParcelable(Shared.EXTRA_SELECTION); + mSelection = selection != null ? selection : new Selection(); mSearchMode = args.getBoolean(Shared.EXTRA_SEARCH_MODE); mIconHelper = new IconHelper(context, MODE_GRID); @@ -288,14 +292,25 @@ public class DirectoryFragment extends Fragment outState.putParcelable(Shared.EXTRA_ROOT, mRoot); outState.putParcelable(Shared.EXTRA_DOC, mDocument); outState.putString(Shared.EXTRA_QUERY, mQuery); - outState.putParcelable(Shared.EXTRA_SELECTION, mSelection); - outState.putBoolean(Shared.EXTRA_SEARCH_MODE, mSearchMode); + // Workaround. To avoid crash, write only up to 512 KB of selection. + // If more files are selected, then the selection will be lost. + final Parcel parcel = Parcel.obtain(); + try { + mSelection.writeToParcel(parcel, 0); + if (parcel.dataSize() <= 512 * 1024) { + outState.putParcelable(Shared.EXTRA_SELECTION, mSelection); + } + } finally { + parcel.recycle(); + } + + outState.putBoolean(Shared.EXTRA_SEARCH_MODE, mSearchMode); } @Override public void onActivityResult(@RequestCode int requestCode, int resultCode, Intent data) { - switch(requestCode) { + switch (requestCode) { case REQUEST_COPY_DESTINATION: handleCopyResult(resultCode, data); break; @@ -488,24 +503,19 @@ public class DirectoryFragment extends Fragment @Override public void onSelectionChanged() { mSelectionManager.getSelection(mSelected); - TypedValue color = new TypedValue(); if (mSelected.size() > 0) { if (DEBUG) Log.d(TAG, "Maybe starting action mode."); if (mActionMode == null) { if (DEBUG) Log.d(TAG, "Yeah. Starting action mode."); mActionMode = getActivity().startActionMode(this); } - getActivity().getTheme().resolveAttribute(R.attr.colorActionMode, color, true); updateActionMenu(); } else { if (DEBUG) Log.d(TAG, "Finishing action mode."); if (mActionMode != null) { mActionMode.finish(); } - getActivity().getTheme().resolveAttribute( - android.R.attr.colorPrimaryDark, color, true); } - getActivity().getWindow().setStatusBarColor(color.data); if (mActionMode != null) { final String title = Shared.getQuantityString(getActivity(), @@ -1063,8 +1073,19 @@ public class DirectoryFragment extends Fragment } public void selectAllFiles() { + // Exclude disabled files + List<String> enabled = new ArrayList<String>(); + for (String id : mAdapter.getModelIds()) { + Cursor cursor = getModel().getItem(id); + String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); + int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); + if (isDocumentEnabled(docMimeType, docFlags)) { + enabled.add(id); + } + } + // Only select things currently visible in the adapter. - boolean changed = mSelectionManager.setItemsSelected(mAdapter.getModelIds(), true); + boolean changed = mSelectionManager.setItemsSelected(enabled, true); if (changed) { updateDisplayState(); } @@ -1217,41 +1238,68 @@ public class DirectoryFragment extends Fragment DocumentInfo.fromDirectoryCursor(cursor)); } - private Drawable getDragShadowIcon(List<DocumentInfo> docs) { - if (docs.size() == 1) { - final DocumentInfo doc = docs.get(0); - return mIconHelper.getDocumentIcon(getActivity(), doc.authority, doc.documentId, - doc.mimeType, doc.icon); - } - return getActivity().getDrawable(R.drawable.ic_doc_generic); - } + private static class DragShadowBuilder extends View.DragShadowBuilder { + + private final Context mContext; + private final IconHelper mIconHelper; + private final LayoutInflater mInflater; + private final View mShadowView; + private final TextView mTitle; + private final ImageView mIcon; + private final int mWidth; + private final int mHeight; + + public DragShadowBuilder(Context context, IconHelper iconHelper, List<DocumentInfo> docs) { + mContext = context; + mIconHelper = iconHelper; + mInflater = LayoutInflater.from(context); + + mWidth = mContext.getResources().getDimensionPixelSize(R.dimen.drag_shadow_width); + mHeight= mContext.getResources().getDimensionPixelSize(R.dimen.drag_shadow_height); - private class DrawableShadowBuilder extends View.DragShadowBuilder { + mShadowView = mInflater.inflate(R.layout.drag_shadow_layout, null); + mTitle = (TextView) mShadowView.findViewById(android.R.id.title); + mIcon = (ImageView) mShadowView.findViewById(android.R.id.icon); - private final Drawable mShadow; + mTitle.setText(getTitle(docs)); + mIcon.setImageDrawable(getIcon(docs)); + } - private final int mShadowDimension; + private Drawable getIcon(List<DocumentInfo> docs) { + if (docs.size() == 1) { + final DocumentInfo doc = docs.get(0); + return mIconHelper.getDocumentIcon(mContext, doc.authority, doc.documentId, + doc.mimeType, doc.icon); + } + return mContext.getDrawable(R.drawable.ic_doc_generic); + } - public DrawableShadowBuilder(Drawable shadow) { - mShadow = shadow; - mShadowDimension = getResources().getDimensionPixelSize( - R.dimen.drag_shadow_size); - mShadow.setBounds(0, 0, mShadowDimension, mShadowDimension); + private String getTitle(List<DocumentInfo> docs) { + if (docs.size() == 1) { + final DocumentInfo doc = docs.get(0); + return doc.displayName; + } + return Shared.getQuantityString(mContext, R.plurals.elements_dragged, docs.size()); } @Override public void onProvideShadowMetrics( Point shadowSize, Point shadowTouchPoint) { - shadowSize.set(mShadowDimension, mShadowDimension); - shadowTouchPoint.set(mShadowDimension / 2, mShadowDimension / 2); + shadowSize.set(mWidth, mHeight); + shadowTouchPoint.set(mWidth, mHeight); } @Override public void onDrawShadow(Canvas canvas) { - mShadow.draw(canvas); + Rect r = canvas.getClipBounds(); + // Calling measure is necessary in order for all child views to get correctly laid out. + mShadowView.measure( + View.MeasureSpec.makeMeasureSpec(r.right- r.left, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(r.top- r.bottom, View.MeasureSpec.EXACTLY)); + mShadowView.layout(r.left, r.top, r.right, r.bottom); + mShadowView.draw(canvas); } } - /** * Abstract task providing support for loading documents *off* * the main thread. And if it isn't obvious, creating a list @@ -1339,7 +1387,7 @@ public class DirectoryFragment extends Fragment // This has to be handled here instead of in a keyboard shortcut, because // keyboard shortcuts all have to be modified with the 'Ctrl' key. if (mSelectionManager.hasSelection()) { - Metrics.logKeyboardAction(getContext(), keyCode); + Metrics.logKeyboardAction(getContext(), Metrics.ACTION_KEYBOARD_DELETE); deleteDocuments(mSelectionManager.getSelection()); } // Always handle the key, even if there was nothing to delete. This is a @@ -1402,7 +1450,7 @@ public class DirectoryFragment extends Fragment } v.startDragAndDrop( mClipper.getClipDataForDocuments(docs), - new DrawableShadowBuilder(getDragShadowIcon(docs)), + new DragShadowBuilder(getActivity(), mIconHelper, docs), getDisplayState().stack.peek(), View.DRAG_FLAG_GLOBAL | View.DRAG_FLAG_GLOBAL_URI_READ | View.DRAG_FLAG_GLOBAL_URI_WRITE diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java index faa8e3892f61..016cc9e889df 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java @@ -148,11 +148,15 @@ public abstract class FragmentTuner { MenuItem share = menu.findItem(R.id.menu_share); MenuItem delete = menu.findItem(R.id.menu_delete); MenuItem rename = menu.findItem(R.id.menu_rename); + MenuItem selectAll = menu.findItem(R.id.menu_select_all); open.setVisible(true); share.setVisible(false); delete.setVisible(false); rename.setVisible(false); + selectAll.setVisible(mState.allowMultiple); + + Menus.disableHiddenItems(menu); } @Override diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java index f2949196f2a1..69f0e677eb04 100644 --- a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java +++ b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java @@ -22,8 +22,10 @@ import static com.android.documentsui.StubProvider.ROOT_1_ID; import android.app.DownloadManager; import android.app.DownloadManager.Request; import android.content.Context; +import android.content.Intent; import android.net.Uri; import android.os.RemoteException; +import android.provider.DocumentsContract; import android.support.test.uiautomator.Configurator; import android.support.test.uiautomator.UiObject; import android.test.suitebuilder.annotation.LargeTest; @@ -69,11 +71,10 @@ public class FilesActivityUiTest extends ActivityTest<FilesActivity> { ROOT_1_ID); // Separate logic for "Documents" root, which presence depends on the config setting - boolean homeRootHidden = context.getResources().getBoolean(R.bool.home_root_hidden); - if (homeRootHidden) { - bots.roots.assertRootsAbsent("Documents"); - } else { + if (Shared.shouldShowDocumentsRoot(context, new Intent(DocumentsContract.ACTION_BROWSE))) { bots.roots.assertRootsPresent("Documents"); + } else { + bots.roots.assertRootsAbsent("Documents"); } } diff --git a/packages/Keyguard/res/drawable/ic_backspace_24dp.xml b/packages/Keyguard/res/drawable/ic_backspace_24dp.xml index 47c8d14330c0..1e4022ea402b 100644 --- a/packages/Keyguard/res/drawable/ic_backspace_24dp.xml +++ b/packages/Keyguard/res/drawable/ic_backspace_24dp.xml @@ -15,6 +15,7 @@ Copyright (C) 2014 The Android Open Source Project --> <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" + android:autoMirrored="true" android:height="24dp" android:viewportWidth="48.0" android:viewportHeight="48.0"> diff --git a/packages/Keyguard/res/values/attrs.xml b/packages/Keyguard/res/values/attrs.xml index 96a5bcc5fcbc..7cfe6316084f 100644 --- a/packages/Keyguard/res/values/attrs.xml +++ b/packages/Keyguard/res/values/attrs.xml @@ -32,6 +32,9 @@ <declare-styleable name="PasswordTextView"> <attr name="scaledTextSize" format="integer" /> + <attr name="android:gravity" /> + <attr name="dotSize" format="dimension" /> + <attr name="charPadding" format="dimension" /> </declare-styleable> <declare-styleable name="CarrierText"> diff --git a/packages/Keyguard/src/com/android/keyguard/NumPadKey.java b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java index ef8bb0be0d14..2ff7e121721a 100644 --- a/packages/Keyguard/src/com/android/keyguard/NumPadKey.java +++ b/packages/Keyguard/src/com/android/keyguard/NumPadKey.java @@ -71,6 +71,10 @@ public class NumPadKey extends ViewGroup { } public NumPadKey(Context context, AttributeSet attrs, int defStyle) { + this(context, attrs, defStyle, R.layout.keyguard_num_pad_key); + } + + protected NumPadKey(Context context, AttributeSet attrs, int defStyle, int contentResource) { super(context, attrs, defStyle); setFocusable(true); @@ -92,7 +96,7 @@ public class NumPadKey extends ViewGroup { mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE); - inflater.inflate(R.layout.keyguard_num_pad_key, this, true); + inflater.inflate(contentResource, this, true); mDigitText = (TextView) findViewById(R.id.digit_text); mDigitText.setText(Integer.toString(mDigit)); @@ -113,7 +117,11 @@ public class NumPadKey extends ViewGroup { } } - setBackground(mContext.getDrawable(R.drawable.ripple_drawable)); + a = context.obtainStyledAttributes(attrs, android.R.styleable.View); + if (!a.hasValueOrEmpty(android.R.styleable.View_background)) { + setBackground(mContext.getDrawable(R.drawable.ripple_drawable)); + } + a.recycle(); setContentDescription(mDigitText.getText().toString()); } diff --git a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java index 50e7ecb92ffc..6eea81bf4014 100644 --- a/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java +++ b/packages/Keyguard/src/com/android/keyguard/PasswordTextView.java @@ -33,6 +33,7 @@ import android.provider.Settings; import android.text.InputType; import android.text.TextUtils; import android.util.AttributeSet; +import android.view.Gravity; import android.view.View; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; @@ -81,6 +82,7 @@ public class PasswordTextView extends View { * The raw text size, will be multiplied by the scaled density when drawn */ private final int mTextHeightRaw; + private final int mGravity; private ArrayList<CharState> mTextChars = new ArrayList<>(); private String mText = ""; private Stack<CharState> mCharPool = new Stack<>(); @@ -118,6 +120,12 @@ public class PasswordTextView extends View { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.PasswordTextView); try { mTextHeightRaw = a.getInt(R.styleable.PasswordTextView_scaledTextSize, 0); + mGravity = a.getInt(R.styleable.PasswordTextView_android_gravity, Gravity.CENTER); + mDotSize = a.getDimensionPixelSize(R.styleable.PasswordTextView_dotSize, + getContext().getResources().getDimensionPixelSize(R.dimen.password_dot_size)); + mCharPadding = a.getDimensionPixelSize(R.styleable.PasswordTextView_charPadding, + getContext().getResources().getDimensionPixelSize( + R.dimen.password_char_padding)); } finally { a.recycle(); } @@ -125,9 +133,6 @@ public class PasswordTextView extends View { mDrawPaint.setTextAlign(Paint.Align.CENTER); mDrawPaint.setColor(0xffffffff); mDrawPaint.setTypeface(Typeface.create("sans-serif-light", 0)); - mDotSize = getContext().getResources().getDimensionPixelSize(R.dimen.password_dot_size); - mCharPadding = getContext().getResources().getDimensionPixelSize(R.dimen - .password_char_padding); mShowPassword = Settings.System.getInt(mContext.getContentResolver(), Settings.System.TEXT_SHOW_PASSWORD, 1) == 1; mAppearInterpolator = AnimationUtils.loadInterpolator(mContext, @@ -142,11 +147,23 @@ public class PasswordTextView extends View { @Override protected void onDraw(Canvas canvas) { float totalDrawingWidth = getDrawingWidth(); - float currentDrawPosition = getWidth() / 2 - totalDrawingWidth / 2; + float currentDrawPosition; + if ((mGravity & Gravity.START) != 0) { + if (getLayoutDirection() == LAYOUT_DIRECTION_RTL) { + currentDrawPosition = getWidth() - getPaddingRight() - totalDrawingWidth; + } else { + currentDrawPosition = getPaddingLeft(); + } + } else { + currentDrawPosition = getWidth() / 2 - totalDrawingWidth / 2; + } int length = mTextChars.size(); Rect bounds = getCharBounds(); int charHeight = (bounds.bottom - bounds.top); - float yPosition = getHeight() / 2; + float yPosition = + (getHeight() - getPaddingBottom() - getPaddingTop()) / 2 + getPaddingTop(); + canvas.clipRect(getPaddingLeft(), getPaddingTop(), + getWidth()-getPaddingRight(), getHeight()-getPaddingBottom()); float charLength = bounds.right - bounds.left; for (int i = 0; i < length; i++) { CharState charState = mTextChars.get(i); diff --git a/packages/PrintServiceRecommendationService/res/values/strings.xml b/packages/PrintServiceRecommendationService/res/values/strings.xml index 83d38000395a..07d0004fa09b 100644 --- a/packages/PrintServiceRecommendationService/res/values/strings.xml +++ b/packages/PrintServiceRecommendationService/res/values/strings.xml @@ -23,7 +23,7 @@ <string name="plugin_vendor_brother">Brother</string> <string name="plugin_vendor_canon">Canon</string> <string name="plugin_vendor_xerox">Xerox</string> - <string name="plugin_vendor_samsung">Samsung Electorics</string> + <string name="plugin_vendor_samsung">Samsung Electronics</string> <string name="plugin_vendor_epson">Epson</string> <string name="plugin_vendor_konika_minolta">Konika Minolta</string> <string name="plugin_vendor_fuji">Fuji</string> diff --git a/packages/PrintServiceRecommendationService/res/xml/vendorconfigs.xml b/packages/PrintServiceRecommendationService/res/xml/vendorconfigs.xml index fda2768c8678..119943cd5f9f 100644 --- a/packages/PrintServiceRecommendationService/res/xml/vendorconfigs.xml +++ b/packages/PrintServiceRecommendationService/res/xml/vendorconfigs.xml @@ -46,7 +46,7 @@ <vendor> <name>@string/plugin_vendor_canon</name> - <package>com.xerox.printservice</package> + <package>jp.co.canon.android.printservice.plugin</package> <mdns-names> <mdns-name>Canon</mdns-name> </mdns-names> @@ -54,7 +54,7 @@ <vendor> <name>@string/plugin_vendor_xerox</name> - <package>jp.co.canon.android.printservice.plugin</package> + <package>com.xerox.printservice</package> <mdns-names> <mdns-name>Xerox</mdns-name> </mdns-names> diff --git a/packages/PrintSpooler/res/layout/print_activity_controls.xml b/packages/PrintSpooler/res/layout/print_activity_controls.xml index a87afe0a77a9..248d0c05934a 100644 --- a/packages/PrintSpooler/res/layout/print_activity_controls.xml +++ b/packages/PrintSpooler/res/layout/print_activity_controls.xml @@ -239,7 +239,8 @@ android:singleLine="true" android:ellipsize="end" android:visibility="visible" - android:inputType="textNoSuggestions"> + android:inputType="number" + android:digits="0123456789 ,-"> </com.android.printspooler.widget.CustomErrorEditText> </LinearLayout> diff --git a/packages/PrintSpooler/res/values-af/strings.xml b/packages/PrintSpooler/res/values-af/strings.xml index 0224c6c596c0..fa5ec3f5269c 100644 --- a/packages/PrintSpooler/res/values-af/strings.xml +++ b/packages/PrintSpooler/res/values-af/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Aanbevole dienste"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Gedeaktiveerde dienste"</string> <string name="all_services_title" msgid="5578662754874906455">"Alle dienste"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Installeer om <xliff:g id="COUNT_1">%1$s</xliff:g> drukkers te ontdek</item> + <item quantity="one">Installeer om <xliff:g id="COUNT_0">%1$s</xliff:g> drukker ontdek</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Druk tans <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Kanselleer tans <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Drukkerfout by <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-am/strings.xml b/packages/PrintSpooler/res/values-am/strings.xml index 98255d46f2c9..5ada8d31ed42 100644 --- a/packages/PrintSpooler/res/values-am/strings.xml +++ b/packages/PrintSpooler/res/values-am/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"የሚመከሩ አገልግሎቶች"</string> <string name="disabled_services_title" msgid="7313253167968363211">"የተሰናከሉ አገልግሎቶች"</string> <string name="all_services_title" msgid="5578662754874906455">"ሁሉም አገልግሎቶች"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> አታሚዎች ለማግኘት ይጫኑ</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> አታሚዎች ለማግኘት ይጫኑ</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ን በማተም ላይ"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ን በመተው ላይ"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"የአታሚ ስህተት <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ar/strings.xml b/packages/PrintSpooler/res/values-ar/strings.xml index 5f0255c5dd8b..1208298bd701 100644 --- a/packages/PrintSpooler/res/values-ar/strings.xml +++ b/packages/PrintSpooler/res/values-ar/strings.xml @@ -76,6 +76,14 @@ <string name="recommended_services_title" msgid="3799434882937956924">"الخدمات الموصى بها"</string> <string name="disabled_services_title" msgid="7313253167968363211">"الخدمات المعطَّلة"</string> <string name="all_services_title" msgid="5578662754874906455">"جميع الخدمات"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="zero">التثبيت لاستكشاف <xliff:g id="COUNT_1">%1$s</xliff:g> طابعات</item> + <item quantity="two">التثبيت لاستكشاف طابعتين (<xliff:g id="COUNT_1">%1$s</xliff:g>)</item> + <item quantity="few">التثبيت لاستكشاف <xliff:g id="COUNT_1">%1$s</xliff:g> طابعات</item> + <item quantity="many">التثبيت لاستكشاف <xliff:g id="COUNT_1">%1$s</xliff:g> طابعة</item> + <item quantity="other">التثبيت لاستكشاف <xliff:g id="COUNT_1">%1$s</xliff:g> طابعات</item> + <item quantity="one">التثبيت لاستكشاف <xliff:g id="COUNT_0">%1$s</xliff:g> طابعة</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"جارٍ طباعة <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"جارٍ إلغاء <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"خطا في الطابعة <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-az-rAZ/strings.xml b/packages/PrintSpooler/res/values-az-rAZ/strings.xml index b5dfaf89b6ff..4404aadb4e44 100644 --- a/packages/PrintSpooler/res/values-az-rAZ/strings.xml +++ b/packages/PrintSpooler/res/values-az-rAZ/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Tövsiyə olunan xidmətlər"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Deaktiv edilmiş xidmətlər"</string> <string name="all_services_title" msgid="5578662754874906455">"Bütün xidmətlər"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> printeri kəşf etmək üçün quraşdırın</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> printeri kəşf etmək üçün quraşdırın</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> çap edilir"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ləğv edilir"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printer xətası <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml index 2ac80028cc32..50ce1f96b912 100644 --- a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml +++ b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml @@ -73,6 +73,11 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Preporučene usluge"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Onemogućene usluge"</string> <string name="all_services_title" msgid="5578662754874906455">"Sve usluge"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Instalirajte da biste otkrili <xliff:g id="COUNT_1">%1$s</xliff:g> štampač</item> + <item quantity="few">Instalirajte da biste otkrili <xliff:g id="COUNT_1">%1$s</xliff:g> štampača</item> + <item quantity="other">Instalirajte da biste otkrili <xliff:g id="COUNT_1">%1$s</xliff:g> štampača</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Štampa se <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Otkazuje se <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Greška štampača <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-be-rBY/strings.xml b/packages/PrintSpooler/res/values-be-rBY/strings.xml index 13d573ec5921..c264f9266b81 100644 --- a/packages/PrintSpooler/res/values-be-rBY/strings.xml +++ b/packages/PrintSpooler/res/values-be-rBY/strings.xml @@ -74,6 +74,12 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Рэкамендаваныя службы"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Адключаныя службы"</string> <string name="all_services_title" msgid="5578662754874906455">"Усе службы"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Усталюйце, каб знайсці <xliff:g id="COUNT_1">%1$s</xliff:g> прынтар</item> + <item quantity="few">Усталюйце, каб знайсці <xliff:g id="COUNT_1">%1$s</xliff:g> прынтары</item> + <item quantity="many">Усталюйце, каб знайсці <xliff:g id="COUNT_1">%1$s</xliff:g> прынтараў</item> + <item quantity="other">Усталюйце, каб знайсці <xliff:g id="COUNT_1">%1$s</xliff:g> прынтара</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Друк <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Скасоўваецца <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Памылка друку <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-bg/strings.xml b/packages/PrintSpooler/res/values-bg/strings.xml index 73c51e9ad1d3..3dd6ec566ce7 100644 --- a/packages/PrintSpooler/res/values-bg/strings.xml +++ b/packages/PrintSpooler/res/values-bg/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Препоръчителни услуги"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Деактивирани услуги"</string> <string name="all_services_title" msgid="5578662754874906455">"Всички услуги"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Инсталирайте, за да бъдат открити <xliff:g id="COUNT_1">%1$s</xliff:g> принтера</item> + <item quantity="one">Инсталирайте, за да бъде открит <xliff:g id="COUNT_0">%1$s</xliff:g> принтер</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"„<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“ се отпечатва"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"„<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“ се анулира"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Грешка в принтера при „<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“"</string> diff --git a/packages/PrintSpooler/res/values-bn-rBD/strings.xml b/packages/PrintSpooler/res/values-bn-rBD/strings.xml index 25b4660265f6..3789f21db147 100644 --- a/packages/PrintSpooler/res/values-bn-rBD/strings.xml +++ b/packages/PrintSpooler/res/values-bn-rBD/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"প্রস্তাবিত পরিষেবাগুলি"</string> <string name="disabled_services_title" msgid="7313253167968363211">"অক্ষম করা পরিষেবাগুলি"</string> <string name="all_services_title" msgid="5578662754874906455">"সমস্ত পরিষেবা"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g>টি মুদ্রক খুঁজে পেতে ইনস্টল করুন</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g>টি মুদ্রক খুঁজে পেতে ইনস্টল করুন</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> প্রিন্ট করা হচ্ছে"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> বাতিল করা হচ্ছে"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> মুদ্রক ত্রুটি"</string> diff --git a/packages/PrintSpooler/res/values-bs-rBA/strings.xml b/packages/PrintSpooler/res/values-bs-rBA/strings.xml index 9a17707210da..c3c9bb33e9c3 100644 --- a/packages/PrintSpooler/res/values-bs-rBA/strings.xml +++ b/packages/PrintSpooler/res/values-bs-rBA/strings.xml @@ -73,6 +73,11 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Preporučene usluge"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Isključene usluge"</string> <string name="all_services_title" msgid="5578662754874906455">"Sve usluge"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one"> Instaliraj da pronađeš <xliff:g id="COUNT_1">%1$s</xliff:g> štampač</item> + <item quantity="few"> Instaliraj da pronađeš <xliff:g id="COUNT_1">%1$s</xliff:g> štampača</item> + <item quantity="other"> Instaliraj da pronađeš <xliff:g id="COUNT_1">%1$s</xliff:g> štampača</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Štampa se <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Otkazivanje <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Greška pri štampanju <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ca/strings.xml b/packages/PrintSpooler/res/values-ca/strings.xml index a1df40603404..f65a63c95874 100644 --- a/packages/PrintSpooler/res/values-ca/strings.xml +++ b/packages/PrintSpooler/res/values-ca/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Serveis recomanats"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Serveis desactivats"</string> <string name="all_services_title" msgid="5578662754874906455">"Tots els serveis"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Instal·la\'l per detectar <xliff:g id="COUNT_1">%1$s</xliff:g> impressores</item> + <item quantity="one">Instal·la\'l per detectar <xliff:g id="COUNT_0">%1$s</xliff:g> impressora</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"S\'està imprimint <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"S\'està cancel·lant <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Error d\'impressora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-cs/strings.xml b/packages/PrintSpooler/res/values-cs/strings.xml index 55fb21bbc24b..9bfa2719ef49 100644 --- a/packages/PrintSpooler/res/values-cs/strings.xml +++ b/packages/PrintSpooler/res/values-cs/strings.xml @@ -74,6 +74,12 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Doporučené služby"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Deaktivované služby"</string> <string name="all_services_title" msgid="5578662754874906455">"Všechny služby"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="few">Instalací objevíte <xliff:g id="COUNT_1">%1$s</xliff:g> tiskárny</item> + <item quantity="many">Instalací objevíte <xliff:g id="COUNT_1">%1$s</xliff:g> tiskárny</item> + <item quantity="other">Instalací objevíte <xliff:g id="COUNT_1">%1$s</xliff:g> tiskáren</item> + <item quantity="one">Instalací objevíte <xliff:g id="COUNT_0">%1$s</xliff:g> tiskárnu</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Tisk úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Rušení úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Chyba tiskárny u úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-da/strings.xml b/packages/PrintSpooler/res/values-da/strings.xml index 49417bd75f04..75a0b56f01de 100644 --- a/packages/PrintSpooler/res/values-da/strings.xml +++ b/packages/PrintSpooler/res/values-da/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Anbefalede tjenester"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Deaktiverede tjenester"</string> <string name="all_services_title" msgid="5578662754874906455">"Alle tjenester"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Installer for at finde <xliff:g id="COUNT_1">%1$s</xliff:g> printer</item> + <item quantity="other">Installer for at finde <xliff:g id="COUNT_1">%1$s</xliff:g> printere</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> udskrives"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> annulleres"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Udskriften <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> mislykkedes"</string> diff --git a/packages/PrintSpooler/res/values-de/strings.xml b/packages/PrintSpooler/res/values-de/strings.xml index cb7aeee3cd2b..8c6181d31b04 100644 --- a/packages/PrintSpooler/res/values-de/strings.xml +++ b/packages/PrintSpooler/res/values-de/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Empfohlene Dienste"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Deaktivierte Dienste"</string> <string name="all_services_title" msgid="5578662754874906455">"Alle Dienste"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Installieren, um <xliff:g id="COUNT_1">%1$s</xliff:g> Drucker zu erkennen</item> + <item quantity="one">Installieren, um <xliff:g id="COUNT_0">%1$s</xliff:g> Drucker zu erkennen</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> wird gedruckt..."</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> wird abgebrochen..."</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Druckerfehler <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-el/strings.xml b/packages/PrintSpooler/res/values-el/strings.xml index 4441ea2e9e76..31d3f8333535 100644 --- a/packages/PrintSpooler/res/values-el/strings.xml +++ b/packages/PrintSpooler/res/values-el/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Προτεινόμενες υπηρεσίες"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Υπηρεσίες για άτομα με αναπηρία"</string> <string name="all_services_title" msgid="5578662754874906455">"Όλες οι υπηρεσίες"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Κάντε εγκατάσταση για να ανακαλύψετε <xliff:g id="COUNT_1">%1$s</xliff:g> εκτυπωτές</item> + <item quantity="one">Κάντε εγκατάσταση για να ανακαλύψετε <xliff:g id="COUNT_0">%1$s</xliff:g> εκτυπωτή</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Εκτύπωση <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Ακύρωση <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Σφάλμα εκτυπωτή <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-en-rAU/strings.xml b/packages/PrintSpooler/res/values-en-rAU/strings.xml index f8b6265d8506..5e32ae48be42 100644 --- a/packages/PrintSpooler/res/values-en-rAU/strings.xml +++ b/packages/PrintSpooler/res/values-en-rAU/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Recommended services"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Disabled services"</string> <string name="all_services_title" msgid="5578662754874906455">"All services"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item> + <item quantity="one">Install to discover <xliff:g id="COUNT_0">%1$s</xliff:g> printer</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printer error <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-en-rGB/strings.xml b/packages/PrintSpooler/res/values-en-rGB/strings.xml index f8b6265d8506..5e32ae48be42 100644 --- a/packages/PrintSpooler/res/values-en-rGB/strings.xml +++ b/packages/PrintSpooler/res/values-en-rGB/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Recommended services"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Disabled services"</string> <string name="all_services_title" msgid="5578662754874906455">"All services"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item> + <item quantity="one">Install to discover <xliff:g id="COUNT_0">%1$s</xliff:g> printer</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printer error <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-en-rIN/strings.xml b/packages/PrintSpooler/res/values-en-rIN/strings.xml index f8b6265d8506..5e32ae48be42 100644 --- a/packages/PrintSpooler/res/values-en-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-en-rIN/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Recommended services"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Disabled services"</string> <string name="all_services_title" msgid="5578662754874906455">"All services"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Install to discover <xliff:g id="COUNT_1">%1$s</xliff:g> printers</item> + <item quantity="one">Install to discover <xliff:g id="COUNT_0">%1$s</xliff:g> printer</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printer error <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml index 8d555971cedd..a6a9f0780176 100644 --- a/packages/PrintSpooler/res/values-es-rUS/strings.xml +++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Servicios recomendados"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Servicios inhabilitados"</string> <string name="all_services_title" msgid="5578662754874906455">"Todos los servicios"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Instala para ver <xliff:g id="COUNT_1">%1$s</xliff:g> impresoras</item> + <item quantity="one">Instala para ver <xliff:g id="COUNT_0">%1$s</xliff:g> impresora</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimiendo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Error de impresora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-es/strings.xml b/packages/PrintSpooler/res/values-es/strings.xml index 7d08a0efe31a..4f6731d4b3ea 100644 --- a/packages/PrintSpooler/res/values-es/strings.xml +++ b/packages/PrintSpooler/res/values-es/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Servicios recomendados"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Servicios inhabilitados"</string> <string name="all_services_title" msgid="5578662754874906455">"Todos los servicios"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Instalar para descubrir <xliff:g id="COUNT_1">%1$s</xliff:g> impresoras</item> + <item quantity="one">Instalar para descubrir <xliff:g id="COUNT_0">%1$s</xliff:g> impresora</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimiendo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Error de impresora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-et-rEE/strings.xml b/packages/PrintSpooler/res/values-et-rEE/strings.xml index 09da3e09e782..3d0516c21858 100644 --- a/packages/PrintSpooler/res/values-et-rEE/strings.xml +++ b/packages/PrintSpooler/res/values-et-rEE/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Soovitatud teenused"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Keelatud teenused"</string> <string name="all_services_title" msgid="5578662754874906455">"Kõik teenused"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Installige <xliff:g id="COUNT_1">%1$s</xliff:g> printeri avastamiseks</item> + <item quantity="one">Installige <xliff:g id="COUNT_0">%1$s</xliff:g> printeri avastamiseks</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Prinditöö <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> printimine"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Prinditöö <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> tühistamine"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printeri viga: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-eu-rES/strings.xml b/packages/PrintSpooler/res/values-eu-rES/strings.xml index 6b760b441cd3..c56692fd333e 100644 --- a/packages/PrintSpooler/res/values-eu-rES/strings.xml +++ b/packages/PrintSpooler/res/values-eu-rES/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Gomendatutako zerbitzuak"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Desgaitutako zerbitzuak"</string> <string name="all_services_title" msgid="5578662754874906455">"Zerbitzu guztiak"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Instalatu <xliff:g id="COUNT_1">%1$s</xliff:g> inprimagailu aurkitzeko</item> + <item quantity="one">Instalatu <xliff:g id="COUNT_0">%1$s</xliff:g> inprimagailu aurkitzeko</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> inprimatzen"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> bertan behera uzten"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Errorea <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> inprimatzean"</string> diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml index fa105d5bcbcb..8a6c0ddba370 100644 --- a/packages/PrintSpooler/res/values-fa/strings.xml +++ b/packages/PrintSpooler/res/values-fa/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"خدمات توصیهشده"</string> <string name="disabled_services_title" msgid="7313253167968363211">"خدمات غیرفعال"</string> <string name="all_services_title" msgid="5578662754874906455">"همه خدمات"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">نصب کنید تا <xliff:g id="COUNT_1">%1$s</xliff:g> چاپگر را پیدا کنید</item> + <item quantity="other">نصب کنید تا <xliff:g id="COUNT_1">%1$s</xliff:g> چاپگر را پیدا کنید</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"در حال چاپ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"در حال لغو <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"خطای چاپگر <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-fi/strings.xml b/packages/PrintSpooler/res/values-fi/strings.xml index cf051f85891f..3d6897d6bcce 100644 --- a/packages/PrintSpooler/res/values-fi/strings.xml +++ b/packages/PrintSpooler/res/values-fi/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Suositellut palvelut"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Käytöstä poistetut palvelut"</string> <string name="all_services_title" msgid="5578662754874906455">"Kaikki palvelut"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Asentamalla voit löytää <xliff:g id="COUNT_1">%1$s</xliff:g> tulostinta.</item> + <item quantity="one">Asentamalla voit löytää <xliff:g id="COUNT_0">%1$s</xliff:g> tulostimen.</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Tulostetaan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Peruutetaan työ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Tulostinvirhe työlle <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml index 11d2875d583c..6c9539a3db80 100644 --- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml +++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Services recommandés"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Services désactivés"</string> <string name="all_services_title" msgid="5578662754874906455">"Tous les services"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimante</item> + <item quantity="other">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimantes</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Impression de <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> en cours…"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Annulation de « <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> »…"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Erreur impression : « <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> »"</string> diff --git a/packages/PrintSpooler/res/values-fr/strings.xml b/packages/PrintSpooler/res/values-fr/strings.xml index 6b892816d385..64add68614ee 100644 --- a/packages/PrintSpooler/res/values-fr/strings.xml +++ b/packages/PrintSpooler/res/values-fr/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Services recommandés"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Services désactivés"</string> <string name="all_services_title" msgid="5578662754874906455">"Tous les services"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimante</item> + <item quantity="other">Installer pour détecter <xliff:g id="COUNT_1">%1$s</xliff:g> imprimantes</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Impression de \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" en cours…"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Annulation de \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" en cours…"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Erreur impression pour \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\""</string> diff --git a/packages/PrintSpooler/res/values-gl-rES/strings.xml b/packages/PrintSpooler/res/values-gl-rES/strings.xml index 7ddc9f82c4dd..099159d66682 100644 --- a/packages/PrintSpooler/res/values-gl-rES/strings.xml +++ b/packages/PrintSpooler/res/values-gl-rES/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Servizos recomendados"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Servizos desactivados"</string> <string name="all_services_title" msgid="5578662754874906455">"Todos os servizos"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Instala o servizo para atopar <xliff:g id="COUNT_1">%1$s</xliff:g> impresoras</item> + <item quantity="one">Instala o servizo para atopar <xliff:g id="COUNT_0">%1$s</xliff:g> impresora</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Erro da impresora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-gu-rIN/strings.xml b/packages/PrintSpooler/res/values-gu-rIN/strings.xml index 6a7e0df1ac81..b42fdabe4035 100644 --- a/packages/PrintSpooler/res/values-gu-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-gu-rIN/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"ભલામણ કરેલી સેવાઓ"</string> <string name="disabled_services_title" msgid="7313253167968363211">"અક્ષમ કરેલી સેવાઓ"</string> <string name="all_services_title" msgid="5578662754874906455">"બધી સેવાઓ"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> પ્રિન્ટરની શોધ કરવા માટે ઇન્સ્ટૉલ કરો</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> પ્રિન્ટરની શોધ કરવા માટે ઇન્સ્ટૉલ કરો</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> છાપી રહ્યાં છે"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ને રદ કરી રહ્યું છે"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"પ્રિન્ટર ભૂલ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-hi/strings.xml b/packages/PrintSpooler/res/values-hi/strings.xml index 377dc62f5e6d..507754a0a4db 100644 --- a/packages/PrintSpooler/res/values-hi/strings.xml +++ b/packages/PrintSpooler/res/values-hi/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"सुझाई गई सेवाएं"</string> <string name="disabled_services_title" msgid="7313253167968363211">"अक्षम सेवाएं"</string> <string name="all_services_title" msgid="5578662754874906455">"सभी सेवाएं"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> प्रिंटर खोजने के लिए इंस्टॉल करें</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> प्रिंटर खोजने के लिए इंस्टॉल करें</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> प्रिंट हो रहा है"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> रद्द हो रहा है"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिंटर त्रुटि <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-hr/strings.xml b/packages/PrintSpooler/res/values-hr/strings.xml index 8550be40b90f..92c97ea3223f 100644 --- a/packages/PrintSpooler/res/values-hr/strings.xml +++ b/packages/PrintSpooler/res/values-hr/strings.xml @@ -73,6 +73,11 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Preporučene usluge"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Onemogućene usluge"</string> <string name="all_services_title" msgid="5578662754874906455">"Sve usluge"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Instalirajte da biste pronašli <xliff:g id="COUNT_1">%1$s</xliff:g> pisač</item> + <item quantity="few">Instalirajte da biste pronašli <xliff:g id="COUNT_1">%1$s</xliff:g> pisača</item> + <item quantity="other">Instalirajte da biste pronašli <xliff:g id="COUNT_1">%1$s</xliff:g> pisača</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Ispisivanje <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Otkazivanje zadatka <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Pogreška pisača <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-hu/strings.xml b/packages/PrintSpooler/res/values-hu/strings.xml index 20789a36ab05..a2e53db859e2 100644 --- a/packages/PrintSpooler/res/values-hu/strings.xml +++ b/packages/PrintSpooler/res/values-hu/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Javasolt szolgáltatások"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Letiltott szolgáltatások"</string> <string name="all_services_title" msgid="5578662754874906455">"Minden szolgáltatás"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Telepítés <xliff:g id="COUNT_1">%1$s</xliff:g> nyomtató felfedezéséhez</item> + <item quantity="one">Telepítés <xliff:g id="COUNT_0">%1$s</xliff:g> nyomtató felfedezéséhez</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"A(z) <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> nyomtatása"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"A(z) <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> törlése"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Nyomtatási hiba: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-hy-rAM/strings.xml b/packages/PrintSpooler/res/values-hy-rAM/strings.xml index 895033860b2f..e26c2444280d 100644 --- a/packages/PrintSpooler/res/values-hy-rAM/strings.xml +++ b/packages/PrintSpooler/res/values-hy-rAM/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Խորհուրդ տրվող ծառայությունները"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Կասեցված ծառայությունները"</string> <string name="all_services_title" msgid="5578662754874906455">"Բոլոր ծառայությունները"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Տեղադրեք՝ <xliff:g id="COUNT_1">%1$s</xliff:g> տպիչ հայտնաբերելու համար</item> + <item quantity="other">Տեղադրեք՝ <xliff:g id="COUNT_1">%1$s</xliff:g> տպիչ հայտնաբերելու համար</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Տպվում է՝ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>-ը չեղարկվում է"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Տպիչի սխալ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-in/strings.xml b/packages/PrintSpooler/res/values-in/strings.xml index 9b722500e8b5..4ec06441db7a 100644 --- a/packages/PrintSpooler/res/values-in/strings.xml +++ b/packages/PrintSpooler/res/values-in/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Layanan yang disarankan"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Layanan dinonaktifkan"</string> <string name="all_services_title" msgid="5578662754874906455">"Semua layanan"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Pasang untuk menemukan <xliff:g id="COUNT_1">%1$s</xliff:g> printer</item> + <item quantity="one">Pasang untuk menemukan <xliff:g id="COUNT_0">%1$s</xliff:g> printer</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Mencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Membatalkan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Ada kesalahan printer <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-is-rIS/strings.xml b/packages/PrintSpooler/res/values-is-rIS/strings.xml index 37abb5a0c8a3..e05f07f4bec1 100644 --- a/packages/PrintSpooler/res/values-is-rIS/strings.xml +++ b/packages/PrintSpooler/res/values-is-rIS/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Þjónusta sem mælt er með"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Þjónusta við fatlaða"</string> <string name="all_services_title" msgid="5578662754874906455">"Öll þjónusta"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Settu upp til að finna <xliff:g id="COUNT_1">%1$s</xliff:g> prentara</item> + <item quantity="other">Settu upp til að finna <xliff:g id="COUNT_1">%1$s</xliff:g> prentara</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Prentar <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Hættir við <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Prentaravilla <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-it/strings.xml b/packages/PrintSpooler/res/values-it/strings.xml index dd4a8cb47a70..39a0a6182206 100644 --- a/packages/PrintSpooler/res/values-it/strings.xml +++ b/packages/PrintSpooler/res/values-it/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Servizi consigliati"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Servizi disattivati"</string> <string name="all_services_title" msgid="5578662754874906455">"Tutti i servizi"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Installa per rilevare <xliff:g id="COUNT_1">%1$s</xliff:g> stampanti</item> + <item quantity="one">Installa per rilevare <xliff:g id="COUNT_0">%1$s</xliff:g> stampante</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Stampa di <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Annullamento di <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Errore della stampante: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-iw/strings.xml b/packages/PrintSpooler/res/values-iw/strings.xml index 1d813bbc2bac..9aa4104c90f7 100644 --- a/packages/PrintSpooler/res/values-iw/strings.xml +++ b/packages/PrintSpooler/res/values-iw/strings.xml @@ -74,6 +74,12 @@ <string name="recommended_services_title" msgid="3799434882937956924">"שירותים מומלצים"</string> <string name="disabled_services_title" msgid="7313253167968363211">"שירותים מושבתים"</string> <string name="all_services_title" msgid="5578662754874906455">"כל השירותים"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="two">התקן כדי לגלות <xliff:g id="COUNT_1">%1$s</xliff:g> מדפסות</item> + <item quantity="many">התקן כדי לגלות <xliff:g id="COUNT_1">%1$s</xliff:g> מדפסות</item> + <item quantity="other">התקן כדי לגלות <xliff:g id="COUNT_1">%1$s</xliff:g> מדפסות</item> + <item quantity="one">התקן כדי לגלות מדפסת <xliff:g id="COUNT_0">%1$s</xliff:g></item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"מדפיס את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"מבטל את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"שגיאת מדפסת ב-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ja/strings.xml b/packages/PrintSpooler/res/values-ja/strings.xml index 946052a43e40..f97efc1a1502 100644 --- a/packages/PrintSpooler/res/values-ja/strings.xml +++ b/packages/PrintSpooler/res/values-ja/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"推奨されているサービス"</string> <string name="disabled_services_title" msgid="7313253167968363211">"無効になっているサービス"</string> <string name="all_services_title" msgid="5578662754874906455">"すべてのサービス"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> 台のプリンタを検索するにはインストールします</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> 台のプリンタを検索するにはインストールします</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>を印刷しています"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>をキャンセルしています"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"プリンタエラー: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ka-rGE/strings.xml b/packages/PrintSpooler/res/values-ka-rGE/strings.xml index 94152b1ae345..9cb8b39d4035 100644 --- a/packages/PrintSpooler/res/values-ka-rGE/strings.xml +++ b/packages/PrintSpooler/res/values-ka-rGE/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"რეკომენდებული სერვისები"</string> <string name="disabled_services_title" msgid="7313253167968363211">"გათიშული სერვისები"</string> <string name="all_services_title" msgid="5578662754874906455">"ყველა სერვისი"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">დააინსტალირეთ <xliff:g id="COUNT_1">%1$s</xliff:g> პრინტერის აღმოსაჩენად</item> + <item quantity="one">დააინსტალირეთ <xliff:g id="COUNT_0">%1$s</xliff:g> პრინტერის აღმოსაჩენად</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"იბეჭდება <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"მიმდინარეობს <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>-ის გაუქმება"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"ბეჭდვის შეცდომა <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml index c647dab05d1f..37b2cd3a8862 100644 --- a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml +++ b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Ұсынылған қызметтер"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Өшірілген қызметтер"</string> <string name="all_services_title" msgid="5578662754874906455">"Барлық қызметтер"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> принтерді табу үшін орнатыңыз</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> принтерді табу үшін орнатыңыз</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> басып шығарылуда"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> жұмысын тоқтатуда"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> принтер қателігі"</string> diff --git a/packages/PrintSpooler/res/values-km-rKH/strings.xml b/packages/PrintSpooler/res/values-km-rKH/strings.xml index 330edf579094..12d296d3f006 100644 --- a/packages/PrintSpooler/res/values-km-rKH/strings.xml +++ b/packages/PrintSpooler/res/values-km-rKH/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"សេវាកម្មដែលបានណែនាំ"</string> <string name="disabled_services_title" msgid="7313253167968363211">"សេវាកម្មដែលបិទដំណើរការ"</string> <string name="all_services_title" msgid="5578662754874906455">"សេវាកម្មទាំងអស់"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">ដំឡើងដើម្បីរកមើលម៉ាស៊ីនបោះពុម្ព <xliff:g id="COUNT_1">%1$s</xliff:g></item> + <item quantity="one">ដំឡើងដើម្បីរកមើលម៉ាស៊ីនបោះពុម្ព <xliff:g id="COUNT_0">%1$s</xliff:g></item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"កំពុងបោះពុម្ព <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"ការបោះបង់ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"កំហុសម៉ាស៊ីនបោះពុម្ព <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-kn-rIN/strings.xml b/packages/PrintSpooler/res/values-kn-rIN/strings.xml index f1cef8684cc2..8b1acddcb563 100644 --- a/packages/PrintSpooler/res/values-kn-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-kn-rIN/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"ಶಿಫಾರಸು ಮಾಡಲಾದ ಸೇವೆಗಳು"</string> <string name="disabled_services_title" msgid="7313253167968363211">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾದ ಸೇವೆಗಳು"</string> <string name="all_services_title" msgid="5578662754874906455">"ಎಲ್ಲ ಸೇವೆಗಳು"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> ಪ್ರಿಂಟರ್ಗಳನ್ನು ಶೋಧಿಸಲು ಸ್ಥಾಪಿಸಿ</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> ಪ್ರಿಂಟರ್ಗಳನ್ನು ಶೋಧಿಸಲು ಸ್ಥಾಪಿಸಿ</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ಮುದ್ರಿಸಲಾಗುತ್ತಿದೆ"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ರದ್ದು ಮಾಡಲಾಗುತ್ತಿದೆ"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"ಮುದ್ರಕ ದೋಷ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ko/strings.xml b/packages/PrintSpooler/res/values-ko/strings.xml index d3cc9671b157..e6ca240e7042 100644 --- a/packages/PrintSpooler/res/values-ko/strings.xml +++ b/packages/PrintSpooler/res/values-ko/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"권장 서비스"</string> <string name="disabled_services_title" msgid="7313253167968363211">"사용 중지된 서비스"</string> <string name="all_services_title" msgid="5578662754874906455">"모든 서비스"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g>개 프린터를 표시하려면 설치하세요.</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g>개 프린터를 표시하려면 설치하세요.</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> 인쇄 중"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> 취소 중"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"프린터 오류: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ky-rKG/strings.xml b/packages/PrintSpooler/res/values-ky-rKG/strings.xml index d84e5d857ad0..ae0b05e2a2f0 100644 --- a/packages/PrintSpooler/res/values-ky-rKG/strings.xml +++ b/packages/PrintSpooler/res/values-ky-rKG/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Сунушталган кызматтар"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Өчүрүлгөн кызматтар"</string> <string name="all_services_title" msgid="5578662754874906455">"Бардык кызматтар"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Орнотсоңуз <xliff:g id="COUNT_1">%1$s</xliff:g> принтер таап аласыз</item> + <item quantity="one">Орнотсоңуз <xliff:g id="COUNT_0">%1$s</xliff:g> принтер таап аласыз</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> басылууда"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> токтотулууда"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Принтерде ката кетти: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-lo-rLA/strings.xml b/packages/PrintSpooler/res/values-lo-rLA/strings.xml index 6a690538aa8a..2392e4a188ea 100644 --- a/packages/PrintSpooler/res/values-lo-rLA/strings.xml +++ b/packages/PrintSpooler/res/values-lo-rLA/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"ບໍລິການທີ່ແນະນຳ"</string> <string name="disabled_services_title" msgid="7313253167968363211">"ບໍລິການທີ່ຖືກປິດການນຳໃຊ້"</string> <string name="all_services_title" msgid="5578662754874906455">"ບໍລິການທັງໝົດ"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">ຕິດຕັ້ງເພື່ອຄົ້ນພົບເຄື່ອງພິມ <xliff:g id="COUNT_1">%1$s</xliff:g> ເຄື່ອງ</item> + <item quantity="one">ຕິດຕັ້ງເພື່ອຄົ້ນພົບເຄື່ອງພິມ <xliff:g id="COUNT_0">%1$s</xliff:g> ເຄື່ອງ</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"ກຳລັງພິມ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"ກຳລັງຍົກເລີກ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"ເຄື່ອງພິມເກີດຂໍ້ຜິດພາດ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-lt/strings.xml b/packages/PrintSpooler/res/values-lt/strings.xml index ddcaba7275d7..65ccc2be040b 100644 --- a/packages/PrintSpooler/res/values-lt/strings.xml +++ b/packages/PrintSpooler/res/values-lt/strings.xml @@ -74,6 +74,12 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Rekomenduojamos paslaugos"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Išjungtos paslaugos"</string> <string name="all_services_title" msgid="5578662754874906455">"Visos paslaugos"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Įdiekite, kad būtų rastas <xliff:g id="COUNT_1">%1$s</xliff:g> spausdintuvas</item> + <item quantity="few">Įdiekite, kad būtų rasti <xliff:g id="COUNT_1">%1$s</xliff:g> spausdintuvai</item> + <item quantity="many">Įdiekite, kad būtų rasta <xliff:g id="COUNT_1">%1$s</xliff:g> spausdintuvo</item> + <item quantity="other">Įdiekite, kad būtų rasta <xliff:g id="COUNT_1">%1$s</xliff:g> spausdintuvų</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Spausdinama: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Atšaukiama: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Spausdintuvo klaida: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-lv/strings.xml b/packages/PrintSpooler/res/values-lv/strings.xml index 50ba32d81b44..1bcfe783d239 100644 --- a/packages/PrintSpooler/res/values-lv/strings.xml +++ b/packages/PrintSpooler/res/values-lv/strings.xml @@ -73,6 +73,11 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Ieteiktie pakalpojumi"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Atspējotie pakalpojumi"</string> <string name="all_services_title" msgid="5578662754874906455">"Visi pakalpojumi"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="zero">Instalējiet, lai atklātu <xliff:g id="COUNT_1">%1$s</xliff:g> printerus</item> + <item quantity="one">Instalējiet, lai atklātu <xliff:g id="COUNT_1">%1$s</xliff:g> printeri</item> + <item quantity="other">Instalējiet, lai atklātu <xliff:g id="COUNT_1">%1$s</xliff:g> printerus</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Notiek darba <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> drukāšana…"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Pārtrauc drukas darbu <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>…"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printera kļūda ar darbu <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-mk-rMK/strings.xml b/packages/PrintSpooler/res/values-mk-rMK/strings.xml index a18904224852..d29566bc1edf 100644 --- a/packages/PrintSpooler/res/values-mk-rMK/strings.xml +++ b/packages/PrintSpooler/res/values-mk-rMK/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Препорачани услуги"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Оневозможени услуги"</string> <string name="all_services_title" msgid="5578662754874906455">"Сите услуги"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Инсталирајте за да пронајдете <xliff:g id="COUNT_1">%1$s</xliff:g> печатач</item> + <item quantity="other">Инсталирајте за да пронајдете <xliff:g id="COUNT_1">%1$s</xliff:g> печатачи</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> се печати"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> се откажува"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Грешка при печатење <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ml-rIN/strings.xml b/packages/PrintSpooler/res/values-ml-rIN/strings.xml index 56256325f721..16d654c63fc0 100644 --- a/packages/PrintSpooler/res/values-ml-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-ml-rIN/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"ശുപാർശ ചെയ്യപ്പെടുന്ന സേവനങ്ങൾ"</string> <string name="disabled_services_title" msgid="7313253167968363211">"പ്രവർത്തനരഹിതമാക്കിയ സേവനങ്ങൾ"</string> <string name="all_services_title" msgid="5578662754874906455">"എല്ലാ സേവനങ്ങളും"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> പ്രിന്ററുകൾ കണ്ടെത്തുന്നതിന് ഇൻസ്റ്റാൾ ചെയ്യുക</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> പ്രിന്റർ കണ്ടെത്തുന്നതിന് ഇൻസ്റ്റാൾ ചെയ്യുക</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> പ്രിന്റുചെയ്യുന്നു"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> റദ്ദാക്കുന്നു"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"പ്രിന്റർ പിശക് <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-mn-rMN/strings.xml b/packages/PrintSpooler/res/values-mn-rMN/strings.xml index 7797944cc170..ded066566499 100644 --- a/packages/PrintSpooler/res/values-mn-rMN/strings.xml +++ b/packages/PrintSpooler/res/values-mn-rMN/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Санал болгосон үйлчилгээ"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Идэвхгүй болгосон үйлчилгээ"</string> <string name="all_services_title" msgid="5578662754874906455">"Бүх үйлчилгээ"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other"> <xliff:g id="COUNT_1">%1$s</xliff:g> хэвлэгч олохын тулд суулгах</item> + <item quantity="one"> <xliff:g id="COUNT_0">%1$s</xliff:g> хэвлэгч олохын тулд суулгах</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Хэвлэж байна <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Цуцлаж байна <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Принтерийн алдаа <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-mr-rIN/strings.xml b/packages/PrintSpooler/res/values-mr-rIN/strings.xml index ee09db231883..5436635ada1c 100644 --- a/packages/PrintSpooler/res/values-mr-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-mr-rIN/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"शिफारस केलेल्या सेवा"</string> <string name="disabled_services_title" msgid="7313253167968363211">"अक्षम केलल्या सेवा"</string> <string name="all_services_title" msgid="5578662754874906455">"सर्व सेवा"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> प्रिंटर शोधण्यासाठी स्थापित करा</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> प्रिंटर शोधण्यासाठी स्थापित करा</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> मुद्रण करीत आहे"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> रद्द करीत आहे"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिंटर त्रुटी <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ms-rMY/strings.xml b/packages/PrintSpooler/res/values-ms-rMY/strings.xml index 4042c7171853..8af5232f8a16 100644 --- a/packages/PrintSpooler/res/values-ms-rMY/strings.xml +++ b/packages/PrintSpooler/res/values-ms-rMY/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Perkhidmatan yang disyorkan"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Perkhidmatan yang dilumpuhkan"</string> <string name="all_services_title" msgid="5578662754874906455">"Semua perkhidmatan"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Pasang untuk menemui <xliff:g id="COUNT_1">%1$s</xliff:g> pencetak</item> + <item quantity="one">Pasang untuk menemui <xliff:g id="COUNT_0">%1$s</xliff:g> pencetak</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Mencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Membatalkan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Ralat pencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-my-rMM/strings.xml b/packages/PrintSpooler/res/values-my-rMM/strings.xml index f34ca6782a08..9b5f46aca49f 100644 --- a/packages/PrintSpooler/res/values-my-rMM/strings.xml +++ b/packages/PrintSpooler/res/values-my-rMM/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"အကြံပြုထားသည့် ဝန်ဆောင်မှုများ"</string> <string name="disabled_services_title" msgid="7313253167968363211">"ပိတ်ထားသည့် ဝန်ဆောင်မှုများ"</string> <string name="all_services_title" msgid="5578662754874906455">"ဝန်ဆောင်မှုများ အားလုံး"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">ပုံနှိပ်စက် <xliff:g id="COUNT_1">%1$s</xliff:g> ခုကို ရှာဖွေရန် စနစ်ထည့်သွင်းပါ</item> + <item quantity="one">ပုံနှိပ်စက် <xliff:g id="COUNT_0">%1$s</xliff:g> ခုကို ရှာဖွေရန် စနစ်ထည့်သွင်းပါ</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ကို စာထုတ်နေပါသည်"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ကို ပယ်ဖျက်နေပါသည်"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"စာထုတ်စက်မှ အမှား <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-nb/strings.xml b/packages/PrintSpooler/res/values-nb/strings.xml index 6b74765451dd..82282bad9268 100644 --- a/packages/PrintSpooler/res/values-nb/strings.xml +++ b/packages/PrintSpooler/res/values-nb/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Anbefalte tjenester"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Tjenester som er slått av"</string> <string name="all_services_title" msgid="5578662754874906455">"Alle tjenester"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Installer for å finne <xliff:g id="COUNT_1">%1$s</xliff:g> printere</item> + <item quantity="one">Installer for å finne <xliff:g id="COUNT_0">%1$s</xliff:g> printer</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Skriver ut <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Avbryter <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Skriverfeil <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ne-rNP/strings.xml b/packages/PrintSpooler/res/values-ne-rNP/strings.xml index 8e8bf15f7be9..4cf2f51b288a 100644 --- a/packages/PrintSpooler/res/values-ne-rNP/strings.xml +++ b/packages/PrintSpooler/res/values-ne-rNP/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"सिफारिस गरिएका सेवाहरू"</string> <string name="disabled_services_title" msgid="7313253167968363211">"असक्षम गरिएका सेवाहरू"</string> <string name="all_services_title" msgid="5578662754874906455">"सबै सेवाहरू"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> प्रिन्टरहरू पत्ता लगाउनका लागि स्थापना गर्नुहोस्</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> प्रिन्टर पत्ता लगाउनका लागि स्थापना गर्नुहोस्</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"प्रिन्ट गरिँदै <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"रद्द गरिँदै <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिन्टर त्रुटि <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-nl/strings.xml b/packages/PrintSpooler/res/values-nl/strings.xml index 3c65d8af5d00..83b9a2233166 100644 --- a/packages/PrintSpooler/res/values-nl/strings.xml +++ b/packages/PrintSpooler/res/values-nl/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Aanbevolen services"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Uitgeschakelde services"</string> <string name="all_services_title" msgid="5578662754874906455">"Alle services"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Installeren om <xliff:g id="COUNT_1">%1$s</xliff:g> printers te vinden</item> + <item quantity="one">Installeren om <xliff:g id="COUNT_0">%1$s</xliff:g> printer te vinden</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> afdrukken"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> annuleren"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printerfout <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-pa-rIN/strings.xml b/packages/PrintSpooler/res/values-pa-rIN/strings.xml index 934123bcbef4..5f3366fb4eda 100644 --- a/packages/PrintSpooler/res/values-pa-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-pa-rIN/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"ਸਿਫ਼ਾਰਸ਼ ਕੀਤੀਆਂ ਸੇਵਾਵਾਂ"</string> <string name="disabled_services_title" msgid="7313253167968363211">"ਅਯੋਗ ਬਣਾਈਆਂ ਗਈਆਂ ਸੇਵਾਵਾਂ"</string> <string name="all_services_title" msgid="5578662754874906455">"ਸਾਰੀਆਂ ਸੇਵਾਵਾਂ"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> ਪ੍ਰਿੰਟਰ ਖੋਜਣ ਲਈ ਸਥਾਪਤ ਕਰੋ</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> ਪ੍ਰਿੰਟਰ ਖੋਜਣ ਲਈ ਸਥਾਪਤ ਕਰੋ</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ਨੂੰ ਪ੍ਰਿੰਟ ਕਰ ਰਿਹਾ ਹੈ"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ਨੂੰ ਰੱਦ ਕਰ ਰਿਹਾ ਹੈ"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"ਪ੍ਰਿੰਟਰ ਅਸ਼ੁੱਧੀ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-pl/strings.xml b/packages/PrintSpooler/res/values-pl/strings.xml index 80b607076a02..e7fb7b61470e 100644 --- a/packages/PrintSpooler/res/values-pl/strings.xml +++ b/packages/PrintSpooler/res/values-pl/strings.xml @@ -74,6 +74,12 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Polecane usługi"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Wyłączone usługi"</string> <string name="all_services_title" msgid="5578662754874906455">"Wszystkie usługi"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="few">Zainstaluj, by wykryć <xliff:g id="COUNT_1">%1$s</xliff:g> drukarki</item> + <item quantity="many">Zainstaluj, by wykryć <xliff:g id="COUNT_1">%1$s</xliff:g> drukarek</item> + <item quantity="other">Zainstaluj, by wykryć <xliff:g id="COUNT_1">%1$s</xliff:g> drukarki</item> + <item quantity="one">Zainstaluj, by wykryć <xliff:g id="COUNT_0">%1$s</xliff:g> drukarkę</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Drukowanie: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Anulowanie: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Błąd drukarki: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-pt-rBR/strings.xml b/packages/PrintSpooler/res/values-pt-rBR/strings.xml index 4bd1161dc153..dd8cdb25ab73 100644 --- a/packages/PrintSpooler/res/values-pt-rBR/strings.xml +++ b/packages/PrintSpooler/res/values-pt-rBR/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Serviços recomendados"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Serviços desativados"</string> <string name="all_services_title" msgid="5578662754874906455">"Todos os serviços"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Instale para encontrar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item> + <item quantity="other">Instale para encontrar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Erro ao imprimir <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-pt-rPT/strings.xml b/packages/PrintSpooler/res/values-pt-rPT/strings.xml index 7660c5c42caa..c1fe7bfb38a8 100644 --- a/packages/PrintSpooler/res/values-pt-rPT/strings.xml +++ b/packages/PrintSpooler/res/values-pt-rPT/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Serviços recomendados"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Serviços desativados"</string> <string name="all_services_title" msgid="5578662754874906455">"Todos os serviços"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Instale para detetar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item> + <item quantity="one">Instale para detetar <xliff:g id="COUNT_0">%1$s</xliff:g> impressora</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"A imprimir <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"A cancelar <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Erro da impressora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-pt/strings.xml b/packages/PrintSpooler/res/values-pt/strings.xml index 4bd1161dc153..dd8cdb25ab73 100644 --- a/packages/PrintSpooler/res/values-pt/strings.xml +++ b/packages/PrintSpooler/res/values-pt/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Serviços recomendados"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Serviços desativados"</string> <string name="all_services_title" msgid="5578662754874906455">"Todos os serviços"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Instale para encontrar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item> + <item quantity="other">Instale para encontrar <xliff:g id="COUNT_1">%1$s</xliff:g> impressoras</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Erro ao imprimir <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ro/strings.xml b/packages/PrintSpooler/res/values-ro/strings.xml index dd38c31dc397..b326e09fbd95 100644 --- a/packages/PrintSpooler/res/values-ro/strings.xml +++ b/packages/PrintSpooler/res/values-ro/strings.xml @@ -73,6 +73,11 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Servicii recomandate"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Servicii dezactivate"</string> <string name="all_services_title" msgid="5578662754874906455">"Toate serviciile"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="few">Instalați pentru a descoperi <xliff:g id="COUNT_1">%1$s</xliff:g> imprimante</item> + <item quantity="other">Instalați pentru a descoperi <xliff:g id="COUNT_1">%1$s</xliff:g> de imprimante</item> + <item quantity="one">Instalați pentru a descoperi <xliff:g id="COUNT_0">%1$s</xliff:g> imprimantă</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Se printează <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Se anulează <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Eroare de printare: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ru/strings.xml b/packages/PrintSpooler/res/values-ru/strings.xml index 6c074ed9edce..5acadbc27662 100644 --- a/packages/PrintSpooler/res/values-ru/strings.xml +++ b/packages/PrintSpooler/res/values-ru/strings.xml @@ -74,6 +74,12 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Рекомендуемые службы"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Отключенные службы"</string> <string name="all_services_title" msgid="5578662754874906455">"Все службы печати"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Установите, чтобы найти <xliff:g id="COUNT_1">%1$s</xliff:g> принтер</item> + <item quantity="few">Установите, чтобы найти <xliff:g id="COUNT_1">%1$s</xliff:g> принтера</item> + <item quantity="many">Установите, чтобы найти <xliff:g id="COUNT_1">%1$s</xliff:g> принтеров</item> + <item quantity="other">Установите, чтобы найти <xliff:g id="COUNT_1">%1$s</xliff:g> принтера</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Печать задания \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\"…"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Отмена задания <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>…"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Ошибка задания \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\""</string> diff --git a/packages/PrintSpooler/res/values-si-rLK/strings.xml b/packages/PrintSpooler/res/values-si-rLK/strings.xml index 8278aeee4f25..db4c5fdb070e 100644 --- a/packages/PrintSpooler/res/values-si-rLK/strings.xml +++ b/packages/PrintSpooler/res/values-si-rLK/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"නිර්දේශිත සේවා"</string> <string name="disabled_services_title" msgid="7313253167968363211">"අබල කළ සේවා"</string> <string name="all_services_title" msgid="5578662754874906455">"සියලු සේවා"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">මුද්රණ යන්ත්ර <xliff:g id="COUNT_1">%1$s</xliff:g>ක් සොයා ගැනීමට ස්ථාපනය කරන්න</item> + <item quantity="other">මුද්රණ යන්ත්ර <xliff:g id="COUNT_1">%1$s</xliff:g>ක් සොයා ගැනීමට ස්ථාපනය කරන්න</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> මුද්රණය වේ"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"අවලංගු කෙරේ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"මුද්රණ දෝෂය <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-sk/strings.xml b/packages/PrintSpooler/res/values-sk/strings.xml index 610fe99722d3..63ee5e2a59ad 100644 --- a/packages/PrintSpooler/res/values-sk/strings.xml +++ b/packages/PrintSpooler/res/values-sk/strings.xml @@ -74,6 +74,12 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Odporúčané služby"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Zakázané služby"</string> <string name="all_services_title" msgid="5578662754874906455">"Všetky služby"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="few">Nainštalujte a objavte <xliff:g id="COUNT_1">%1$s</xliff:g> tlačiarne</item> + <item quantity="many">Nainštalujte a objavte <xliff:g id="COUNT_1">%1$s</xliff:g> tlačiarne</item> + <item quantity="other">Nainštalujte a objavte <xliff:g id="COUNT_1">%1$s</xliff:g> tlačiarní</item> + <item quantity="one">Nainštalujte a objavte <xliff:g id="COUNT_0">%1$s</xliff:g> tlačiareň</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Prebieha tlač úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Prebieha zrušenie úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Chyba tlačiarne – úloha <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-sl/strings.xml b/packages/PrintSpooler/res/values-sl/strings.xml index b5124b4d43bc..f7616db5db94 100644 --- a/packages/PrintSpooler/res/values-sl/strings.xml +++ b/packages/PrintSpooler/res/values-sl/strings.xml @@ -74,6 +74,12 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Priporočene storitve"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Onemogočene storitve"</string> <string name="all_services_title" msgid="5578662754874906455">"Vse storitve"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Namestite za odkrivanje <xliff:g id="COUNT_1">%1$s</xliff:g> tiskalnika</item> + <item quantity="two">Namestite za odkrivanje <xliff:g id="COUNT_1">%1$s</xliff:g> tiskalnikov</item> + <item quantity="few">Namestite za odkrivanje <xliff:g id="COUNT_1">%1$s</xliff:g> tiskalnikov</item> + <item quantity="other">Namestite za odkrivanje <xliff:g id="COUNT_1">%1$s</xliff:g> tiskalnikov</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Tiskanje: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Preklic: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Napaka tiskalnika: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-sq-rAL/strings.xml b/packages/PrintSpooler/res/values-sq-rAL/strings.xml index 27bbbf902653..f4d2817f0d22 100644 --- a/packages/PrintSpooler/res/values-sq-rAL/strings.xml +++ b/packages/PrintSpooler/res/values-sq-rAL/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Shërbimet e rekomanduara"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Shërbimet e çaktivizuara"</string> <string name="all_services_title" msgid="5578662754874906455">"Të gjitha shërbimet"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Instaloje për të zbuluar <xliff:g id="COUNT_1">%1$s</xliff:g> printera</item> + <item quantity="one">Instaloje për të zbuluar <xliff:g id="COUNT_0">%1$s</xliff:g> printer</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Po printon <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Po anulon <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printeri ndeshi në gabim gjatë punës: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml index ea6fcb7a0e9d..b285044fbbfd 100644 --- a/packages/PrintSpooler/res/values-sr/strings.xml +++ b/packages/PrintSpooler/res/values-sr/strings.xml @@ -73,6 +73,11 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Препоручене услуге"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Онемогућене услуге"</string> <string name="all_services_title" msgid="5578662754874906455">"Све услуге"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Инсталирајте да бисте открили <xliff:g id="COUNT_1">%1$s</xliff:g> штампач</item> + <item quantity="few">Инсталирајте да бисте открили <xliff:g id="COUNT_1">%1$s</xliff:g> штампача</item> + <item quantity="other">Инсталирајте да бисте открили <xliff:g id="COUNT_1">%1$s</xliff:g> штампача</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Штампа се <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Отказује се <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Грешка штампача <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-sv/strings.xml b/packages/PrintSpooler/res/values-sv/strings.xml index c909e19c70ff..4a728006fe05 100644 --- a/packages/PrintSpooler/res/values-sv/strings.xml +++ b/packages/PrintSpooler/res/values-sv/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Rekommenderade tjänster"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Inaktiverade tjänster"</string> <string name="all_services_title" msgid="5578662754874906455">"Alla tjänster"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Installera och hitta <xliff:g id="COUNT_1">%1$s</xliff:g> skrivare</item> + <item quantity="one">Installera och hitta <xliff:g id="COUNT_0">%1$s</xliff:g> skrivare</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Skriver ut <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Avbryter <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Skrivarfel för <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-sw/strings.xml b/packages/PrintSpooler/res/values-sw/strings.xml index bd14117def99..34b935d5fd95 100644 --- a/packages/PrintSpooler/res/values-sw/strings.xml +++ b/packages/PrintSpooler/res/values-sw/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Huduma zinazopendekezwa"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Huduma ambazo haziruhusiwi"</string> <string name="all_services_title" msgid="5578662754874906455">"Huduma zote"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Sakinisha ili ugundue printa <xliff:g id="COUNT_1">%1$s</xliff:g></item> + <item quantity="one">Sakinisha ili ugundue printa <xliff:g id="COUNT_0">%1$s</xliff:g></item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Inachapisha <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Inaghairi <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Hitilafu ya kuchapisha <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ta-rIN/strings.xml b/packages/PrintSpooler/res/values-ta-rIN/strings.xml index 782ebf21bf86..22f41bfe7f37 100644 --- a/packages/PrintSpooler/res/values-ta-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-ta-rIN/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"பரிந்துரைக்கப்படும் அச்சுப் பொறிகள்"</string> <string name="disabled_services_title" msgid="7313253167968363211">"முடக்கப்பட்ட அச்சுப் பொறிகள்"</string> <string name="all_services_title" msgid="5578662754874906455">"எல்லா அச்சுப் பொறிகளும்"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> பிரிண்டர்களைக் கண்டறிய, நிறுவவும்</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> பிரிண்டரைக் கண்டறிய, நிறுவவும்</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ஐ அச்சிடுகிறது"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ஐ ரத்துசெய்கிறது"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"பிரிண்டர் பிழை <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-te-rIN/strings.xml b/packages/PrintSpooler/res/values-te-rIN/strings.xml index ca393c839ff2..1211cfdff4c7 100644 --- a/packages/PrintSpooler/res/values-te-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-te-rIN/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"సిఫార్సు చేయబడిన సేవలు"</string> <string name="disabled_services_title" msgid="7313253167968363211">"నిలిపివేసిన సేవలు"</string> <string name="all_services_title" msgid="5578662754874906455">"అన్ని సేవలు"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> ప్రింటర్లను కనుగొనడానికి ఇన్స్టాల్ చేయండి</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> ప్రింటర్ను కనుగొనడానికి ఇన్స్టాల్ చేయండి</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ను ముద్రిస్తోంది"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ను రద్దు చేస్తోంది"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"ప్రింటర్ లోపం <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-th/strings.xml b/packages/PrintSpooler/res/values-th/strings.xml index 92b960e67344..7f9928829dcc 100644 --- a/packages/PrintSpooler/res/values-th/strings.xml +++ b/packages/PrintSpooler/res/values-th/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"บริการที่แนะนำ"</string> <string name="disabled_services_title" msgid="7313253167968363211">"บริการที่ปิดใช้"</string> <string name="all_services_title" msgid="5578662754874906455">"บริการทั้งหมด"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">ติดตั้งเพื่อค้นหาเครื่องพิมพ์ <xliff:g id="COUNT_1">%1$s</xliff:g> เครื่อง</item> + <item quantity="one">ติดตั้งเพื่อค้นหาเครื่องพิมพ์ <xliff:g id="COUNT_0">%1$s</xliff:g> เครื่อง</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"กำลังพิมพ์ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"กำลังยกเลิก <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"ข้อผิดพลาดเครื่องพิมพ์ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-tl/strings.xml b/packages/PrintSpooler/res/values-tl/strings.xml index 5a7365990ead..7b5081509451 100644 --- a/packages/PrintSpooler/res/values-tl/strings.xml +++ b/packages/PrintSpooler/res/values-tl/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Mga inirerekomendang serbisyo"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Mga naka-disable na serbisyo"</string> <string name="all_services_title" msgid="5578662754874906455">"Lahat ng serbisyo"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">I-install upang tumuklas ng <xliff:g id="COUNT_1">%1$s</xliff:g> printer</item> + <item quantity="other">I-install upang tumuklas ng <xliff:g id="COUNT_1">%1$s</xliff:g> na printer</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Pini-print ang <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Kinakansela ang <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Error sa printer <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-tr/strings.xml b/packages/PrintSpooler/res/values-tr/strings.xml index f17bc9d2ed73..1ca722b0b758 100644 --- a/packages/PrintSpooler/res/values-tr/strings.xml +++ b/packages/PrintSpooler/res/values-tr/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Önerilen hizmetler"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Devre dışı bırakılmış hizmetler"</string> <string name="all_services_title" msgid="5578662754874906455">"Tüm hizmetler"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> yazıcıyı keşfetmek için yükleyin</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> yazıcıyı keşfetmek için yükleyin</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> yazdırılıyor"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> iptal ediliyor"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Yazıcı hatası: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-uk/strings.xml b/packages/PrintSpooler/res/values-uk/strings.xml index 9629ad396cff..800463966678 100644 --- a/packages/PrintSpooler/res/values-uk/strings.xml +++ b/packages/PrintSpooler/res/values-uk/strings.xml @@ -74,6 +74,12 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Рекомендовані служби"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Вимкнені служби"</string> <string name="all_services_title" msgid="5578662754874906455">"Усі служби"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Установіть, щоб знайти <xliff:g id="COUNT_1">%1$s</xliff:g> принтер</item> + <item quantity="few">Установіть, щоб знайти <xliff:g id="COUNT_1">%1$s</xliff:g> принтери</item> + <item quantity="many">Установіть, щоб знайти <xliff:g id="COUNT_1">%1$s</xliff:g> принтерів</item> + <item quantity="other">Установіть, щоб знайти <xliff:g id="COUNT_1">%1$s</xliff:g> принтера</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" друкується"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" скасовується"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Помилка завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\""</string> diff --git a/packages/PrintSpooler/res/values-ur-rPK/strings.xml b/packages/PrintSpooler/res/values-ur-rPK/strings.xml index 0d01ee20e97c..19e759cbc377 100644 --- a/packages/PrintSpooler/res/values-ur-rPK/strings.xml +++ b/packages/PrintSpooler/res/values-ur-rPK/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"تجویز کردہ سروسز"</string> <string name="disabled_services_title" msgid="7313253167968363211">"غیر فعال کردہ سروسز"</string> <string name="all_services_title" msgid="5578662754874906455">"تمام سروسز"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> پرنٹرز دریافت کرنے کیلئے انسٹال کریں</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> پرنٹر دریافت کرنے کیلئے انسٹال کریں</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> پرنٹ کررہا ہے"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> کو منسوخ کر رہا ہے"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"پرنٹر کی خرابی <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml index 1f379d94b6f1..cf87a740d133 100644 --- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml +++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Tavsiya etilgan xizmatlar"</string> <string name="disabled_services_title" msgid="7313253167968363211">"O‘chirib qo‘yilgan xizmatlar"</string> <string name="all_services_title" msgid="5578662754874906455">"Barcha xizmatlar"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> ta printerni topish uchun o‘rnating</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$s</xliff:g> ta printerni topish uchun o‘rnating</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Chop etilmoqda: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> bekor qilinmoqda"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printerda xatolik: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-vi/strings.xml b/packages/PrintSpooler/res/values-vi/strings.xml index b931557178c4..2c1fa2701120 100644 --- a/packages/PrintSpooler/res/values-vi/strings.xml +++ b/packages/PrintSpooler/res/values-vi/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Dịch vụ được đề xuất"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Dịch vụ đã tắt"</string> <string name="all_services_title" msgid="5578662754874906455">"Tất cả dịch vụ"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">Cài đặt để phát hiện <xliff:g id="COUNT_1">%1$s</xliff:g> máy in</item> + <item quantity="one">Cài đặt để phát hiện <xliff:g id="COUNT_0">%1$s</xliff:g> máy in</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"In <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Hủy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Lỗi máy in <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-zh-rCN/strings.xml b/packages/PrintSpooler/res/values-zh-rCN/strings.xml index ffc9f85cbf02..b3500514fa6f 100644 --- a/packages/PrintSpooler/res/values-zh-rCN/strings.xml +++ b/packages/PrintSpooler/res/values-zh-rCN/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"推荐的服务"</string> <string name="disabled_services_title" msgid="7313253167968363211">"已停用的服务"</string> <string name="all_services_title" msgid="5578662754874906455">"所有服务"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">安装即可找到 <xliff:g id="COUNT_1">%1$s</xliff:g> 台打印机</item> + <item quantity="one">安装即可找到 <xliff:g id="COUNT_0">%1$s</xliff:g> 台打印机</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"正在打印“<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>”"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"正在取消打印“<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>”"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"打印机在打印“<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>”时出错"</string> diff --git a/packages/PrintSpooler/res/values-zh-rHK/strings.xml b/packages/PrintSpooler/res/values-zh-rHK/strings.xml index 4411a23b7b76..192b41b06ad5 100644 --- a/packages/PrintSpooler/res/values-zh-rHK/strings.xml +++ b/packages/PrintSpooler/res/values-zh-rHK/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"推薦服務"</string> <string name="disabled_services_title" msgid="7313253167968363211">"已停用的服務"</string> <string name="all_services_title" msgid="5578662754874906455">"所有服務"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">安裝即可使用 <xliff:g id="COUNT_1">%1$s</xliff:g> 部印表機</item> + <item quantity="one">安裝即可使用 <xliff:g id="COUNT_0">%1$s</xliff:g> 部印表機</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"正在列印 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"正在取消 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"打印機錯誤:<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-zh-rTW/strings.xml b/packages/PrintSpooler/res/values-zh-rTW/strings.xml index 98126a77b489..4aa5681a6035 100644 --- a/packages/PrintSpooler/res/values-zh-rTW/strings.xml +++ b/packages/PrintSpooler/res/values-zh-rTW/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"建議的列印服務"</string> <string name="disabled_services_title" msgid="7313253167968363211">"已停用的列印服務"</string> <string name="all_services_title" msgid="5578662754874906455">"所有列印服務"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="other">安裝即可使用 <xliff:g id="COUNT_1">%1$s</xliff:g> 個印表機</item> + <item quantity="one">安裝即可使用 <xliff:g id="COUNT_0">%1$s</xliff:g> 個印表機</item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"正在列印 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"正在取消 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"印表機發生錯誤:<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-zu/strings.xml b/packages/PrintSpooler/res/values-zu/strings.xml index f2b49900f0e3..121022b59b1d 100644 --- a/packages/PrintSpooler/res/values-zu/strings.xml +++ b/packages/PrintSpooler/res/values-zu/strings.xml @@ -72,6 +72,10 @@ <string name="recommended_services_title" msgid="3799434882937956924">"Amasevisi anconyiwe"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Amasevisi akhutshaziwe"</string> <string name="all_services_title" msgid="5578662754874906455">"Onke amasevisi"</string> + <plurals name="print_services_recommendation_subtitle" formatted="false" msgid="5678487708807185138"> + <item quantity="one">Faka ukuze uthole amaphrinta we-<xliff:g id="COUNT_1">%1$s</xliff:g></item> + <item quantity="other">Faka ukuze uthole amaphrinta we-<xliff:g id="COUNT_1">%1$s</xliff:g></item> + </plurals> <string name="printing_notification_title_template" msgid="295903957762447362">"Iphrinta i-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Ikhansela i-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Iphutha lephrinta ye-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java index cde0fa3b4896..e7aebddf5aa8 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java @@ -62,7 +62,6 @@ import android.printservice.PrintServiceInfo; import android.provider.DocumentsContract; import android.text.Editable; import android.text.TextUtils; -import android.text.TextUtils.SimpleStringSplitter; import android.text.TextWatcher; import android.util.ArrayMap; import android.util.ArraySet; @@ -117,8 +116,6 @@ import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.regex.Matcher; -import java.util.regex.Pattern; public class PrintActivity extends Activity implements RemotePrintDocument.UpdateResultCallbacks, PrintErrorFragment.OnActionListener, PageAdapter.ContentCallbacks, @@ -165,22 +162,11 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat private static final int MIN_COPIES = 1; private static final String MIN_COPIES_STRING = String.valueOf(MIN_COPIES); - private static final Pattern PATTERN_DIGITS = Pattern.compile("[\\d]+"); - - private static final Pattern PATTERN_ESCAPE_SPECIAL_CHARS = Pattern.compile( - "(?=[]\\[+&|!(){}^\"~*?:\\\\])"); - - private static final Pattern PATTERN_PAGE_RANGE = Pattern.compile( - "[\\s]*[0-9]+[\\-]?[\\s]*[0-9]*[\\s]*?(([,])" - + "[\\s]*[0-9]+[\\s]*[\\-]?[\\s]*[0-9]*[\\s]*|[\\s]*)+"); - private boolean mIsOptionsUiBound = false; private final PrinterAvailabilityDetector mPrinterAvailabilityDetector = new PrinterAvailabilityDetector(); - private final SimpleStringSplitter mStringCommaSplitter = new SimpleStringSplitter(','); - private final OnFocusChangeListener mSelectAllOnFocusListener = new SelectAllOnFocusListener(); private PrintSpoolerProvider mSpoolerProvider; @@ -1493,9 +1479,11 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat cancelPrint(); } } else if (view == mMoreOptionsButton) { - // The selected pages is only applied once the user leaves the text field. A click - // on this button, does not count as leaving. - updateSelectedPagesFromTextField(); + if (mPageRangeEditText.getError() == null) { + // The selected pages is only applied once the user leaves the text field. A click + // on this button, does not count as leaving. + updateSelectedPagesFromTextField(); + } if (mCurrentPrinter != null) { startAdvancedPrintOptionsActivity(mCurrentPrinter); @@ -1918,42 +1906,10 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat } if (mRangeOptionsSpinner.getSelectedItemPosition() > 0) { - List<PageRange> pageRanges = new ArrayList<>(); - mStringCommaSplitter.setString(mPageRangeEditText.getText().toString()); - - while (mStringCommaSplitter.hasNext()) { - String range = mStringCommaSplitter.next().trim(); - if (TextUtils.isEmpty(range)) { - continue; - } - final int dashIndex = range.indexOf('-'); - final int fromIndex; - final int toIndex; - - if (dashIndex > 0) { - fromIndex = Integer.parseInt(range.substring(0, dashIndex).trim()) - 1; - // It is possible that the dash is at the end since the input - // verification can has to allow the user to keep entering if - // this would lead to a valid input. So we handle this. - if (dashIndex < range.length() - 1) { - String fromString = range.substring(dashIndex + 1, range.length()).trim(); - toIndex = Integer.parseInt(fromString) - 1; - } else { - toIndex = fromIndex; - } - } else { - fromIndex = toIndex = Integer.parseInt(range) - 1; - } - - PageRange pageRange = new PageRange(Math.min(fromIndex, toIndex), - Math.max(fromIndex, toIndex)); - pageRanges.add(pageRange); - } - - PageRange[] pageRangesArray = new PageRange[pageRanges.size()]; - pageRanges.toArray(pageRangesArray); + PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info; + final int pageCount = (info != null) ? getAdjustedPageCount(info) : 0; - return PageRangeUtils.normalize(pageRangesArray); + return PageRangeUtils.parsePageRanges(mPageRangeEditText.getText(), pageCount); } return PageRange.ALL_PAGES_ARRAY; @@ -2785,7 +2741,7 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat editText.setSelection(editText.getText().length()); } - if (view == mPageRangeEditText && !hasFocus) { + if (view == mPageRangeEditText && !hasFocus && mPageRangeEditText.getError() == null) { updateSelectedPagesFromTextField(); } } @@ -2805,18 +2761,12 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat @Override public void afterTextChanged(Editable editable) { final boolean hadErrors = hasErrors(); - String text = editable.toString(); - if (TextUtils.isEmpty(text)) { - if (mPageRangeEditText.getError() == null) { - mPageRangeEditText.setError(""); - updateOptionsUi(); - } - return; - } + PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info; + final int pageCount = (info != null) ? getAdjustedPageCount(info) : 0; + PageRange[] ranges = PageRangeUtils.parsePageRanges(editable, pageCount); - String escapedText = PATTERN_ESCAPE_SPECIAL_CHARS.matcher(text).replaceAll("////"); - if (!PATTERN_PAGE_RANGE.matcher(escapedText).matches()) { + if (ranges.length == 0) { if (mPageRangeEditText.getError() == null) { mPageRangeEditText.setError(""); updateOptionsUi(); @@ -2824,30 +2774,6 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat return; } - PrintDocumentInfo info = mPrintedDocument.getDocumentInfo().info; - final int pageCount = (info != null) ? getAdjustedPageCount(info) : 0; - - // The range - Matcher matcher = PATTERN_DIGITS.matcher(text); - while (matcher.find()) { - String numericString = text.substring(matcher.start(), matcher.end()).trim(); - if (TextUtils.isEmpty(numericString)) { - continue; - } - final int pageIndex = Integer.parseInt(numericString); - if (pageIndex < 1 || pageIndex > pageCount) { - if (mPageRangeEditText.getError() == null) { - mPageRangeEditText.setError(""); - updateOptionsUi(); - } - return; - } - } - - // We intentionally do not catch the case of the from page being - // greater than the to page. When computing the requested pages - // we just swap them if necessary. - if (mPageRangeEditText.getError() != null) { mPageRangeEditText.setError(null); updateOptionsUi(); diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java index cee16c8b29e9..fcc9f6a36171 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/SelectPrinterActivity.java @@ -18,12 +18,11 @@ package com.android.printspooler.ui; import android.app.Activity; import android.app.LoaderManager; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentSender.SendIntentException; import android.content.Loader; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager.NameNotFoundException; import android.database.DataSetObserver; import android.graphics.drawable.Drawable; import android.os.Bundle; @@ -34,6 +33,7 @@ import android.print.PrinterInfo; import android.printservice.PrintServiceInfo; import android.provider.Settings; import android.text.TextUtils; +import android.util.ArrayMap; import android.util.Log; import android.util.TypedValue; import android.view.ContextMenu; @@ -80,8 +80,8 @@ public final class SelectPrinterActivity extends Activity implements private static final String KEY_NOT_FIRST_CREATE = "KEY_NOT_FIRST_CREATE"; - /** If there are any enabled print services */ - private boolean mHasEnabledPrintServices; + /** The currently enabled print services by their ComponentName */ + private ArrayMap<ComponentName, PrintServiceInfo> mEnabledPrintServices; private PrinterRegistry mPrinterRegistry; @@ -100,6 +100,8 @@ public final class SelectPrinterActivity extends Activity implements setContentView(R.layout.select_printer_activity); + mEnabledPrintServices = new ArrayMap<>(); + mPrinterRegistry = new PrinterRegistry(this, null, LOADER_ID_PRINT_REGISTRY, LOADER_ID_PRINT_REGISTRY_INT); @@ -317,7 +319,7 @@ public final class SelectPrinterActivity extends Activity implements } TextView titleView = (TextView) findViewById(R.id.title); View progressBar = findViewById(R.id.progress_bar); - if (!mHasEnabledPrintServices) { + if (mEnabledPrintServices.size() > 0) { titleView.setText(R.string.print_no_print_services); progressBar.setVisibility(View.GONE); } else if (adapter.getUnfilteredCount() <= 0) { @@ -346,11 +348,16 @@ public final class SelectPrinterActivity extends Activity implements @Override public void onLoadFinished(Loader<List<PrintServiceInfo>> loader, - List<PrintServiceInfo> data) { - if (data == null || data.isEmpty()) { - mHasEnabledPrintServices = false; - } else { - mHasEnabledPrintServices = true; + List<PrintServiceInfo> services) { + mEnabledPrintServices.clear(); + + if (services != null && !services.isEmpty()) { + final int numServices = services.size(); + for (int i = 0; i < numServices; i++) { + PrintServiceInfo service = services.get(i); + + mEnabledPrintServices.put(service.getComponentName(), service); + } } onPrintServicesUpdate(); @@ -533,14 +540,12 @@ public final class SelectPrinterActivity extends Activity implements CharSequence title = printer.getName(); Drawable icon = printer.loadIcon(SelectPrinterActivity.this); - CharSequence printServiceLabel; - try { - PackageInfo packageInfo = getPackageManager().getPackageInfo( - printer.getId().getServiceName().getPackageName(), 0); + PrintServiceInfo service = mEnabledPrintServices.get(printer.getId().getServiceName()); - printServiceLabel = packageInfo.applicationInfo.loadLabel(getPackageManager()); - } catch (NameNotFoundException e) { - printServiceLabel = null; + CharSequence printServiceLabel = null; + if (service != null) { + printServiceLabel = service.getResolveInfo().loadLabel(getPackageManager()) + .toString(); } CharSequence description = printer.getDescription(); diff --git a/packages/PrintSpooler/src/com/android/printspooler/util/PageRangeUtils.java b/packages/PrintSpooler/src/com/android/printspooler/util/PageRangeUtils.java index 2b317b3cbef0..7425c033a7a4 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/util/PageRangeUtils.java +++ b/packages/PrintSpooler/src/com/android/printspooler/util/PageRangeUtils.java @@ -18,7 +18,9 @@ package com.android.printspooler.util; import android.print.PageRange; import android.print.PrintDocumentInfo; +import android.util.Pair; +import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -155,6 +157,167 @@ public final class PageRangeUtils { } /** + * Return the next position after {@code pos} that is not a space character. + * + * @param s The string to parse + * @param pos The starting position + * + * @return The position of the first space character + */ + private static int readWhiteSpace(CharSequence s, int pos) { + while (pos < s.length() && s.charAt(pos) == ' ') { + pos++; + } + + return pos; + } + + /** + * Read a number from a string at a certain position. + * + * @param s The string to parse + * @param pos The starting position + * + * @return The position after the number + the number read or null if the number was not found + */ + private static Pair<Integer, Integer> readNumber(CharSequence s, int pos) { + Integer result = 0; + while (pos < s.length() && s.charAt(pos) >= '0' && s.charAt(pos) <= '9') { + // Number cannot start with 0 + if (result == 0 && s.charAt(pos) == '0') { + break; + } + result = result * 10 + (s.charAt(pos) - '0'); + // Abort on overflow + if (result < 0) { + break; + } + pos++; + } + + // 0 is not a valid page number + if (result == 0) { + return new Pair<>(pos, null); + } else { + return new Pair<>(pos, result); + } + } + + /** + * Read a single character from a string at a certain position. + * + * @param s The string to parse + * @param pos The starting position + * @param expectedChar The character to read + * + * @return The position after the character + the character read or null if the character was + * not found + */ + private static Pair<Integer, Character> readChar(CharSequence s, int pos, char expectedChar) { + if (pos < s.length() && s.charAt(pos) == expectedChar) { + return new Pair<>(pos + 1, expectedChar); + } else { + return new Pair<>(pos, null); + } + } + + /** + * Read a page range character from a string at a certain position. + * + * @param s The string to parse + * @param pos The starting position + * @param maxPageNumber The highest page number to accept. + * + * @return The position after the page range + the page range read or null if the page range was + * not found + */ + private static Pair<Integer, PageRange> readRange(CharSequence s, int pos, int maxPageNumber) { + Pair<Integer, Integer> retInt; + Pair<Integer, Character> retChar; + + Character comma; + if (pos == 0) { + // When we reading the first range, we do not want to have a comma + comma = ','; + } else { + retChar = readChar(s, pos, ','); + pos = retChar.first; + comma = retChar.second; + } + + pos = readWhiteSpace(s, pos); + + retInt = readNumber(s, pos); + pos = retInt.first; + Integer start = retInt.second; + + pos = readWhiteSpace(s, pos); + + retChar = readChar(s, pos, '-'); + pos = retChar.first; + Character separator = retChar.second; + + pos = readWhiteSpace(s, pos); + + retInt = readNumber(s, pos); + pos = retInt.first; + Integer end = retInt.second; + + pos = readWhiteSpace(s, pos); + + if (comma != null && + // range, maybe unbounded + ((separator != null && (start != null || end != null)) || + // single page + (separator == null && start != null && end == null))) { + if (start == null) { + start = 1; + } + + if (end == null) { + if (separator == null) { + end = start; + } else { + end = maxPageNumber; + } + } + + if (start <= end && start >= 1 && end <= maxPageNumber) { + return new Pair<>(pos, new PageRange(start - 1, end - 1)); + } + } + + return new Pair<>(pos, null); + } + + /** + * Parse a string into an array of page ranges. + * + * @param s The string to parse + * @param maxPageNumber The highest page number to accept. + * + * @return The parsed ranges or null if the string could not be parsed. + */ + public static PageRange[] parsePageRanges(CharSequence s, int maxPageNumber) { + ArrayList<PageRange> ranges = new ArrayList<>(); + + int pos = 0; + while (pos < s.length()) { + Pair<Integer, PageRange> retRange = readRange(s, pos, maxPageNumber); + + if (retRange.second == null) { + ranges.clear(); + break; + } + + ranges.add(retRange.second); + pos = retRange.first; + } + + return PageRangeUtils.normalize(ranges.toArray(new PageRange[ranges.size()])); + } + + /** * Offsets a the start and end of page ranges with the given value. * * @param pageRanges The page ranges to offset. diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml index 9cf9dc979c2a..c44f0d06bd65 100644 --- a/packages/SettingsLib/res/values-af/strings.xml +++ b/packages/SettingsLib/res/values-af/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierdie kenmerk is eksperimenteel en kan werkverrigting beïnvloed."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Geneutraliseer deur <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ongeveer <xliff:g id="TIME">%1$s</xliff:g> oor"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – sowat <xliff:g id="TIME">%2$s</xliff:g> oor"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol op WS"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol oor USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tot vol vanaf draadloos"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Onbekend"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Laai"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laai tans op WS"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Laai tans oor USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Laai tans draadloos"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Laai nie"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laai nie"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Vol"</string> diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml index 40e5a31c87fc..cd05135def5c 100644 --- a/packages/SettingsLib/res/values-am/strings.xml +++ b/packages/SettingsLib/res/values-am/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ይህ ባህሪ የሙከራ ነውና አፈጻጸም ላይ ተጽዕኖ ሊኖረው ይችላል።"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"በ<xliff:g id="TITLE">%1$s</xliff:g> ተሽሯል"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"<xliff:g id="TIME">%1$s</xliff:g> ገደማ ቀርቷል"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ገደማ <xliff:g id="TIME">%2$s</xliff:g> ይቀራል"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> እስከሚሞላ ድረስ"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> በኤሲ ላይ እስከሚሞላ ድረስ"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> በዩኤስቢ ላይ እስከሚሞላ ድረስ"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> በገመድ አልባ ላይ እስከሚሞላ ድረስ"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"ያልታወቀ"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"ኃይል በመሙላት ላይ"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"በኤሲ ሃይል በመሙላት ላይ"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"በዩኤስቢ ሃይል በመሙላት ላይ"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"በገመድ አልባ ሃይል በመሙላት ላይ"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"ባትሪ እየሞላ አይደለም"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ኃይል እየሞላ አይደለም"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ሙሉነው"</string> diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml index e21b02c706df..b3f55eb03fd1 100644 --- a/packages/SettingsLib/res/values-ar/strings.xml +++ b/packages/SettingsLib/res/values-ar/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"هذه الميزة تجريبية وقد تؤثر في الأداء."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"تم الاستبدال بـ <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"يتبقى <xliff:g id="TIME">%1$s</xliff:g> تقريبًا"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - تبقى <xliff:g id="TIME">%2$s</xliff:g> تقريبًا"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال باستخدام التيار المتردد"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال عبر USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> حتى الاكتمال بالشحن اللاسلكي"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"غير معروف"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"شحن"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"جارٍ الشحن بتيار متردد"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"جارٍ الشحن عبر USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"جارٍ الشحن لاسلكيًا"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"لا يتم الشحن"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"لا يتم الشحن"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ممتلئة"</string> diff --git a/packages/SettingsLib/res/values-az-rAZ/strings.xml b/packages/SettingsLib/res/values-az-rAZ/strings.xml index ca06e664fca9..9a099aff3a7f 100644 --- a/packages/SettingsLib/res/values-az-rAZ/strings.xml +++ b/packages/SettingsLib/res/values-az-rAZ/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya eksperimentaldır və performansa təsir edə bilər."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tərəfindən qəbul edilmir"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Təxminən <xliff:g id="TIME">%1$s</xliff:g> qalıb"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - təxminən <xliff:g id="TIME">%2$s</xliff:g> qalıb"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> dolana qədər"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC üzərindən dolana qədər"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB üzərindən dolana qədər"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> naqilsiz üzərindən dolana qədər"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Naməlum"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Enerji doldurma"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Dəyişən cərəyanda qidalanır"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB üzərindən qidalanır"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Naqilsiz qidalanır"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Doldurulmur"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Enerji doldurulmur"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Tam"</string> diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml index 4bd9b0381cac..85b6ac2fb13b 100644 --- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml +++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna i može da utiče na performanse."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamenjuje ga <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo oko <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni punjačem"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni preko USB-a"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> dok se ne napuni bežično"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Punjenje preko punjača"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Punjenje preko USB-a"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bežično punjenje"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string> diff --git a/packages/SettingsLib/res/values-be-rBY/strings.xml b/packages/SettingsLib/res/values-be-rBY/strings.xml index ebb5a592a75e..c8098ec22300 100644 --- a/packages/SettingsLib/res/values-be-rBY/strings.xml +++ b/packages/SettingsLib/res/values-be-rBY/strings.xml @@ -278,7 +278,7 @@ <string name="enable_webview_multiprocess_desc" msgid="852226124223847283">"Запусціць апрацоўшчыкі WebView у ізаляваным працэсе."</string> <string name="select_webview_provider_title" msgid="4628592979751918907">"Рэалізацыя WebView"</string> <string name="select_webview_provider_dialog_title" msgid="4370551378720004872">"Наладзіць рэалізацыю WebView"</string> - <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Гэты элемент больш не даступны для выбару. Паспрабуйце яшчэ раз."</string> + <string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Гэты варыянт больш не даступны. Паспрабуйце яшчэ раз."</string> <string name="convert_to_file_encryption" msgid="3060156730651061223">"Перайсці на шыфраванне файлаў"</string> <string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Пераход..."</string> <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Шыфраванне файлаў ужо дзейнічае"</string> @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Гэтая функцыя з\'яўляецца эксперыментальнай і можа паўплываць на прадукцыйнасць."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Перавызначаны <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Засталося прыблізна <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – засталося прыблізна <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі ад сеткі пер. току"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўнай зарадкі па USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> да поўн. зарадкі бесправадным шляхам"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Невядома"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Зарадка"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Зар. ад сеткі пер. току"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Зарадка па USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Бесправадная зарадка"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Не зараджаецца"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не зараджаецца"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Поўная"</string> diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml index e0641b1b45ac..35b24bf23129 100644 --- a/packages/SettingsLib/res/values-bg/strings.xml +++ b/packages/SettingsLib/res/values-bg/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Тази функция е експериментална и може да се отрази на ефективността."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Заменено от „<xliff:g id="TITLE">%1$s</xliff:g>“"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Прибл. оставащо време: <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – приблизително оставащо време: <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане при променлив ток"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно зареждане през USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до пълно безжично зареждане"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Неизвестно"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Зарежда се"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Зареждане при AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Зареждане през USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Безжично зареждане"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Не се зарежда"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се зарежда"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Пълна"</string> diff --git a/packages/SettingsLib/res/values-bn-rBD/strings.xml b/packages/SettingsLib/res/values-bn-rBD/strings.xml index 5ca7d033ccac..14c2c9549fc5 100644 --- a/packages/SettingsLib/res/values-bn-rBD/strings.xml +++ b/packages/SettingsLib/res/values-bn-rBD/strings.xml @@ -296,17 +296,26 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"এই বৈশিষ্ট্যটি পরীক্ষামূলক এবং এটি কার্য-সম্পাদনা প্রভাবিত করতে পারে।"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> এর দ্বারা ওভাররাইড করা হয়েছে"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"প্রায় <xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string> + <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> বাকী আছে"</string> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - আনুমানিক <xliff:g id="TIME">%2$s</xliff:g> বাকি আছে"</string> + <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> বাকী আছে"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - সম্পূর্ণ হতে <xliff:g id="TIME">%2$s</xliff:g> বাকি"</string> + <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - ACতে সম্পূর্ণ হতে <xliff:g id="TIME">%2$s</xliff:g> বাকি"</string> + <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB এর মাধ্যমে সম্পূর্ণ হতে <xliff:g id="TIME">%2$s</xliff:g> বাকি"</string> + <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - বেতার যোগে সম্পূর্ণ হতে <xliff:g id="TIME">%2$s</xliff:g> বাকি"</string> + <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="battery_info_status_unknown" msgid="196130600938058547">"অজানা"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"চার্জ হচ্ছে"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC তে চার্জ হচ্ছে"</string> + <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"চার্জ হচ্ছে"</string> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB এর মাধ্যমে চার্জ হচ্ছে"</string> + <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"চার্জ হচ্ছে"</string> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"তারবিহীনভাবে চার্জ হচ্ছে"</string> + <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"চার্জ হচ্ছে"</string> <string name="battery_info_status_discharging" msgid="310932812698268588">"চার্জ হচ্ছে না"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"চার্জ হচ্ছে না"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"পূর্ণ"</string> diff --git a/packages/SettingsLib/res/values-bs-rBA/strings.xml b/packages/SettingsLib/res/values-bs-rBA/strings.xml index ce0f40994906..f9c7fcad3907 100644 --- a/packages/SettingsLib/res/values-bs-rBA/strings.xml +++ b/packages/SettingsLib/res/values-bs-rBA/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova funkcija je eksperimentalna te može utjecati na performanse."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Zamjenjuje <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još otprilike <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – preostalo vreme je otprilike <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pune baterije"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do kraja punjenja na el. napajanju"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pune baterije preko USB-a"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pune baterije bežičnim punjenjem"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Puni se"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Puni se na punjaču"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Punjenje preko USB-a"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bežično punjenje"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string> diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml index 5106f5bd4f77..a07074071b55 100644 --- a/packages/SettingsLib/res/values-ca/strings.xml +++ b/packages/SettingsLib/res/values-ca/strings.xml @@ -296,17 +296,26 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Aquesta funció és experimental i pot afectar el rendiment."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"S\'ha substituït per <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Temps restant aproximat: <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Temps restant: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g>: falten aproximadament <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g>; temps restant: <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega"</string> + <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega per CA"</string> + <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega per USB"</string> + <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> per completar la càrrega sense fil"</string> + <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconegut"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"S\'està carregant"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Càrrega: corr. alt."</string> + <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"S\'està carregant"</string> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Càrrega per USB"</string> + <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"S\'està carregant"</string> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Càrrega sense fils"</string> + <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"S\'està carregant"</string> <string name="battery_info_status_discharging" msgid="310932812698268588">"No s\'està carregant"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No s\'està carregant"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Plena"</string> diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml index 3d3dd6fb1877..040c9f06255f 100644 --- a/packages/SettingsLib/res/values-cs/strings.xml +++ b/packages/SettingsLib/res/values-cs/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkce je experimentální a může mít vliv na výkon."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Přepsáno nastavením <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Zbývající čas: <xliff:g id="TIME">%1$s</xliff:g> (přibližně)"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zbývá přibližně <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití ze zásuvky"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití přes USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabití bezdrátově"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Neznámé"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjí se"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Nabíjení z adaptéru"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Nabíjení přes USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bezdrátové nabíjení"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Nenabíjí se"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíjí se"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string> diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml index 1f354b7f1bea..ddad673dfc86 100644 --- a/packages/SettingsLib/res/values-da/strings.xml +++ b/packages/SettingsLib/res/values-da/strings.xml @@ -296,17 +296,26 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Denne funktion er eksperimentel og kan påvirke ydeevnen."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tilsidesat af <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> tilbage"</string> + <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> tilbage"</string> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string> + <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> tilbage"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til fuldt opladet"</string> + <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til fuldt opladet med adapter"</string> + <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til fuldt opladet med USB"</string> + <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> til fuldt opladet med trådløs"</string> + <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="battery_info_status_unknown" msgid="196130600938058547">"Ukendt"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Oplader"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Opladning med AC"</string> + <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Oplader"</string> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Opladning via USB"</string> + <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Oplader"</string> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Trådløs opladning"</string> + <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Oplader"</string> <string name="battery_info_status_discharging" msgid="310932812698268588">"Oplader ikke"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Oplader ikke"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Fuld"</string> diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml index 404b72b24dc8..514228faea41 100644 --- a/packages/SettingsLib/res/values-de/strings.xml +++ b/packages/SettingsLib/res/values-de/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Hierbei handelt es sich um eine experimentelle Funktion. Dies kann sich auf die Leistung auswirken."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Außer Kraft gesetzt von \"<xliff:g id="TITLE">%1$s</xliff:g>\""</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Noch ca. <xliff:g id="TIME">%1$s</xliff:g> verbleibend"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – noch etwa <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – voll in <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – bei Stromanschluss voll in <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – über USB voll in <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – bei kabellosem Laden voll in <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Unbekannt"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Wird aufgeladen"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laden über Netzteil"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Laden über USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Kabelloses Laden"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Wird nicht geladen"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wird nicht geladen"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Voll"</string> diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml index 52988f67741b..8df693ae3b54 100644 --- a/packages/SettingsLib/res/values-el/strings.xml +++ b/packages/SettingsLib/res/values-el/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Αυτή η λειτουργία είναι πειραματική και ενδεχομένως να επηρεάσει τις επιδόσεις."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Αντικαταστάθηκε από <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Απομένουν περίπου <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - απομένουν περίπου <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση με φορτιστή AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη φόρτιση μέσω USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> για πλήρη ασύρματη φόρτιση"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Άγνωστο"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Φόρτιση"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Φόρτιση με AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Φόρτιση μέσω USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Ασύρματη φόρτιση"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Δεν φορτίζει"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Δεν φορτίζει"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Πλήρης"</string> diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml index b2df062b6f11..466291aff7ff 100644 --- a/packages/SettingsLib/res/values-en-rAU/strings.xml +++ b/packages/SettingsLib/res/values-en-rAU/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full on AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full over USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full from wireless"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Charging on AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Charging over USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Charging wirelessly"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string> diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml index b2df062b6f11..466291aff7ff 100644 --- a/packages/SettingsLib/res/values-en-rGB/strings.xml +++ b/packages/SettingsLib/res/values-en-rGB/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full on AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full over USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full from wireless"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Charging on AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Charging over USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Charging wirelessly"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string> diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml index b2df062b6f11..466291aff7ff 100644 --- a/packages/SettingsLib/res/values-en-rIN/strings.xml +++ b/packages/SettingsLib/res/values-en-rIN/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"This feature is experimental and may affect performance."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overridden by <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Approx. <xliff:g id="TIME">%1$s</xliff:g> left"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – approx. <xliff:g id="TIME">%2$s</xliff:g> left"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full on AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full over USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> until full from wireless"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Unknown"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Charging"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Charging on AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Charging over USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Charging wirelessly"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Not charging"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Not charging"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Full"</string> diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml index dd7ee4d6823d..9bc2cf414d25 100644 --- a/packages/SettingsLib/res/values-es-rUS/strings.xml +++ b/packages/SettingsLib/res/values-es-rUS/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar el rendimiento."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Reemplazado por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Falta <xliff:g id="TIME">%1$s</xliff:g> aproximadamente"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g>: alrededor de <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga por CA"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga por USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> para completar la carga inalámbrica"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconocido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Carga en CA"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Carga con USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Carga inalámbrica"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"No se está cargando."</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se realiza la carga"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Cargado"</string> diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml index 0cc6cb6fa83c..ec0cafea2792 100644 --- a/packages/SettingsLib/res/values-es/strings.xml +++ b/packages/SettingsLib/res/values-es/strings.xml @@ -34,7 +34,7 @@ <string name="connected_via_passpoint" msgid="2826205693803088747">"Conectado a través de %1$s"</string> <string name="available_via_passpoint" msgid="1617440946846329613">"Disponible a través de %1$s"</string> <string name="wifi_connected_no_internet" msgid="3149853966840874992">"Conexión sin Internet"</string> - <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectada"</string> + <string name="bluetooth_disconnected" msgid="6557104142667339895">"Desconectado"</string> <string name="bluetooth_disconnecting" msgid="8913264760027764974">"Desconectando…"</string> <string name="bluetooth_connecting" msgid="8555009514614320497">"Estableciendo conexión…"</string> <string name="bluetooth_connected" msgid="6038755206916626419">"Conectado"</string> @@ -296,17 +296,26 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función es experimental y puede afectar al rendimiento."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Tiempo restante (aproximado): <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Tiempo restante: <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - Quedan <xliff:g id="TIME">%2$s</xliff:g> aproximadamente"</string> + <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> - Tiempo restante: <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la batería"</string> + <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la batería con CA"</string> + <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la batería por USB"</string> + <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar la batería con Wi-Fi"</string> + <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconocido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Cargando en CA"</string> + <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Cargando"</string> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Cargando por USB"</string> + <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Cargando"</string> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Cargando de forma inalámbrica"</string> + <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Cargando"</string> <string name="battery_info_status_discharging" msgid="310932812698268588">"No se está cargando"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"No se está cargando"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string> diff --git a/packages/SettingsLib/res/values-et-rEE/strings.xml b/packages/SettingsLib/res/values-et-rEE/strings.xml index a275b1a8c9af..29a1aea1e20d 100644 --- a/packages/SettingsLib/res/values-et-rEE/strings.xml +++ b/packages/SettingsLib/res/values-et-rEE/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"See funktsioon on katseline ja võib mõjutada toimivust."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Alistas <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Umbes <xliff:g id="TIME">%1$s</xliff:g> on jäänud"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – jäänud on umbes <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis (vahelduvvool)"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis (USB)"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, kuni aku on täis (juhtmeta laad.)"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Tundmatu"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Laadimine"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laad. vahelduvv.-v."</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Laadimine USB kaudu"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Juhtmevaba laadimine"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Ei lae"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei lae"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Täis"</string> diff --git a/packages/SettingsLib/res/values-eu-rES/strings.xml b/packages/SettingsLib/res/values-eu-rES/strings.xml index 2556224e0dce..4f55e350fbe0 100644 --- a/packages/SettingsLib/res/values-eu-rES/strings.xml +++ b/packages/SettingsLib/res/values-eu-rES/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Eginbidea esperimentala da eta eragina izan dezake funtzionamenduan."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> hobespena gainjarri zaio"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"<xliff:g id="TIME">%1$s</xliff:g> inguru guztiz kargatu arte"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> inguru. <xliff:g id="TIME">%2$s</xliff:g> geratzen d(ir)a"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> korrontearen bidez guztiz kargatu arte"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB bidez guztiz kargatu arte"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> haririk gabe guztiz kargatu arte"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Ezezaguna"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Kargatzea"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"KA bidez kargatzen"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB bidez kargatzen"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Hari gabe kargatzen"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Ez da kargatzen ari"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ez da kargatzen ari"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Beteta"</string> diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml index 1e67182a4bda..e9d63fddd521 100644 --- a/packages/SettingsLib/res/values-fa/strings.xml +++ b/packages/SettingsLib/res/values-fa/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"این قابلیت آزمایشی است و ممکن است عملکرد را تحت تأثیر قرار دهد."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"توسط <xliff:g id="TITLE">%1$s</xliff:g> لغو شد"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"تقریباً <xliff:g id="TIME">%1$s</xliff:g> باقی مانده است"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریباً <xliff:g id="TIME">%2$s</xliff:g> باقی مانده است"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل با جریان متناوب"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل از طریق USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> تا شارژ کامل بهطور بیسیم"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"ناشناس"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"در حال شارژ شدن"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"شارژ با جریان متناوب"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"شارژ از طریق USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"شارژ به صورت بیسیم"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"شارژ نمیشود"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"شارژ نمیشود"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"پر"</string> diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml index 3d8ac9887163..5531d270e1f3 100644 --- a/packages/SettingsLib/res/values-fi/strings.xml +++ b/packages/SettingsLib/res/values-fi/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tämä ominaisuus on kokeellinen ja voi vaikuttaa suorituskykyyn."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Tämän ohittaa <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Noin <xliff:g id="TIME">%1$s</xliff:g> jäljellä"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – noin <xliff:g id="TIME">%2$s</xliff:g> jäljellä"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä (laturilataus)"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä (USB-lataus)"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> kunnes täynnä (WiFi-lataus)"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Tuntematon"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Ladataan"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laturilataus"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB-lataus"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Langaton lataus"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Ei laturissa"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ei laturissa"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Täynnä"</string> diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml index 4eb3a427d0d4..df6bdc64b394 100644 --- a/packages/SettingsLib/res/values-fr-rCA/strings.xml +++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut toucher les performances."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> %% – Temps restant : environ <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>)"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (charge complète sur c.a. dans <xliff:g id="TIME">%2$s</xliff:g>)"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (chargée à 100 %% par USB dans <xliff:g id="TIME">%2$s</xliff:g>)"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> %% (chargée à 100 %% avec chargeur sans fil dans <xliff:g id="TIME">%2$s</xliff:g>)"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"En charge (c.a.)"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"En charge par USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"En charge sans fil"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"N\'est pas en charge"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"N\'est pas en charge"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Pleine"</string> diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml index efb10ecedeb6..ee40b2a42ff2 100644 --- a/packages/SettingsLib/res/values-fr/strings.xml +++ b/packages/SettingsLib/res/values-fr/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Cette fonctionnalité est expérimentale et peut affecter les performances."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Remplacé par <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Il reste environ <xliff:g id="TIME">%1$s</xliff:g>."</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – Temps restant : <xliff:g id="TIME">%2$s</xliff:g> environ"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% dans <xliff:g id="TIME">%2$s</xliff:g>)"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% sur secteur dans <xliff:g id="TIME">%2$s</xliff:g>)"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% via USB dans <xliff:g id="TIME">%2$s</xliff:g>)"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> (chargée à 100 %% sans fil dans <xliff:g id="TIME">%2$s</xliff:g>)"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Inconnu"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Batterie en charge"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"En charge sur secteur"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"En charge via USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"En charge sans fil"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Pas en charge"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Débranchée"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"pleine"</string> diff --git a/packages/SettingsLib/res/values-gl-rES/strings.xml b/packages/SettingsLib/res/values-gl-rES/strings.xml index 3d61e215208c..4a0451e42aad 100644 --- a/packages/SettingsLib/res/values-gl-rES/strings.xml +++ b/packages/SettingsLib/res/values-gl-rES/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta función é experimental e pode afectar ao rendemento."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Anulado por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Duración aproximada de <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - faltan aproximadamente <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga con CA"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga con USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> para completar a carga co modo sen fíos"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Descoñecido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Cargando"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Cargando con CA"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Cargando por USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Cargando sen fíos"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Non se está cargando"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non está cargando"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Completa"</string> diff --git a/packages/SettingsLib/res/values-gu-rIN/strings.xml b/packages/SettingsLib/res/values-gu-rIN/strings.xml index 628b4be81c46..becda2852f46 100644 --- a/packages/SettingsLib/res/values-gu-rIN/strings.xml +++ b/packages/SettingsLib/res/values-gu-rIN/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"આ સુવિધા પ્રાયોગિક છે અને કામગીરી પર અસર કરી શકે છે."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> દ્વારા ઓવરરાઇડ થયું"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"અંદાજે. <xliff:g id="TIME">%1$s</xliff:g> બાકી"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - આશરે <xliff:g id="TIME">%2$s</xliff:g> બાકી"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"સંપૂર્ણ થવામાં <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g>, AC પર પૂર્ણ ચાર્જ થયાંને <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g>, USB પર પૂર્ણ ચાર્જ થયાંને <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> વાયરલેસ દ્વારા પૂર્ણ થાય ત્યાં સુધી"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"અજાણ્યું"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"ચાર્જ થઈ રહ્યું છે"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC પર ચાર્જિંગ"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB થી ચાર્જિંગ"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"વાયરલેસથી ચાર્જિંગ"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"ચાર્જ થઈ રહ્યું નથી"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ચાર્જ થઈ રહ્યું નથી"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"પૂર્ણ"</string> diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml index 047c7db08f80..6dffdd9d7269 100644 --- a/packages/SettingsLib/res/values-hi/strings.xml +++ b/packages/SettingsLib/res/values-hi/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यह सुविधा प्रायोगिक है और निष्पादन को प्रभावित कर सकती है."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> के द्वारा ओवरराइड किया गया"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"लगभग <xliff:g id="TIME">%1$s</xliff:g> शेष"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - लगभग <xliff:g id="TIME">%2$s</xliff:g> शेष"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूरी होने तक"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC पर पूरी होने तक"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB पर पूरी होने तक"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> वायरलेस से पूरी होने तक"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हो रही है"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC से चार्ज हो रही"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB पर चार्ज हो रही"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"वायरलेस रूप से चार्ज हो रही"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"चार्ज नहीं हो रही है"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज नहीं हो रही है"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"पूरी"</string> diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml index f5ad6d2323a1..1edb01544831 100644 --- a/packages/SettingsLib/res/values-hr/strings.xml +++ b/packages/SettingsLib/res/values-hr/strings.xml @@ -296,17 +296,26 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ova je značajka eksperimentalna i može utjecati na performanse."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Premošćeno postavkom <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Još približno <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"Još <xliff:g id="TIME">%1$s</xliff:g>"</string> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – još približno <xliff:g id="TIME">%2$s</xliff:g>"</string> + <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – još <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti"</string> + <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti strujnim napajanjem"</string> + <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti putem USB-a"</string> + <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napunjenosti bežičnim putem"</string> + <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="battery_info_status_unknown" msgid="196130600938058547">"Nepoznato"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Punjenje"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Punjenje punjačem"</string> + <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Punjenje"</string> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Punjenje putem USB-a"</string> + <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Punjenje"</string> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bežično punjenje"</string> + <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Punjenje"</string> <string name="battery_info_status_discharging" msgid="310932812698268588">"Ne puni se"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ne puni se"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Puna"</string> diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml index 7279c9cfc2f8..060599cfa10e 100644 --- a/packages/SettingsLib/res/values-hu/strings.xml +++ b/packages/SettingsLib/res/values-hu/strings.xml @@ -296,17 +296,26 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ez egy kísérleti funkció, és hatással lehet a teljesítményre."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Felülírva erre: <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Kb. <xliff:g id="TIME">%1$s</xliff:g> van hátra"</string> + <string name="power_remaining_duration_only_short" msgid="5329694252258605547">"<xliff:g id="TIME">%1$s</xliff:g> van hátra"</string> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – kb. <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string> + <string name="power_discharging_duration_short" msgid="4192244429001842403">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> van hátra"</string> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a teljes töltöttség eléréséig"</string> + <string name="power_charging_duration_short" msgid="1098603958472207920">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a teljes feltöltésig hálózatról"</string> + <string name="power_charging_duration_ac_short" msgid="7895864687218765582">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a teljes feltöltésig USB-ről"</string> + <string name="power_charging_duration_usb_short" msgid="941854728040426399">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> a feltöltésig vezeték nélkül"</string> + <string name="power_charging_duration_wireless_short" msgid="1642664799869599476">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>"</string> <string name="battery_info_status_unknown" msgid="196130600938058547">"Ismeretlen"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Töltés"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Hálózati töltés"</string> + <string name="battery_info_status_charging_ac_short" msgid="7431401092096415502">"Töltés"</string> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB-s töltés"</string> + <string name="battery_info_status_charging_usb_short" msgid="6733371990319101366">"Töltés"</string> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Nem vezetékes töltés"</string> + <string name="battery_info_status_charging_wireless_short" msgid="752569941028903610">"Töltés"</string> <string name="battery_info_status_discharging" msgid="310932812698268588">"Nem tölt"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nem töltődik"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Feltöltve"</string> diff --git a/packages/SettingsLib/res/values-hy-rAM/strings.xml b/packages/SettingsLib/res/values-hy-rAM/strings.xml index 23d83a272ce4..63c433668aea 100644 --- a/packages/SettingsLib/res/values-hy-rAM/strings.xml +++ b/packages/SettingsLib/res/values-hy-rAM/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Սա փորձնական գործառույթ է և կարող է ազդել աշխատանքի վրա:"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Գերազանցված է <xliff:g id="TITLE">%1$s</xliff:g>-ից"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Մնացել է մոտ <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - մնաց մոտավորապես <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը հոսանքից"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը USB-ով"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> մինչև լրիվ լիցքավորումը անլար ցանցից"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Անհայտ"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Լիցքավորում"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Լիցքավորում AC-ով"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Լիցքավորում USB-ով"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Անլար լիցքավորում"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Չի լիցքավորվում"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Չի լիցքավորվում"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Լիցքավորված"</string> diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml index 24fd0f17c4b9..c86c76842eaa 100644 --- a/packages/SettingsLib/res/values-in/strings.xml +++ b/packages/SettingsLib/res/values-in/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Fitur ini bersifat eksperimental dan dapat memengaruhi kinerja."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Digantikan oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Kira-kira tersisa <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira tersisa. <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh pada AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh melalui USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sampai penuh dari nirkabel"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Tidak diketahui"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Mengisi daya"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Mengisi daya pada AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Isi daya lewat USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Isi daya nirkabel"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Tidak mengisi daya"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengisi daya"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string> diff --git a/packages/SettingsLib/res/values-is-rIS/strings.xml b/packages/SettingsLib/res/values-is-rIS/strings.xml index e22dbe036782..1fc0dc0763da 100644 --- a/packages/SettingsLib/res/values-is-rIS/strings.xml +++ b/packages/SettingsLib/res/values-is-rIS/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Þessi eiginleiki er á tilraunastigi og getur haft áhrif á frammistöðu."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Hnekkt af <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Um það bil <xliff:g id="TIME">%1$s</xliff:g> eftir"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – u.þ.b. <xliff:g id="TIME">%2$s</xliff:g> eftir"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu með hleðslutæki"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu í gegnum USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> í fulla hleðslu þráðlaust"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Óþekkt"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Í hleðslu"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Hleðslutæki tengt"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Hleður um USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Hleður þráðlaust"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Ekki í hleðslu"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ekki í hleðslu"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Fullhlaðin"</string> diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml index 84ff78a4a21c..78cd29b854b0 100644 --- a/packages/SettingsLib/res/values-it/strings.xml +++ b/packages/SettingsLib/res/values-it/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Questa funzione è sperimentale e potrebbe influire sulle prestazioni."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valore sostituito da <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Circa <xliff:g id="TIME">%1$s</xliff:g> rimanenti"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – Tempo rimanente: <xliff:g id="TIME">%2$s</xliff:g> circa"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa tramite CA"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> alla carica completa tramite USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> lla carica completa con wireless"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Sconosciuta"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"In carica"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"In carica tramite CA"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"In carica tramite USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"In carica, wireless"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Non in carica"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Non in carica"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Carica"</string> diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml index 74ea37200f52..16e0f44d8e6f 100644 --- a/packages/SettingsLib/res/values-iw/strings.xml +++ b/packages/SettingsLib/res/values-iw/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"תכונה זו היא ניסיונית ועשויה להשפיע על הביצועים."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"נעקף על ידי <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"נשארו <xliff:g id="TIME">%1$s</xliff:g> בערך"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> בקירוב עד לסיום"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד למילוי"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד למילוי בזרם חילופין"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד למילוי ב-USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> עד למילוי בטעינה אלחוטית"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"לא ידוע"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"טוען"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"טוען בזרם חילופין"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"טוען ב-USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"טוען באופן אלחוטי"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"לא בטעינה"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"לא טוען"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"מלא"</string> diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml index 2556d994c469..ce405dffd86a 100644 --- a/packages/SettingsLib/res/values-ja/strings.xml +++ b/packages/SettingsLib/res/values-ja/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"この機能は試験運用機能であり、パフォーマンスに影響することがあります。"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g>によって上書き済み"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"あと約 <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 残り約<xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>(AC)"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>(USB)"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - フル充電まで<xliff:g id="TIME">%2$s</xliff:g>(ワイヤレス)"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"不明"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"ACで充電しています"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USBで充電しています"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"無線で充電しています"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"充電していません"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"充電していません"</string> <!-- String.format failed for translation --> diff --git a/packages/SettingsLib/res/values-ka-rGE/strings.xml b/packages/SettingsLib/res/values-ka-rGE/strings.xml index 29e9459e241b..20a1d2a351ae 100644 --- a/packages/SettingsLib/res/values-ka-rGE/strings.xml +++ b/packages/SettingsLib/res/values-ka-rGE/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ეს ფუნქცია საცდელია და შეიძლება გავლენა იქონიოს შესრულებაზე."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"უკუგებულია <xliff:g id="TITLE">%1$s</xliff:g>-ის მიერ"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"დარჩენილია დაახლოებით <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"დაახლ. <xliff:g id="LEVEL">%1$s</xliff:g> დარჩენილია <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> სრულ დატენვამდე"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ელკვებით სრულ დატენვამდე"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB-თი სრულ დატენვამდე"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> უსადენოდან სრულ დატენვამდე"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"უცნობი"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"იტენება"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"დატენვა ელკვებაზე"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"დატენვა USB-ზე"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"დატენვა უსადენოდ"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"არ იტენება"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"არ იტენება"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ბატარეა დატენილია"</string> diff --git a/packages/SettingsLib/res/values-kk-rKZ/strings.xml b/packages/SettingsLib/res/values-kk-rKZ/strings.xml index fdd3f955e930..e71c8d0ca6d4 100644 --- a/packages/SettingsLib/res/values-kk-rKZ/strings.xml +++ b/packages/SettingsLib/res/values-kk-rKZ/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бұл мүмкіндік эксперименттік болып табылады және өнімділікке әсер етуі мүмкін."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> үстінен басқан"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Шамамен <xliff:g id="TIME">%1$s</xliff:g> қалды"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - шамамен <xliff:g id="TIME">%2$s</xliff:g> қалды"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - айнымалы токпен толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB арқылы толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - сымсыз толғанша <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Белгісіз"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Зарядталуда"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Айнымалы токпен зар."</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB арқылы зарядтау"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Сымсыз зарядтау"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Зарядталу орындалып жатқан жоқ"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Зарядталып тұрған жоқ"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Толық"</string> diff --git a/packages/SettingsLib/res/values-km-rKH/strings.xml b/packages/SettingsLib/res/values-km-rKH/strings.xml index 2cafa294f00e..687b71b17ade 100644 --- a/packages/SettingsLib/res/values-km-rKH/strings.xml +++ b/packages/SettingsLib/res/values-km-rKH/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"លក្ខណៈនេះគឺជាការពិសោធន៍ ហើយអាចប៉ះពាល់ការអនុវត្ត។"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"បដិសេធដោយ <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"នៅសល់ប្រហែល <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - នៅសល់ប្រហែល <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់ពេញ"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់ពេញរចន្តឆ្លាស់"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់ពេញតាមយូអេសប៊ី"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> រហូតដល់ពេញពីឥតខ្សែ"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"មិនស្គាល់"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"កំពុងបញ្ចូលថ្ម"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"បញ្ចូលថ្មតាម AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"បញ្ចូលថ្មតាមយូអេសប៊ី"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"បញ្ចូលថ្មដោយឥតខ្សែ"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"មិនកំពុងបញ្ចូលថ្ម"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"មិនបញ្ចូលថ្ម"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ពេញ"</string> diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml index 6d13b354d8c0..713d9b3a73af 100644 --- a/packages/SettingsLib/res/values-kn-rIN/strings.xml +++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ಇದು ಪ್ರಾಯೋಗಿಕ ವೈಶಿಷ್ಟ್ಯವಾಗಿದೆ. ಕಾರ್ಯಕ್ಷಮತೆ ಮೇಲೆ ಪರಿಣಾಮ ಬೀರಬಹುದು."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ಮೂಲಕ ಅತಿಕ್ರಮಿಸುತ್ತದೆ"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"ಸುಮಾರು <xliff:g id="TIME">%1$s</xliff:g> ಉಳಿದಿದೆ"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"ಸುಮಾರು <xliff:g id="LEVEL">%1$s</xliff:g> <xliff:g id="TIME">%2$s</xliff:g> ಉಳಿದಿದೆ"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC ನಲ್ಲಿ ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB ಮೂಲಕ ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ವೈರ್ಲೆಸ್ನಿಂದ ಪೂರ್ಣವಾಗುವವರೆಗೆ"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"ಅಜ್ಞಾತ"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"ಚಾರ್ಜ್ ಆಗುತ್ತಿದೆ"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC ನಲ್ಲಿ ಚಾರ್ಜ್"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB ಮೂಲಕ ಚಾರ್ಜ್"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"ನಿಸ್ತಂತುವಾಗಿ ಚಾರ್ಜ್"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ಚಾರ್ಜ್ ಆಗುತ್ತಿಲ್ಲ"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ಭರ್ತಿ"</string> diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml index 035793ec0930..348141ed75ca 100644 --- a/packages/SettingsLib/res/values-ko/strings.xml +++ b/packages/SettingsLib/res/values-ko/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"실험실 기능이며 성능에 영향을 줄 수 있습니다."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> 우선 적용됨"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"약 <xliff:g id="TIME">%1$s</xliff:g> 남음"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 대략 <xliff:g id="TIME">%2$s</xliff:g> 남음"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료(AC 전원)"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료(USB)"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 후 충전 완료(무선)"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"알 수 없음"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"충전 중"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"충전 중(AC 전원)"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"충전 중(USB)"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"충전 중(무선)"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"충전 안함"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"충전 안함"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"충전 완료"</string> diff --git a/packages/SettingsLib/res/values-ky-rKG/strings.xml b/packages/SettingsLib/res/values-ky-rKG/strings.xml index 8c43312c34d1..2016f0497820 100644 --- a/packages/SettingsLib/res/values-ky-rKG/strings.xml +++ b/packages/SettingsLib/res/values-ky-rKG/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Бул сынамык мүмкүнчүлүк болгондуктан, иштин майнаптуулугуна таасир этиши мүмкүн."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> менен алмаштырылган"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Болжол менен <xliff:g id="TIME">%1$s</xliff:g> калды"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - болжол менен <xliff:g id="TIME">%2$s</xliff:g> саат калды"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> толгончо"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC аркылуу толгончо"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB аркылуу толгончо"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> зымсыз кубаттоо аркылуу толгончо"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Белгисиз"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Кубатталууда"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"ӨА кубатталууда"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB\'ден кубатталууда"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Зымсыз кубатталууда"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Кубат алган жок"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Кубатталган жок"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Толук"</string> diff --git a/packages/SettingsLib/res/values-lo-rLA/strings.xml b/packages/SettingsLib/res/values-lo-rLA/strings.xml index f158d44dadcf..7e6db5ee29b6 100644 --- a/packages/SettingsLib/res/values-lo-rLA/strings.xml +++ b/packages/SettingsLib/res/values-lo-rLA/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ຄຸນສົມບັດນີ້ກຳລັງຢູ່ໃນການທົດລອງແລະອາດມີຜົນຕໍ່ປະສິດທິພາບ."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"ຖືກແທນໂດຍ <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"ຍັງເຫຼືອປະມານ <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ເຫຼືອປະມານ <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງຈະເຕັມ"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງຈະເຕັມໂດຍສາກດ້ວຍໄຟ AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງຈະເຕັມໂດຍສາກດ້ວຍ USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ຈຶ່ງຈະເຕັມໂດຍສາກແບບໄຮ້ສາຍ"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"ບໍ່ຮູ້ຈັກ"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"ກຳລັງສາກໄຟ"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"ກຳລັງສາກຜ່ານໝໍ້ໄຟ"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"ກຳລັງສາກຜ່ານ USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"ກຳລັງສາກໄຮ້ສາຍ"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"ບໍ່ໄດ້ສາກໄຟ"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ບໍ່ໄດ້ສາກໄຟ"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ເຕັມ"</string> diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml index d5cea8efc460..d49876e69b16 100644 --- a/packages/SettingsLib/res/values-lt/strings.xml +++ b/packages/SettingsLib/res/values-lt/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ši funkcija yra eksperimentinė ir ji gali turėti įtakos našumui."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nepaisyta naudojant nuostatą „<xliff:g id="TITLE">%1$s</xliff:g>“"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Liko maždaug <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – liko maždaug <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo naud. kint. sr."</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo naudojant USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> iki visiško įkrovimo belaid. ryš."</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Nežinomas"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Kraunasi..."</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Įkr. naud. kint. sr."</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Įkraunama naud. USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Įkraunama be laidų"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Nekraunama"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nekraunama"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Visiškai įkrautas"</string> diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml index ea6f4f9627e8..6cd9cfd5da38 100644 --- a/packages/SettingsLib/res/values-lv/strings.xml +++ b/packages/SettingsLib/res/values-lv/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Šī funkcija ir eksperimentāla un var ietekmēt veiktspēju."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Jaunā preference: <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Atlikušais laiks: aptuveni <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> — aptuvenais atlikušais laiks: <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai uzlādei"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai maiņstrāvas uzlādei"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai USB uzlādei"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> — <xliff:g id="TIME">%2$s</xliff:g> līdz pilnai bezvadu uzlādei"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Nezināms"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Uzlāde"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Maiņstrāvas uzlāde"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB uzlāde"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bezvadu uzlāde"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Nenotiek uzlāde"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenotiek uzlāde"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Pilns"</string> diff --git a/packages/SettingsLib/res/values-mk-rMK/strings.xml b/packages/SettingsLib/res/values-mk-rMK/strings.xml index e954cdf12bb6..f8f65ec8bd52 100644 --- a/packages/SettingsLib/res/values-mk-rMK/strings.xml +++ b/packages/SettingsLib/res/values-mk-rMK/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Функцијата е експериментална и може да влијае на изведбата."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Прескокнато според <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Преостанаа прибл. <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – преостанува приближно <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна на AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна преку USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до целосно полна, безжично"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Се полни"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Полнење на струја"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Полнење преку УСБ"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Безжично полнење"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Не се полни"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не се полни"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Целосна"</string> diff --git a/packages/SettingsLib/res/values-ml-rIN/strings.xml b/packages/SettingsLib/res/values-ml-rIN/strings.xml index a4b3877bfe01..7350b7fe10a0 100644 --- a/packages/SettingsLib/res/values-ml-rIN/strings.xml +++ b/packages/SettingsLib/res/values-ml-rIN/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ഈ ഫീച്ചർ പരീക്ഷണാത്മകമായതിനാൽ പ്രകടനത്തെ ബാധിച്ചേക്കാം."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ഉപയോഗിച്ച് അസാധുവാക്കി"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"ഏകദേശം <xliff:g id="TIME">%1$s</xliff:g> ശേഷിക്കുന്നു"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ഏകദേശം <xliff:g id="TIME">%2$s</xliff:g> ശേഷിക്കുന്നു"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - AC-യിൽ പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB വഴി പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - വയർലെസ് വഴി പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"അജ്ഞാതം"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"ചാർജ്ജുചെയ്യുന്നു"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC-യിൽ ചാർജ്ജുചെയ്യുന്നു"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB-യിലൂടെ ചാർജ്ജുചെയ്യുന്നു"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"വയർലെസ്സ് കണക്ഷനിലൂടെ ചാർജ്ജുചെയ്യുന്നു"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"ചാർജ്ജുചെയ്യുന്നില്ല"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ചാർജ്ജുചെയ്യുന്നില്ല"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"നിറഞ്ഞു"</string> diff --git a/packages/SettingsLib/res/values-mn-rMN/strings.xml b/packages/SettingsLib/res/values-mn-rMN/strings.xml index d989ef86d7dc..7eeae06da0c0 100644 --- a/packages/SettingsLib/res/values-mn-rMN/strings.xml +++ b/packages/SettingsLib/res/values-mn-rMN/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Энэ функц туршилтынх бөгөөд ажиллагаанд нөлөөлж болзошгүй."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Давхарласан <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ойролцоогоор <xliff:g id="TIME">%1$s</xliff:g> үлдсэн"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ойролцоогоор <xliff:g id="TIME">%2$s</xliff:g> үлдсэн"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"АС-р дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"USB-р дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"утасгүй цэнэглэгчээр дүүртэл <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Тодорхойгүй"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Цэнэглэж байна"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC-р цэнэглэж байна"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB-р цэнэглэж байна"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Кабльгүйгээр цэнэглэж байна"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Цэнэглэхгүй байна"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Цэнэглэхгүй байна"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Дүүрэн"</string> diff --git a/packages/SettingsLib/res/values-mr-rIN/strings.xml b/packages/SettingsLib/res/values-mr-rIN/strings.xml index d363874ae69b..0521ba1a888d 100644 --- a/packages/SettingsLib/res/values-mr-rIN/strings.xml +++ b/packages/SettingsLib/res/values-mr-rIN/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"हे वैशिष्ट्य प्रायोगिक आहे आणि कदाचित कार्यप्रदर्शन प्रभावित करू शकते."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारे अधिलिखित"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"अंदाजे. <xliff:g id="TIME">%1$s</xliff:g> शिल्लक"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - अंदाजे. <xliff:g id="TIME">%2$s</xliff:g> शिल्लक"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूर्ण होण्यात"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC वरून पूर्ण होण्यात"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB वरून पूर्ण होण्यात"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> वायरलेसवरून पूर्ण होण्यात"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज होत आहे"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC वर चार्ज करीत आहे"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB वरून चार्ज करीत आहे"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"वायरलेस वरून चार्ज करीत आहे"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"चार्ज होत नाही"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज होत नाही"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string> diff --git a/packages/SettingsLib/res/values-ms-rMY/strings.xml b/packages/SettingsLib/res/values-ms-rMY/strings.xml index ea79a468bbc2..a8be0e5b9791 100644 --- a/packages/SettingsLib/res/values-ms-rMY/strings.xml +++ b/packages/SettingsLib/res/values-ms-rMY/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ciri ini adalah percubaan dan boleh menjejaskan prestasi."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Diatasi oleh <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Kira-kira <xliff:g id="TIME">%1$s</xliff:g> lagi"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - kira-kira. <xliff:g id="TIME">%2$s</xliff:g> yang tinggal"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh di AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh melalui USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> sehingga penuh dari wayarles"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Tidak diketahui"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Mengecas"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Mengecas pada AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Mengecas melalui USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Mengecas tanpa wayar"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Tidak mengecas"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Tidak mengecas"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Penuh"</string> diff --git a/packages/SettingsLib/res/values-my-rMM/strings.xml b/packages/SettingsLib/res/values-my-rMM/strings.xml index 74e0f29b809f..220deffc42f3 100644 --- a/packages/SettingsLib/res/values-my-rMM/strings.xml +++ b/packages/SettingsLib/res/values-my-rMM/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ဒီအင်္ဂါရပ်မှာ စမ်းသပ်မှု ဖြစ်၍ လုပ်ကိုင်မှုကို အကျိုးသက်ရောက်နိုင်သည်။"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> မှ ကျော်၍ လုပ်ထားသည်။"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"ခန့်မှန်းခြေ <xliff:g id="TIME">%1$s</xliff:g> ကျန်ပါသည်"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ခန့်မှန်းခြေ။ <xliff:g id="TIME">%2$s</xliff:g> ကျန်ရှိနေ"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> အပြည့်အထိ"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> လျှပ်စစ်ဖြင့် အပြည့်အထိ"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB ဖြင့် အပြည့်အထိ"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ကြိုးမဲ့ဖြင့် အပြည့်အထိ"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"အကြောင်းအရာ မသိရှိ"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"အားသွင်းနေပါသည်"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"လျှပ်စစ်ဖြင့် အားသွင်းနေ"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USBဖြင့် အားသွင်းနေ"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"ကြိုးမဲ့ အားသွင်းနေ"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"အားသွင်းမနေပါ"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"အားသွင်းမနေပါ"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"အပြည့်"</string> diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml index 1a0b4683fc82..a1407ace2d00 100644 --- a/packages/SettingsLib/res/values-nb/strings.xml +++ b/packages/SettingsLib/res/values-nb/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Denne funksjonen er eksperimentell og kan påvirke ytelsen."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overstyres av <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> gjenstår"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca. <xliff:g id="TIME">%2$s</xliff:g> igjen"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g> med vekselstrøm"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g> via USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – fulladet om <xliff:g id="TIME">%2$s</xliff:g> via trådløs lading"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Ukjent"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Lader"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Lader via strømuttak"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Lader via USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Lader trådløst"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Lader ikke"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Lader ikke"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string> diff --git a/packages/SettingsLib/res/values-ne-rNP/strings.xml b/packages/SettingsLib/res/values-ne-rNP/strings.xml index a001cab2651f..83e2e74a3b40 100644 --- a/packages/SettingsLib/res/values-ne-rNP/strings.xml +++ b/packages/SettingsLib/res/values-ne-rNP/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"यो सुविधा प्रयोगात्मक छ र प्रदर्शनमा असर गर्न सक्छ।"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> द्वारा अधिरोहित"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"लगभग <xliff:g id="TIME">%1$s</xliff:g> बाँकी छ"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - लगभग। <xliff:g id="TIME">%2$s</xliff:g> बायाँ"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> पूर्ण नभए सम्म"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC मा पूर्ण नभए सम्म"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB मा पूर्ण नभए सम्म"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> वायरलेसबाट पूर्ण नभए सम्म"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"अज्ञात"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"चार्ज हुँदै"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC मा चार्ज गर्दै"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB मा चार्ज गर्दै"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"बिना तार चार्ज गर्दै"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"चार्ज भइरहेको छैन"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"चार्ज हुँदै छैन"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"पूर्ण"</string> diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml index 301e3276a5f5..55017d837cc5 100644 --- a/packages/SettingsLib/res/values-nl/strings.xml +++ b/packages/SettingsLib/res/values-nl/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Deze functie is experimenteel en kan invloed hebben op de prestaties."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Overschreven door <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca. <xliff:g id="TIME">%1$s</xliff:g> resterend"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ca. <xliff:g id="TIME">%2$s</xliff:g> resterend"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol via wisselstroom"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol via USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> tot vol via draadloos"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Onbekend"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Opladen"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Opladen via netvoeding"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Opladen via USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Draadloos opladen"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Wordt niet opgeladen"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Wordt niet opgeladen"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Volledig"</string> diff --git a/packages/SettingsLib/res/values-pa-rIN/strings.xml b/packages/SettingsLib/res/values-pa-rIN/strings.xml index c792ec93834c..eb1eaacfbc8f 100644 --- a/packages/SettingsLib/res/values-pa-rIN/strings.xml +++ b/packages/SettingsLib/res/values-pa-rIN/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ਇਹ ਵਿਸ਼ੇਸ਼ਤਾ ਪ੍ਰਯੋਗਾਤਮਿਕ ਹੈ ਅਤੇ ਪ੍ਰਦਰਸ਼ਨ ਤੇ ਅਸਰ ਪਾ ਸਕਦੀ ਹੈ।"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ਦੁਆਰਾ ਓਵਰਰਾਈਡ ਕੀਤਾ"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"ਲਗਭਗ <xliff:g id="TIME">%1$s</xliff:g> ਬਾਕੀ"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ਲਗਭਗ <xliff:g id="TIME">%2$s</xliff:g> ਬਾਕੀ"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਪੂਰੀ ਹੋਣ ਤੱਕ"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC ਤੇ ਪੂਰਾ ਹੋਣ ਤੱਕ"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB ਤੇ ਪੂਰਾ ਹੋਣ ਤੱਕ"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> ਵਾਇਰਲੈਸ ਤੋਂ ਪੂਰਾ ਹੋਣ ਤੱਕ"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"ਅਗਿਆਤ"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"ਚਾਰਜਿੰਗ"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC ਤੇ ਚਾਰਜਿੰਗ"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB ਤੇ ਚਾਰਜਿੰਗ"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"ਵਾਇਰਲੈਸ ਤੌਰ ਤੇ ਚਾਰਜਿੰਗ"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ਚਾਰਜ ਨਹੀਂ ਹੋ ਰਿਹਾ"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"ਪੂਰੀ"</string> diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml index 8aad98b140a7..1e56cfd07b32 100644 --- a/packages/SettingsLib/res/values-pl/strings.xml +++ b/packages/SettingsLib/res/values-pl/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To jest funkcja eksperymentalna i może wpływać na działanie urządzenia."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Nadpisana przez <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Pozostało około <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostało ok. <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania z gniazdka"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania przez USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do pełnego naładowania bezprzewodowo"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Nieznane"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Ładowanie"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Ładowanie zasilaczem"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Ładowanie przez USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Ład. bezprzewodowe"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Nie podłączony"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nie podłączony"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Naładowana"</string> diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml index c05458bc4998..93f333aa9d2e 100644 --- a/packages/SettingsLib/res/values-pt-rBR/strings.xml +++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Aproximadamente <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restantes"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir em CA"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir via USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir sem fio"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Carregamento CA"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Carregamento via USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Carregamento sem fio"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Não está carregando"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string> diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml index 402bc860a7b7..dda00fe91287 100644 --- a/packages/SettingsLib/res/values-pt-rPT/strings.xml +++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Esta funcionalidade é experimental e pode afetar o desempenho."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Resta(m) aproximadamente <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – resta(m) aprox. <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar completa"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar completa através de CA"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> até ficar completa através de USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até ficar compl. por rede s/ fios"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"A carregar"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"A carregar por CA"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"A carregar por USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"A carregar sem fios"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Não está a carregar"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está a carregar"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Completo"</string> diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml index c05458bc4998..93f333aa9d2e 100644 --- a/packages/SettingsLib/res/values-pt/strings.xml +++ b/packages/SettingsLib/res/values-pt/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Este recurso é experimental e pode afetar o desempenho."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Substituído por <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Aproximadamente <xliff:g id="TIME">%1$s</xliff:g> restante(s)"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - cerca de <xliff:g id="TIME">%2$s</xliff:g> restantes"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir em CA"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir via USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> até concluir sem fio"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Desconhecido"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Carregando"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Carregamento CA"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Carregamento via USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Carregamento sem fio"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Não está carregando"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Não está carregando"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Cheio"</string> diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml index d5e07690382b..3c46d4142e4f 100644 --- a/packages/SettingsLib/res/values-ro/strings.xml +++ b/packages/SettingsLib/res/values-ro/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Această funcție este experimentală și poate afecta performanțele."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Valoare înlocuită de <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Timp rămas: aproximativ <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – timp rămas: aproximativ <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă la c.a."</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă prin USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> până la încărcare completă wireless"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Necunoscut"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Încarcă"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Se încarcă la C.A."</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Se încarcă prin USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Se încarcă fără fir"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Nu se încarcă"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nu încarcă"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Complet"</string> diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml index 7ad9f160d70e..f4929de01bc2 100644 --- a/packages/SettingsLib/res/values-ru/strings.xml +++ b/packages/SettingsLib/res/values-ru/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Это экспериментальная функция, она может снизить производительность устройства."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Новая настройка: <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Осталось примерно <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – осталось около <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки (от сети)"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки (через USB)"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до полной зарядки (беспроводная)"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Неизвестно"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Идет зарядка"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Зарядка от сети"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Зарядка через USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Беспроводная зарядка"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Не заряжается"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряжается"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Батарея заряжена"</string> diff --git a/packages/SettingsLib/res/values-si-rLK/strings.xml b/packages/SettingsLib/res/values-si-rLK/strings.xml index 4c73219f95e4..99f018bbdc5e 100644 --- a/packages/SettingsLib/res/values-si-rLK/strings.xml +++ b/packages/SettingsLib/res/values-si-rLK/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"මෙම විශේෂාංගය පරීක්ෂණාත්මක සහ ඇතැම් විට ක්රියාකාරිත්වයට බලපෑ හැක."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> මගින් ඉක්මවන ලදී"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"දළ වශයෙන් <xliff:g id="TIME">%1$s</xliff:g>ක් ඉතිරිය"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - ආසන්න <xliff:g id="TIME">%2$s</xliff:g> වම"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පුර්ණ වන තෙක්"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"AC හි <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පුර්ණ වන තෙක්"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"USB හරහ <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පුර්ණ වන තෙක්"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"රේඩියෝව වෙතින් <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> සම්පූර්ණ වන තෙක්"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"නොදනී"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"ආරෝපණය වෙමින්"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC හි ආරෝපණය වෙමින්"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB හරහා ආරෝපණය වෙමින්"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"රැහැන් රහිතව ආරෝපණය වෙමින්"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"ආරෝපණය නොවේ"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ආරෝපණය නොවෙමින්"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"පූර්ණ"</string> diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml index e5c9805fc5ae..4dffdefe6064 100644 --- a/packages/SettingsLib/res/values-sk/strings.xml +++ b/packages/SettingsLib/res/values-sk/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Funkcia je experimentálna a môže mať vplyv na výkonnosť."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Prekonané predvoľbou <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Zostáva cca. <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – zostáva približne <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia zo zásuvky"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia cez USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do úplného nabitia bezdrôtovo"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Neznáme"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Nabíjanie"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Nabíjanie zo zásuvky"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Nabíjanie cez USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Bezdrôtové nabíjanie"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Nenabíja sa"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nenabíja sa"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Nabitá"</string> diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml index 8257e3c76e48..676a3ab20331 100644 --- a/packages/SettingsLib/res/values-sl/strings.xml +++ b/packages/SettingsLib/res/values-sl/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"To je preskusna funkcija in lahko vpliva na učinkovitost delovanja."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Preglasila nastavitev: <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Še približno <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – še približno <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek napajalnika"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek USB-ja"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> do napolnjenosti prek brezž. pol."</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Neznano"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Polnjenje"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Polnj. prek iz. toka"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Polnj. prek USB-ja"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Brezžično polnjenje"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Se ne polni"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Se ne polni"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Poln"</string> diff --git a/packages/SettingsLib/res/values-sq-rAL/strings.xml b/packages/SettingsLib/res/values-sq-rAL/strings.xml index 4a673480d095..c18e63950e79 100644 --- a/packages/SettingsLib/res/values-sq-rAL/strings.xml +++ b/packages/SettingsLib/res/values-sq-rAL/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ky funksion është eksperimental dhe mund të ndikojë në veprimtari."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Mbivendosur nga <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Afërsisht <xliff:g id="TIME">%1$s</xliff:g> të mbetura"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - afërsisht <xliff:g id="TIME">%2$s</xliff:g> të mbetura"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> derisa të jetë e plotë"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> deri sa të mbushet në AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> deri sa të mbushet me USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> deri sa të mbushet nga lidhja pa tel"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"I panjohur"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Po ngarkohet"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Po ngarkohet në AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Po ngarkohet me USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Po ngarkohet me valë"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Nuk po ngarkohet"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Nuk po ngarkohet"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"E mbushur"</string> diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml index eaf7ac5464f7..c0791fcf1a5c 100644 --- a/packages/SettingsLib/res/values-sr/strings.xml +++ b/packages/SettingsLib/res/values-sr/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ова функција је експериментална и може да утиче на перформансе."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замењује га <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Још отприлике <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – преостало око <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни пуњачем"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни преко USB-а"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> док се не напуни бежично"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Непознато"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Пуњење"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Пуњење преко пуњача"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Пуњење преко USB-а"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Бежично пуњење"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Не пуни се"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не пуни се"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Пуно"</string> diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml index b01967260807..60c42a53c98f 100644 --- a/packages/SettingsLib/res/values-sv/strings.xml +++ b/packages/SettingsLib/res/values-sv/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Den här funktionen är experimentell och kan påverka prestandan."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Har åsidosatts av <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Ca <xliff:g id="TIME">%1$s</xliff:g> kvar"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – ca <xliff:g id="TIME">%2$s</xliff:g> kvar"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat via laddare"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat via USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> till fulladdat via trådlös laddning"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Okänd"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Laddar"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Laddas via adapter"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Laddas via USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Laddas trådlöst"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Laddar inte"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Laddar inte"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Fullt"</string> diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml index 3daa90f70ad8..5de7686e0067 100644 --- a/packages/SettingsLib/res/values-sw/strings.xml +++ b/packages/SettingsLib/res/values-sw/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Kipengele hiki ni cha majaribio na huenda kikaathiri utendaji."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Imetanguliwa na <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Zimesalia takribani <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia takriban <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae kwa kutumia AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g>%% - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae kwa kutumia USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - imesalia <xliff:g id="TIME">%2$s</xliff:g> hadi ijae kwa isiyotumia waya"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Haijulikani"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Inachaji"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Inachaji kupitia AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Inachaji kupitia USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Inachaji bila kutumia waya"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Haichaji"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Haichaji"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Imejaa"</string> diff --git a/packages/SettingsLib/res/values-ta-rIN/strings.xml b/packages/SettingsLib/res/values-ta-rIN/strings.xml index 574d105fdd50..a5f04d090291 100644 --- a/packages/SettingsLib/res/values-ta-rIN/strings.xml +++ b/packages/SettingsLib/res/values-ta-rIN/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"இது சோதனை முறையிலான அம்சம், இது செயல்திறனைப் பாதிக்கலாம்."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> மூலம் மேலெழுதப்பட்டது"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"தோராயமாக <xliff:g id="TIME">%1$s</xliff:g> உள்ளது"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"தோராயம்: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> உள்ளது"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"முழு சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"முழு AC சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"முழு USB சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"முழு வயர்லெஸ் சார்ஜிற்கு: <xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"அறியப்படாத"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"சார்ஜ் ஏற்றப்படுகிறது"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC மூலம் சார்ஜாகிறது"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB மூலம் சார்ஜாகிறது"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"வயர்லெஸில் சார்ஜாகிறது"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"சார்ஜ் செய்யப்படவில்லை"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"சார்ஜ் ஏறவில்லை"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"முழுமை"</string> diff --git a/packages/SettingsLib/res/values-te-rIN/strings.xml b/packages/SettingsLib/res/values-te-rIN/strings.xml index 238911264f47..fe40766aa36e 100644 --- a/packages/SettingsLib/res/values-te-rIN/strings.xml +++ b/packages/SettingsLib/res/values-te-rIN/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"ఈ లక్షణం ప్రయోగాత్మకమైనది మరియు పనితీరుపై ప్రభావం చూపవచ్చు."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> ద్వారా భర్తీ చేయబడింది"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"సుమారు <xliff:g id="TIME">%1$s</xliff:g> మిగిలి ఉంది"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - సుమారు <xliff:g id="TIME">%2$s</xliff:g> మిగిలి ఉంది"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - ACలో పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB ద్వారా పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - వైర్లెస్ నుండి పూర్తిగా నిండటానికి <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"తెలియదు"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"ఛార్జ్ అవుతోంది"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"ACలో ఛార్జ్ అవుతోంది"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB ద్వారా ఛార్జ్ అవుతోంది"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"వైర్లెస్ ద్వారా ఛార్జ్ అవుతోంది"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"ఛార్జ్ కావడం లేదు"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ఛార్జ్ కావడం లేదు"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"నిండింది"</string> diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml index 0f6f78cb2417..c58692f46411 100644 --- a/packages/SettingsLib/res/values-th/strings.xml +++ b/packages/SettingsLib/res/values-th/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"คุณลักษณะนี้เป็นแบบทดลองและอาจส่งผลต่อประสิทธิภาพการทำงาน"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"แทนที่โดย <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"เหลืออีกประมาณ <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - เหลือประมาณ <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็ม"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็มเมื่อชาร์จผ่าน AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็มเมื่อชาร์จผ่าน USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> จนกว่าจะเต็มเมื่อชาร์จผ่านระบบไร้สาย"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"ไม่ทราบ"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"กำลังชาร์จ"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"กำลังชาร์จไฟ AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"กำลังชาร์จผ่าน USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"กำลังชาร์จแบบไร้สาย"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"ไม่ได้ชาร์จ"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"ไม่ได้ชาร์จ"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"เต็ม"</string> diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml index ef3dde79a0dd..093256c6ef3c 100644 --- a/packages/SettingsLib/res/values-tl/strings.xml +++ b/packages/SettingsLib/res/values-tl/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Ang feature na ito ay pinag-eeksperimentuhan at maaaring makaapekto sa pagganap."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Na-override ng <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Humigit-kumulang <xliff:g id="TIME">%1$s</xliff:g> na lang ang natitira"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - humigit kumulang <xliff:g id="TIME">%2$s</xliff:g> ang natitira"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno sa AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno sa USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> bago mapuno mula sa wireless"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Hindi Kilala"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Nagcha-charge"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Nagcha-charge sa AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Nagcha-charge sa USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Wireless nag-charge"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Hindi nagcha-charge"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hindi nagkakarga"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Puno"</string> diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml index 4b7490d700f0..1947d39776a1 100644 --- a/packages/SettingsLib/res/values-tr/strings.xml +++ b/packages/SettingsLib/res/values-tr/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu özellik deneyseldir ve performansı etkileyebilir."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> tarafından geçersiz kılındı"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Yaklaşık <xliff:g id="TIME">%1$s</xliff:g> kaldı"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - yaklaşık <xliff:g id="TIME">%2$s</xliff:g> kaldı"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - prize takılı, tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - USB üzerinden şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - kablosuzdan tam şarj olmasına <xliff:g id="TIME">%2$s</xliff:g> var"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Bilinmiyor"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Şarj oluyor"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC ile şarj oluyor"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB ile şarj oluyor"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Kablosuz şarj oluyor"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Şarj olmuyor"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Şarj etmiyor"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Dolu"</string> diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml index 5e044c3b2839..0ed6cc0b93ad 100644 --- a/packages/SettingsLib/res/values-uk/strings.xml +++ b/packages/SettingsLib/res/values-uk/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Це експериментальна функція. Вона може вплинути на продуктивність."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Замінено на <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Залишилося приблизно <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – залишилось близько <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного зарядження"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного зарядження з розетки"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного зарядження через USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g> до повного з бездротового зарядження"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Невідомо"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Зарядж-ся"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Заряджання з розетки"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Заряджання через USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Заряджання без дроту"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Не заряджається"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Не заряджається"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Акумулятор заряджено"</string> diff --git a/packages/SettingsLib/res/values-ur-rPK/strings.xml b/packages/SettingsLib/res/values-ur-rPK/strings.xml index 6d3c6c4c037f..99a0f2becfcf 100644 --- a/packages/SettingsLib/res/values-ur-rPK/strings.xml +++ b/packages/SettingsLib/res/values-ur-rPK/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"یہ خصوصیت تجرباتی ہے اور اس کی وجہ سے کاکردگی متاثر ہو سکتی ہے۔"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> کے ذریعہ منسوخ کردیا گیا"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"تقریبا <xliff:g id="TIME">%1$s</xliff:g> باقی ہیں"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - تقریبا <xliff:g id="TIME">%2$s</xliff:g> باقی"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> پورا ہونے تک"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> AC پر پورا ہونے تک"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> USB پر پورا ہونے تک"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> وائرلیس سے پورا ہونے تک"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"نامعلوم"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"چارج ہو رہا ہے"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"AC پر چارج ہو رہی ہے"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"USB پر چارج ہورہی ہے"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"وائرلیس چارجنگ"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"چارج نہیں ہو رہا ہے"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"چارج نہیں ہو رہا ہے"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"مکمل"</string> diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml index ec04120f9f03..b9c024351fd9 100644 --- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml +++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Bu funksiya tajribaviy bo‘lib, u qurilma unumdorligiga ta’sir qilishi mumkin."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"<xliff:g id="TITLE">%1$s</xliff:g> bilan almashtirildi"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Taxminan <xliff:g id="TIME">%1$s</xliff:g> qoldi"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> – taxminan <xliff:g id="TIME">%2$s</xliff:g> qoldi"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, to‘lguncha"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, o‘zgaruvchan tok orqali to‘lguncha"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, USB orqali to‘lguncha"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> – <xliff:g id="TIME">%2$s</xliff:g>, simsiz quvvatlash orqali to‘lguncha"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Noma’lum"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Quvvat olmoqda"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Quvvat olmoqda (AC)"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Quvvat olmoqda (USB)"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Simsiz quvvat olmoqda"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Quvvat olmayapti"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Quvvatlanmayapti"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"To‘la"</string> diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml index dd1d482c4ca0..0c3dc899ce32 100644 --- a/packages/SettingsLib/res/values-vi/strings.xml +++ b/packages/SettingsLib/res/values-vi/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Tính năng này là tính năng thử nghiệm và có thể ảnh hưởng đến hoạt động."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Bị ghi đè bởi <xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Còn khoảng <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - còn khoảng <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy khi cắm vào nguồn AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy qua USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> cho đến khi đầy từ không dây"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Không xác định"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Đang sạc"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Sạc trên AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Sạc qua USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Sạc không dây"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Hiện không sạc"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Hiện không sạc"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Đầy"</string> diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml index 4117ae143f84..2b8ce652fc93 100644 --- a/packages/SettingsLib/res/values-zh-rCN/strings.xml +++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"此功能为实验性功能,可能会影响性能。"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已被“<xliff:g id="TITLE">%1$s</xliff:g>”覆盖"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"还剩大约 <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还可用大约<xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满(交流电充电)"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满(USB充电)"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - 还需<xliff:g id="TIME">%2$s</xliff:g>充满(无线充电)"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"未知"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"正在充电"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"正在通过交流电源充电"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"正在通过USB充电"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"正在无线充电"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"未在充电"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"未在充电"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"电量充足"</string> diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml index 1fb4c5ea7f49..8dd0417846d1 100644 --- a/packages/SettingsLib/res/values-zh-rHK/strings.xml +++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會影響效能。"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已由「<xliff:g id="TITLE">%1$s</xliff:g>」覆寫"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"尚餘大約 <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 尚餘大約 <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電 (透過插頭充電)"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電 (透過 USB 充電)"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> 後完成充電 (無線充電)"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"未知"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"正在透過 AC 充電"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"正在透過 USB 充電"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"正在透過無線方式充電"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"非充電中"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"未開始充電"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"電量已滿"</string> diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml index 9c85f0e54952..dd59954d3ffa 100644 --- a/packages/SettingsLib/res/values-zh-rTW/strings.xml +++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"這是一項實驗性功能,可能會對效能造成影響。"</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"已改為<xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"還剩大約 <xliff:g id="TIME">%1$s</xliff:g>"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - 大約還剩 <xliff:g id="TIME">%2$s</xliff:g>"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (AC)"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (USB)"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g>後充飽 (無線充電)"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"不明"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"充電中"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"正在透過 AC 變壓器充電"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"正在透過 USB 充電"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"正在透過無線方式充電"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"非充電中"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"非充電中"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"電力充足"</string> diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml index 6017d68bfb37..610cac477886 100644 --- a/packages/SettingsLib/res/values-zu/strings.xml +++ b/packages/SettingsLib/res/values-zu/strings.xml @@ -296,17 +296,35 @@ <string name="accessibility_display_daltonizer_preference_subtitle" msgid="3484969015295282911">"Lesi sici esesilingo futhi singathinta ukusebenza."</string> <string name="daltonizer_type_overridden" msgid="3116947244410245916">"Igitshezwe ngaphezulu yi-<xliff:g id="TITLE">%1$s</xliff:g>"</string> <string name="power_remaining_duration_only" msgid="4400068916452346544">"Cishe ngu-<xliff:g id="TIME">%1$s</xliff:g> osele"</string> + <!-- no translation found for power_remaining_duration_only_short (5329694252258605547) --> + <skip /> <string name="power_discharging_duration" msgid="1605929174734600590">"<xliff:g id="LEVEL">%1$s</xliff:g> - isilinganiso esingu-<xliff:g id="TIME">%2$s</xliff:g> esisele"</string> + <!-- no translation found for power_discharging_duration_short (4192244429001842403) --> + <skip /> <string name="power_charging" msgid="1779532561355864267">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string> <string name="power_charging_duration" msgid="2853265177761520490">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale"</string> + <!-- no translation found for power_charging_duration_short (1098603958472207920) --> + <skip /> <string name="power_charging_duration_ac" msgid="3969186192576594254">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale ku-AC"</string> + <!-- no translation found for power_charging_duration_ac_short (7895864687218765582) --> + <skip /> <string name="power_charging_duration_usb" msgid="182405645340976546">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale ngaphezulu kwe-USB"</string> + <!-- no translation found for power_charging_duration_usb_short (941854728040426399) --> + <skip /> <string name="power_charging_duration_wireless" msgid="1829295708243159464">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> kuze igcwale kusukela kokungenantambo"</string> + <!-- no translation found for power_charging_duration_wireless_short (1642664799869599476) --> + <skip /> <string name="battery_info_status_unknown" msgid="196130600938058547">"Akwaziwa"</string> <string name="battery_info_status_charging" msgid="1705179948350365604">"Iyashaja"</string> <string name="battery_info_status_charging_ac" msgid="2909861890674399949">"Iyashaja ku-AC"</string> + <!-- no translation found for battery_info_status_charging_ac_short (7431401092096415502) --> + <skip /> <string name="battery_info_status_charging_usb" msgid="2207489369680923929">"Iyashaja ngaphezulu kwe-USB"</string> + <!-- no translation found for battery_info_status_charging_usb_short (6733371990319101366) --> + <skip /> <string name="battery_info_status_charging_wireless" msgid="3574032603735446573">"Iyashaja ngaphandle kwentambo"</string> + <!-- no translation found for battery_info_status_charging_wireless_short (752569941028903610) --> + <skip /> <string name="battery_info_status_discharging" msgid="310932812698268588">"Ayishaji"</string> <string name="battery_info_status_not_charging" msgid="2820070506621483576">"Ayishaji"</string> <string name="battery_info_status_full" msgid="2824614753861462808">"Kugcwele"</string> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index fe3ef1a9b76b..a560e3c52107 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -733,25 +733,44 @@ <!-- [CHAR_LIMIT=40] Label for estimated remaining duration of battery charging/discharging --> <string name="power_remaining_duration_only">Approx. <xliff:g id="time">%1$s</xliff:g> left</string> + <!-- [CHAR_LIMIT=40] Short label for estimated remaining duration of battery charging/discharging --> + <string name="power_remaining_duration_only_short"><xliff:g id="time">%1$s</xliff:g> left</string> + <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration --> <string name="power_discharging_duration"><xliff:g id="level">%1$s</xliff:g> - approx. <xliff:g id="time">%2$s</xliff:g> left</string> + <!-- [CHAR_LIMIT=40] Label for battery level chart when discharging with duration --> + <string name="power_discharging_duration_short"><xliff:g id="level">%1$s</xliff:g> + - <xliff:g id="time">%2$s</xliff:g> left</string> + <!-- [CHAR_LIMIT=40] Label for battery level chart when charging --> <string name="power_charging"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="state">%2$s</xliff:g></string> <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration --> <string name="power_charging_duration"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> until full</string> + <!-- [CHAR_LIMIT=40] Short label for battery level chart when charging with duration --> + <string name="power_charging_duration_short"><xliff:g id="level">%1$s</xliff:g> - + <xliff:g id="time">%2$s</xliff:g></string> <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration --> <string name="power_charging_duration_ac"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> until full on AC</string> + <!-- [CHAR_LIMIT=40] Short label for battery level chart when charging with duration --> + <string name="power_charging_duration_ac_short"><xliff:g id="level">%1$s</xliff:g> - + <xliff:g id="time">%2$s</xliff:g></string> <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration --> <string name="power_charging_duration_usb"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> until full over USB</string> + <!-- [CHAR_LIMIT=40] Short label for battery level chart when charging with duration --> + <string name="power_charging_duration_usb_short"><xliff:g id="level">%1$s</xliff:g> - + <xliff:g id="time">%2$s</xliff:g></string> <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration --> <string name="power_charging_duration_wireless"><xliff:g id="level">%1$s</xliff:g> - <xliff:g id="time">%2$s</xliff:g> until full from wireless</string> + <!-- [CHAR_LIMIT=40] Label for battery level chart when charging with duration --> + <string name="power_charging_duration_wireless_short"><xliff:g id="level">%1$s</xliff:g> - + <xliff:g id="time">%2$s</xliff:g></string> <!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed --> <string name="battery_info_status_unknown">Unknown</string> @@ -759,10 +778,16 @@ <string name="battery_info_status_charging">Charging</string> <!-- [CHAR_LIMIT=20] Battery use screen. Battery status shown in chart label when charging on AC. --> <string name="battery_info_status_charging_ac">Charging on AC</string> + <!-- [CHAR_LIMIT=20] Battery short status label when charing on AC --> + <string name="battery_info_status_charging_ac_short">Charging</string> <!-- [CHAR_LIMIT=20] Battery use screen. Battery status shown in chart label when charging over USB. --> <string name="battery_info_status_charging_usb">Charging over USB</string> + <!-- [CHAR_LIMIT=20] Battery short status label when charging over USB. --> + <string name="battery_info_status_charging_usb_short">Charging</string> <!-- [CHAR_LIMIT=20] Battery use screen. Battery status shown in chart label when charging over a wireless connection. --> <string name="battery_info_status_charging_wireless">Charging wirelessly</string> + <!-- [CHAR_LIMIT=20] Battery short status label when charging wirelessly. --> + <string name="battery_info_status_charging_wireless_short">Charging</string> <!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed --> <string name="battery_info_status_discharging">Not charging</string> <!-- Battery Info screen. Value for a status item. Used for diagnostic info screens, precise translation isn't needed --> diff --git a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java index 6b29e2165c54..fa1f91fe9fbc 100644 --- a/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java +++ b/packages/SettingsLib/src/com/android/settingslib/BatteryInfo.java @@ -25,6 +25,7 @@ import android.os.BatteryStats.HistoryItem; import android.os.Bundle; import android.os.SystemClock; import android.text.format.Formatter; +import android.util.Log; import android.util.SparseIntArray; import com.android.internal.os.BatteryStatsHelper; import com.android.settingslib.graph.UsageView; @@ -95,6 +96,11 @@ public class BatteryInfo { } public static void getBatteryInfo(final Context context, final Callback callback) { + BatteryInfo.getBatteryInfo(context, callback, false); + } + + public static void getBatteryInfo(final Context context, final Callback callback, + boolean shortString) { new AsyncTask<Void, Void, BatteryStats>() { @Override protected BatteryStats doInBackground(Void... params) { @@ -109,14 +115,20 @@ public class BatteryInfo { Intent batteryBroadcast = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)); BatteryInfo batteryInfo = BatteryInfo.getBatteryInfo(context, - batteryBroadcast, batteryStats, elapsedRealtimeUs); + batteryBroadcast, batteryStats, elapsedRealtimeUs, shortString); callback.onBatteryInfoLoaded(batteryInfo); } }.execute(); } public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast, - BatteryStats stats, long elapsedRealtimeUs) { + BatteryStats stats, long elapsedRealtimeUs) { + return BatteryInfo.getBatteryInfo(context, batteryBroadcast, stats, elapsedRealtimeUs, + false); + } + + public static BatteryInfo getBatteryInfo(Context context, Intent batteryBroadcast, + BatteryStats stats, long elapsedRealtimeUs, boolean shortString) { BatteryInfo info = new BatteryInfo(); info.mStats = stats; info.mBatteryLevel = Utils.getBatteryLevel(batteryBroadcast); @@ -129,9 +141,13 @@ public class BatteryInfo { info.remainingTimeUs = drainTime; String timeString = Formatter.formatShortElapsedTime(context, drainTime / 1000); - info.remainingLabel = resources.getString(R.string.power_remaining_duration_only, + info.remainingLabel = resources.getString( + shortString ? R.string.power_remaining_duration_only_short + : R.string.power_remaining_duration_only, timeString); - info.mChargeLabelString = resources.getString(R.string.power_discharging_duration, + info.mChargeLabelString = resources.getString( + shortString ? R.string.power_discharging_duration_short + : R.string.power_discharging_duration, info.batteryPercentString, timeString); } else { info.remainingLabel = null; @@ -140,7 +156,7 @@ public class BatteryInfo { } else { final long chargeTime = stats.computeChargeTimeRemaining(elapsedRealtimeUs); final String statusLabel = Utils.getBatteryStatus( - resources, batteryBroadcast); + resources, batteryBroadcast, shortString); final int status = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_UNKNOWN); if (chargeTime > 0 && status != BatteryManager.BATTERY_STATUS_FULL) { @@ -151,13 +167,17 @@ public class BatteryInfo { int plugType = batteryBroadcast.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0); int resId; if (plugType == BatteryManager.BATTERY_PLUGGED_AC) { - resId = R.string.power_charging_duration_ac; + resId = shortString ? R.string.power_charging_duration_ac_short + : R.string.power_charging_duration_ac; } else if (plugType == BatteryManager.BATTERY_PLUGGED_USB) { - resId = R.string.power_charging_duration_usb; + resId = shortString ? R.string.power_charging_duration_usb_short + : R.string.power_charging_duration_usb; } else if (plugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) { - resId = R.string.power_charging_duration_wireless; + resId = shortString ? R.string.power_charging_duration_wireless_short + : R.string.power_charging_duration_wireless; } else { - resId = R.string.power_charging_duration; + resId = shortString ? R.string.power_charging_duration_short + : R.string.power_charging_duration; } info.remainingLabel = resources.getString(R.string.power_remaining_duration_only, timeString); diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java index e86ca82bf215..59637bee2e87 100644 --- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java @@ -459,58 +459,40 @@ public class RestrictedLockUtils { LockPatternUtils lockPatternUtils = new LockPatternUtils(context); EnforcedAdmin enforcedAdmin = null; final int userId = UserHandle.myUserId(); - if (lockPatternUtils.isSeparateProfileChallengeEnabled(userId)) { - // userId is managed profile and has a separate challenge, only consider - // the admins in that user. - final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userId); + final UserManager um = UserManager.get(context); + final List<UserInfo> profiles = um.getProfiles(userId); + final int profilesSize = profiles.size(); + // As we do not have a separate screen lock timeout settings for work challenge, + // we need to combine all profiles maximum time to lock even work challenge is + // enabled. + for (int i = 0; i < profilesSize; i++) { + final UserInfo userInfo = profiles.get(i); + final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id); if (admins == null) { - return null; + continue; } for (ComponentName admin : admins) { - if (dpm.getMaximumTimeToLock(admin, userId) > 0) { + if (dpm.getMaximumTimeToLock(admin, userInfo.id) > 0) { if (enforcedAdmin == null) { - enforcedAdmin = new EnforcedAdmin(admin, userId); + enforcedAdmin = new EnforcedAdmin(admin, userInfo.id); } else { return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; } - } - } - } else { - // Return all admins for this user and the profiles that are visible from this - // user that do not use a separate work challenge. - final UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE); - for (UserInfo userInfo : um.getProfiles(userId)) { - final List<ComponentName> admins = dpm.getActiveAdminsAsUser(userInfo.id); - if (admins == null) { + // This same admins could have set policies both on the managed profile + // and on the parent. So, if the admin has set the policy on the + // managed profile here, we don't need to further check if that admin + // has set policy on the parent admin. continue; } - final boolean isSeparateProfileChallengeEnabled = - lockPatternUtils.isSeparateProfileChallengeEnabled(userInfo.id); - for (ComponentName admin : admins) { - if (!isSeparateProfileChallengeEnabled) { - if (dpm.getMaximumTimeToLock(admin, userInfo.id) > 0) { - if (enforcedAdmin == null) { - enforcedAdmin = new EnforcedAdmin(admin, userInfo.id); - } else { - return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; - } - // This same admins could have set policies both on the managed profile - // and on the parent. So, if the admin has set the policy on the - // managed profile here, we don't need to further check if that admin - // has set policy on the parent admin. - continue; - } - } - if (userInfo.isManagedProfile()) { - // If userInfo.id is a managed profile, we also need to look at - // the policies set on the parent. - DevicePolicyManager parentDpm = dpm.getParentProfileInstance(userInfo); - if (parentDpm.getMaximumTimeToLock(admin, userInfo.id) > 0) { - if (enforcedAdmin == null) { - enforcedAdmin = new EnforcedAdmin(admin, userInfo.id); - } else { - return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; - } + if (userInfo.isManagedProfile()) { + // If userInfo.id is a managed profile, we also need to look at + // the policies set on the parent. + final DevicePolicyManager parentDpm = dpm.getParentProfileInstance(userInfo); + if (parentDpm.getMaximumTimeToLock(admin, userInfo.id) > 0) { + if (enforcedAdmin == null) { + enforcedAdmin = new EnforcedAdmin(admin, userInfo.id); + } else { + return EnforcedAdmin.MULTIPLE_ENFORCED_ADMIN; } } } diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java index 74c1ebdd2a79..586f2690ba1f 100644 --- a/packages/SettingsLib/src/com/android/settingslib/Utils.java +++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java @@ -112,20 +112,26 @@ public class Utils { } public static String getBatteryStatus(Resources res, Intent batteryChangedIntent) { - final Intent intent = batteryChangedIntent; + return Utils.getBatteryStatus(res, batteryChangedIntent, false); + } - int plugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0); - int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, + public static String getBatteryStatus(Resources res, Intent batteryChangedIntent, + boolean shortString) { + int plugType = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0); + int status = batteryChangedIntent.getIntExtra(BatteryManager.EXTRA_STATUS, BatteryManager.BATTERY_STATUS_UNKNOWN); String statusString; if (status == BatteryManager.BATTERY_STATUS_CHARGING) { int resId; if (plugType == BatteryManager.BATTERY_PLUGGED_AC) { - resId = R.string.battery_info_status_charging_ac; + resId = shortString ? R.string.battery_info_status_charging_ac_short + : R.string.battery_info_status_charging_ac; } else if (plugType == BatteryManager.BATTERY_PLUGGED_USB) { - resId = R.string.battery_info_status_charging_usb; + resId = shortString ? R.string.battery_info_status_charging_usb_short + : R.string.battery_info_status_charging_usb; } else if (plugType == BatteryManager.BATTERY_PLUGGED_WIRELESS) { - resId = R.string.battery_info_status_charging_wireless; + resId = shortString ? R.string.battery_info_status_charging_wireless_short + : R.string.battery_info_status_charging_wireless; } else { resId = R.string.battery_info_status_charging; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java index aa95be27ea52..d7c9eab6074b 100755 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/PbapClientProfile.java @@ -144,7 +144,9 @@ final class PbapClientProfile implements LocalBluetoothProfile { return true; } } - mService.disconnect(device); + for (BluetoothDevice src : srcs) { + mService.disconnect(device); + } } Log.d(TAG,"PBAPClientProfile attempting to connect to " + device.getAddress()); diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java index c131fa5d547c..7ca76141a84c 100644 --- a/packages/Shell/src/com/android/shell/BugreportProgressService.java +++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java @@ -463,7 +463,6 @@ public class BugreportProgressService extends Service { .setContentTitle(title) .setTicker(title) .setContentText(name) - .setContentInfo(percentageText) .setProgress(info.max, info.progress, false) .setOngoing(true) .setContentIntent(infoPendingIntent) @@ -958,7 +957,7 @@ public class BugreportProgressService extends Service { .setDeleteIntent(newCancelIntent(context, info)); if (!TextUtils.isEmpty(info.name)) { - builder.setContentInfo(info.name); + builder.setSubText(info.name); } Log.v(TAG, "Sending 'Share' notification for ID " + info.id + ": " + title); diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 983944628bd9..9e2442cc2357 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -184,6 +184,14 @@ android:exported="true" /> + <!-- Recents depends on every user having their own SystemUI process, so on user switch, + ensure that the process is created by starting this service. + --> + <service android:name="SystemUISecondaryUserService" + android:exported="true" + android:permission="com.android.systemui.permission.SELF" /> + + <!-- started from PhoneWindowManager TODO: Should have an android:permission attribute --> <service android:name=".screenshot.TakeScreenshotService" @@ -366,7 +374,6 @@ android:name="com.android.systemui.tv.pip.PipOverlayActivity" android:exported="true" android:theme="@style/PipTheme" - android:launchMode="singleTop" android:taskAffinity="" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation" android:resizeableActivity="true" diff --git a/packages/SystemUI/res/drawable/ic_ksh_key_backspace.xml b/packages/SystemUI/res/drawable/ic_ksh_key_backspace.xml new file mode 100644 index 000000000000..6519673de871 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_ksh_key_backspace.xml @@ -0,0 +1,27 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2016 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. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path android:pathData="M0 0h24v24H0z" /> + <path android:fillColor="@color/ksh_key_item_color" + android:pathData="M22 3H7c-.69 0-1.23 .35 -1.59 .88 L0 12l5.41 8.11c.36 .53 .9 .89 +1.59 .89 h15c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm-3 12.59L17.59 17 14 13.41 10.41 17 9 15.59 +12.59 12 9 8.41 10.41 7 14 10.59 17.59 7 19 8.41 15.41 12 19 15.59z" /> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_ksh_key_down.xml b/packages/SystemUI/res/drawable/ic_ksh_key_down.xml new file mode 100644 index 000000000000..25a2560c938b --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_ksh_key_down.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2016 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 + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path android:fillColor="@color/ksh_key_item_color" + android:pathData="M7.41 7.84L12 12.42l4.59-4.58L18 9.25l-6 6-6-6z" /> + <path android:pathData="M0-.75h24v24H0z" /> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_ksh_key_enter.xml b/packages/SystemUI/res/drawable/ic_ksh_key_enter.xml new file mode 100644 index 000000000000..599f35001293 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_ksh_key_enter.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2016 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 + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path android:pathData="M0 0h24v24H0z" /> + <path android:fillColor="@color/ksh_key_item_color" + android:pathData="M19 7v4H5.83l3.58-3.59L8 6l-6 6 6 6 1.41-1.41L5.83 13H21V7z" /> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_ksh_key_left.xml b/packages/SystemUI/res/drawable/ic_ksh_key_left.xml new file mode 100644 index 000000000000..038187e86acb --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_ksh_key_left.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2016 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 + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path android:fillColor="@color/ksh_key_item_color" + android:pathData="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z" /> + <path android:pathData="M0 0h24v24H0z" /> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_ksh_key_meta.xml b/packages/SystemUI/res/drawable/ic_ksh_key_meta.xml new file mode 100644 index 000000000000..1e2195edaf21 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_ksh_key_meta.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2016 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 + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path android:fillColor="@color/ksh_key_item_color" + android:pathData="M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 +3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27 .28 v.79l5 4.99L20.49 +19l-4.99-5zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 +14z" /> + <path android:pathData="M0 0h24v24H0z" /> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_ksh_key_right.xml b/packages/SystemUI/res/drawable/ic_ksh_key_right.xml new file mode 100644 index 000000000000..f2d73150705a --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_ksh_key_right.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2016 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 + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path android:fillColor="@color/ksh_key_item_color" + android:pathData="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z" /> + <path android:pathData="M0 0h24v24H0z" /> +</vector> diff --git a/packages/SystemUI/res/drawable/ic_ksh_key_up.xml b/packages/SystemUI/res/drawable/ic_ksh_key_up.xml new file mode 100644 index 000000000000..36a83b1d1e82 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_ksh_key_up.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + ~ Copyright (C) 2016 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 + --> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path android:fillColor="@color/ksh_key_item_color" + android:pathData="M7.41 15.41L12 10.83l4.59 4.58L18 14l-6-6-6 6z" /> + <path android:pathData="M0 0h24v24H0z" /> +</vector> diff --git a/packages/SystemUI/res/drawable/tv_pip_close_button.xml b/packages/SystemUI/res/drawable/tv_pip_close_button.xml index 86fda0d31346..186a4bae8942 100644 --- a/packages/SystemUI/res/drawable/tv_pip_close_button.xml +++ b/packages/SystemUI/res/drawable/tv_pip_close_button.xml @@ -19,8 +19,20 @@ <item android:state_focused="true"> <layer-list> <item android:drawable="@drawable/tv_pip_button_focused" /> - <item android:drawable="@drawable/ic_close_white" /> + <item android:drawable="@drawable/ic_close_white" + android:top="@dimen/tv_pip_button_icon_padding" + android:bottom="@dimen/tv_pip_button_icon_padding" + android:left="@dimen/tv_pip_button_icon_padding" + android:right="@dimen/tv_pip_button_icon_padding" /> + </layer-list> + </item> + <item> + <layer-list> + <item android:drawable="@drawable/ic_close_white" + android:top="@dimen/tv_pip_button_icon_padding" + android:bottom="@dimen/tv_pip_button_icon_padding" + android:left="@dimen/tv_pip_button_icon_padding" + android:right="@dimen/tv_pip_button_icon_padding" /> </layer-list> </item> - <item android:drawable="@drawable/ic_close_white" /> </selector> diff --git a/packages/SystemUI/res/drawable/tv_pip_full_button.xml b/packages/SystemUI/res/drawable/tv_pip_full_button.xml index 332c669de154..c48dc8287546 100644 --- a/packages/SystemUI/res/drawable/tv_pip_full_button.xml +++ b/packages/SystemUI/res/drawable/tv_pip_full_button.xml @@ -19,8 +19,20 @@ <item android:state_focused="true"> <layer-list> <item android:drawable="@drawable/tv_pip_button_focused" /> - <item android:drawable="@drawable/ic_fullscreen_white_24dp" /> + <item android:drawable="@drawable/ic_fullscreen_white_24dp" + android:top="@dimen/tv_pip_button_icon_padding" + android:bottom="@dimen/tv_pip_button_icon_padding" + android:left="@dimen/tv_pip_button_icon_padding" + android:right="@dimen/tv_pip_button_icon_padding" /> + </layer-list> + </item> + <item> + <layer-list> + <item android:drawable="@drawable/ic_fullscreen_white_24dp" + android:top="@dimen/tv_pip_button_icon_padding" + android:bottom="@dimen/tv_pip_button_icon_padding" + android:left="@dimen/tv_pip_button_icon_padding" + android:right="@dimen/tv_pip_button_icon_padding" /> </layer-list> </item> - <item android:drawable="@drawable/ic_fullscreen_white_24dp" /> </selector> diff --git a/packages/SystemUI/res/drawable/tv_pip_pause_button.xml b/packages/SystemUI/res/drawable/tv_pip_pause_button.xml index d277b07c199e..bcc89739474a 100644 --- a/packages/SystemUI/res/drawable/tv_pip_pause_button.xml +++ b/packages/SystemUI/res/drawable/tv_pip_pause_button.xml @@ -19,8 +19,20 @@ <item android:state_focused="true"> <layer-list> <item android:drawable="@drawable/tv_pip_button_focused" /> - <item android:drawable="@drawable/ic_pause_white_24dp" /> + <item android:drawable="@drawable/ic_pause_white_24dp" + android:top="@dimen/tv_pip_button_icon_padding" + android:bottom="@dimen/tv_pip_button_icon_padding" + android:left="@dimen/tv_pip_button_icon_padding" + android:right="@dimen/tv_pip_button_icon_padding" /> + </layer-list> + </item> + <item> + <layer-list> + <item android:drawable="@drawable/ic_pause_white_24dp" + android:top="@dimen/tv_pip_button_icon_padding" + android:bottom="@dimen/tv_pip_button_icon_padding" + android:left="@dimen/tv_pip_button_icon_padding" + android:right="@dimen/tv_pip_button_icon_padding" /> </layer-list> </item> - <item android:drawable="@drawable/ic_pause_white_24dp" /> </selector> diff --git a/packages/SystemUI/res/drawable/tv_pip_play_button.xml b/packages/SystemUI/res/drawable/tv_pip_play_button.xml index fecdc095dac4..f77ea1df1c53 100644 --- a/packages/SystemUI/res/drawable/tv_pip_play_button.xml +++ b/packages/SystemUI/res/drawable/tv_pip_play_button.xml @@ -19,8 +19,20 @@ <item android:state_focused="true"> <layer-list> <item android:drawable="@drawable/tv_pip_button_focused" /> - <item android:drawable="@drawable/ic_play_arrow_white_24dp" /> + <item android:drawable="@drawable/ic_play_arrow_white_24dp" + android:top="@dimen/tv_pip_button_icon_padding" + android:bottom="@dimen/tv_pip_button_icon_padding" + android:left="@dimen/tv_pip_button_icon_padding" + android:right="@dimen/tv_pip_button_icon_padding" /> + </layer-list> + </item> + <item> + <layer-list> + <item android:drawable="@drawable/ic_play_arrow_white_24dp" + android:top="@dimen/tv_pip_button_icon_padding" + android:bottom="@dimen/tv_pip_button_icon_padding" + android:left="@dimen/tv_pip_button_icon_padding" + android:right="@dimen/tv_pip_button_icon_padding" /> </layer-list> </item> - <item android:drawable="@drawable/ic_play_arrow_white_24dp" /> </selector> diff --git a/packages/SystemUI/res/layout/battery_detail.xml b/packages/SystemUI/res/layout/battery_detail.xml index af3e3796d157..8e7feec94062 100644 --- a/packages/SystemUI/res/layout/battery_detail.xml +++ b/packages/SystemUI/res/layout/battery_detail.xml @@ -26,10 +26,13 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingStart="72dp" - android:paddingBottom="@dimen/battery_detail_graph_space_top" android:textAppearance="?android:attr/textAppearanceMedium" android:textColor="?android:attr/colorAccent" /> + <com.android.systemui.ResizingSpace + android:layout_width="match_parent" + android:layout_height="@dimen/battery_detail_graph_space_top" /> + <com.android.settingslib.graph.UsageView android:id="@+id/battery_usage" android:layout_width="match_parent" @@ -40,11 +43,14 @@ android:colorAccent="?android:attr/colorAccent" systemui:textColor="#66FFFFFF" /> + <com.android.systemui.ResizingSpace + android:layout_width="match_parent" + android:layout_height="@dimen/battery_detail_graph_space_bottom" /> + <View android:layout_width="match_parent" android:layout_height="1dp" android:background="?android:attr/listDivider" - android:layout_marginTop="@dimen/battery_detail_graph_space_bottom" android:layout_marginBottom="8dp" /> <RelativeLayout diff --git a/packages/SystemUI/res/values-h560dp/config.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_key_icon_view.xml index 8b576b924632..0cecb96fd022 100644 --- a/packages/SystemUI/res/values-h560dp/config.xml +++ b/packages/SystemUI/res/layout/keyboard_shortcuts_key_icon_view.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <!-- - ~ Copyright (C) 2014 The Android Open Source Project + ~ Copyright (C) 2016 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. @@ -15,9 +15,10 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> - -<resources> - <!-- The maximum number of items to be displayed in quick settings --> - <integer name="quick_settings_detail_max_item_count">6</integer> -</resources> - +<ImageView xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:padding="@dimen/ksh_item_padding" + android:layout_marginStart="@dimen/ksh_item_margin_start" + android:scaleType="fitXY" + android:background="@color/ksh_key_item_background"/> diff --git a/packages/SystemUI/res/layout/keyboard_shortcuts_key_view.xml b/packages/SystemUI/res/layout/keyboard_shortcuts_key_view.xml index 5002c1298eb2..1215029bdda0 100644 --- a/packages/SystemUI/res/layout/keyboard_shortcuts_key_view.xml +++ b/packages/SystemUI/res/layout/keyboard_shortcuts_key_view.xml @@ -17,9 +17,9 @@ <TextView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginStart="4dp" - android:padding="4dp" - android:background="#EEEEEE" - android:textColor="#8C000000" + android:padding="@dimen/ksh_item_padding" + android:layout_marginStart="@dimen/ksh_item_margin_start" + android:background="@color/ksh_key_item_background" + android:textColor="@color/ksh_key_item_color" android:singleLine="true" - android:textSize="14sp"/> + android:textSize="@dimen/ksh_item_text_size"/> diff --git a/core/res/res/layout/notification_action_list.xml b/packages/SystemUI/res/layout/qs_customize_tile_divider.xml index 400decc49945..0d932acb2c50 100644 --- a/core/res/res/layout/notification_action_list.xml +++ b/packages/SystemUI/res/layout/qs_customize_tile_divider.xml @@ -1,5 +1,6 @@ <?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2012 The Android Open Source Project +<!-- + Copyright (C) 2016 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. @@ -14,17 +15,11 @@ limitations under the License. --> -<LinearLayout +<View xmlns:android="http://schemas.android.com/apk/res/android" - android:id="@+id/actions" android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="horizontal" - android:visibility="gone" - android:layout_marginBottom="8dp" - android:showDividers="middle" - android:divider="?android:attr/listDivider" - android:dividerPadding="12dp" - > - <!-- actions will be added here --> -</LinearLayout> + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:background="?android:attr/listDivider" + android:importantForAccessibility="no" /> diff --git a/packages/SystemUI/res/layout/qs_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml index 3358a1869bdf..af2a28521c99 100644 --- a/packages/SystemUI/res/layout/qs_detail.xml +++ b/packages/SystemUI/res/layout/qs_detail.xml @@ -25,13 +25,15 @@ android:visibility="invisible" android:orientation="vertical"> + <com.android.systemui.ResizingSpace + android:layout_width="match_parent" + android:layout_height="@dimen/qs_detail_margin_top" /> + <include android:id="@+id/qs_detail_header" layout="@layout/qs_detail_header" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="28dp" - /> + android:layout_height="wrap_content" /> <com.android.systemui.statusbar.AlphaOptimizedImageView android:id="@+id/qs_detail_header_progress" diff --git a/packages/SystemUI/res/layout/qs_detail_items.xml b/packages/SystemUI/res/layout/qs_detail_items.xml index c22e42c2e28f..f1a8d63d13dc 100644 --- a/packages/SystemUI/res/layout/qs_detail_items.xml +++ b/packages/SystemUI/res/layout/qs_detail_items.xml @@ -16,17 +16,19 @@ --> <!-- extends FrameLayout --> <com.android.systemui.qs.QSDetailItems xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:sysui="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" - android:paddingTop="16dp" + android:paddingTop="@dimen/qs_detail_items_padding_top" android:paddingStart="16dp" android:paddingEnd="16dp"> - <LinearLayout + <com.android.systemui.qs.AutoSizingList android:id="@android:id/list" android:layout_width="match_parent" - android:layout_height="wrap_content" - android:orientation="vertical" /> + android:layout_height="match_parent" + android:orientation="vertical" + sysui:itemHeight="@dimen/qs_detail_item_height" /> <LinearLayout android:id="@android:id/empty" @@ -48,9 +50,4 @@ android:layout_marginTop="20dp" android:textAppearance="@style/TextAppearance.QS.DetailEmpty" /> </LinearLayout> - - <View - android:id="@+id/min_height_spacer" - android:layout_width="match_parent" - android:layout_height="0dp"/> -</com.android.systemui.qs.QSDetailItems>
\ No newline at end of file +</com.android.systemui.qs.QSDetailItems> diff --git a/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml b/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml index 224a0a0fd859..60112be21175 100644 --- a/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml +++ b/packages/SystemUI/res/layout/screen_pinning_request_buttons.xml @@ -112,21 +112,6 @@ <ImageView android:layout_width="match_parent" android:layout_height="match_parent" - android:scaleType="matrix" - android:src="@drawable/screen_pinning_light_bg_circ" /> - - <ImageView - android:layout_width="match_parent" - android:layout_height="match_parent" - android:paddingEnd="@dimen/screen_pinning_request_inner_padding" - android:paddingStart="@dimen/screen_pinning_request_inner_padding" - android:paddingTop="@dimen/screen_pinning_request_inner_padding" - android:scaleType="matrix" - android:src="@drawable/screen_pinning_bg_circ" /> - - <ImageView - android:layout_width="match_parent" - android:layout_height="match_parent" android:paddingEnd="@dimen/screen_pinning_request_nav_side_padding" android:paddingStart="@dimen/screen_pinning_request_nav_side_padding" android:paddingTop="@dimen/screen_pinning_request_nav_icon_padding" diff --git a/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml b/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml index 1e5193ff9925..ebad7a4085be 100644 --- a/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml +++ b/packages/SystemUI/res/layout/screen_pinning_request_buttons_land.xml @@ -43,21 +43,6 @@ <ImageView android:layout_height="match_parent" android:layout_width="match_parent" - android:scaleType="matrix" - android:src="@drawable/screen_pinning_light_bg_circ" /> - - <ImageView - android:layout_height="match_parent" - android:layout_width="match_parent" - android:scaleType="matrix" - android:paddingLeft="@dimen/screen_pinning_request_inner_padding" - android:paddingTop="@dimen/screen_pinning_request_inner_padding" - android:paddingBottom="@dimen/screen_pinning_request_inner_padding" - android:src="@drawable/screen_pinning_bg_circ" /> - - <ImageView - android:layout_height="match_parent" - android:layout_width="match_parent" android:scaleType="center" android:paddingLeft="@dimen/screen_pinning_request_nav_icon_padding" android:paddingTop="@dimen/screen_pinning_request_nav_side_padding" diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 47d3bffd6a63..3fa6245b7bde 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Maak <xliff:g id="APP">%s</xliff:g> toe."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> verwerp."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle onlangse programme is toegemaak."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Begin tans <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Kennisgewing is toegemaak."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Tuis"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Onlangs"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Terug"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Kennisgewings"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Kortpadsleutels"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Wissel invoermetode"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Programme"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Bystand"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Blaaier"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakte"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-pos"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Kitsboodskappe"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musiek"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Wys saam met volumekontroles"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Moenie steur nie"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Volumeknoppieskortpad"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index f2afb8f563e9..eb5d256bf079 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> አስወግድ።"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ተሰናብቷል::"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ሁሉም የቅርብ ጊዜ ማመልከቻዎች ተሰናብተዋል።"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> በመጀመር ላይ።"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"ማሳወቂያ ተወግዷል።"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"መነሻ"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"የቅርብ ጊዜዎቹ"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ተመለስ"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"ማሳወቂያዎች"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"የቁልፍ ሰሌዳ አቋራጮች"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"የግቤት ስልት ቀይር"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"መተግበሪያዎች"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"ረዳት"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"አሳሽ"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"እውቂያዎች"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ኢሜይል"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"ፈጣን መልዕክት"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"ሙዚቃ"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"የቀን መቁጠሪያ"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"ከድምፅ መቆጣጠሪያዎች ጋር አሳይ"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"አትረብሽ"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"የድምፅ አዝራሮች አቋራጭ"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index f949eaf5f0bf..82a772c0e028 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -172,6 +172,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"إزالة <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"تمت إزالة <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"تم تجاهل كل التطبيقات المستخدمة مؤخرًا."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"جارٍ بدء <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"تم تجاهل الإشعار."</string> @@ -532,6 +534,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"الشاشة الرئيسية"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"الأحدث"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"رجوع"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"الإشعارات"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"اختصارات لوحة المفاتيح"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"تبديل أسلوب الإدخال"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"التطبيقات"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"التطبيق المساعد"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"المتصفح"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"جهات الاتصال"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"البريد الإلكتروني"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"الرسائل الفورية"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"الموسيقى"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"التقويم"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"عرض مع عناصر التحكم في مستوى الصوت"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"الرجاء عدم الإزعاج"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"اختصار أزرار مستوى الصوت"</string> diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml index 3aa911ffad71..59b31419ac17 100644 --- a/packages/SystemUI/res/values-az-rAZ/strings.xml +++ b/packages/SystemUI/res/values-az-rAZ/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> kənarlaşdırın."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> çıxarıldı."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Bütün son tətbiqlər kənarlaşdırıldı."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> başlanır."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Bildiriş uzaqlaşdırıldı."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Əsas səhifə"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Sonuncular"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Geri"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Bildirişlər"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Klaviatura qısa yolları"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Daxiletmə metoduna keçin"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Tətbiqlər"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Yardım"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Brauzer"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktlar"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-poçt"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musiqi"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Təqvim"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Həcm nəzarəti ilə göstərin"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Narahat etməyin"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Səs düymələri qısayolu"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index cc091f646381..0945885077ed 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -169,6 +169,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Odbacite <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikacija <xliff:g id="APP">%s</xliff:g> je odbačena."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Sve nedavno korišćene aplikacije su odbačene."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Pokrećemo <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obaveštenje je odbačeno."</string> @@ -529,6 +531,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početni"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni sadržaj"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nazad"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Obaveštenja"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Tasterske prečice"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Promeni metod unosa"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikacije"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Aplikacija za pomoć"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Pregledač"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakti"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Imejl"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Razmena trenutnih poruka"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muzika"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendar"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Prikaži sa kontrolama jačine zvuka"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ne uznemiravaj"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Prečica za dugmad za jačinu zvuka"</string> diff --git a/packages/SystemUI/res/values-be-rBY/strings.xml b/packages/SystemUI/res/values-be-rBY/strings.xml index a496330b6bf1..726a0e77073e 100644 --- a/packages/SystemUI/res/values-be-rBY/strings.xml +++ b/packages/SystemUI/res/values-be-rBY/strings.xml @@ -172,6 +172,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Выдаліць <xliff:g id="APP">%s</xliff:g> са спіса апошніх."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> выдалены."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Усе апошнія праграмы адхілены."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Запускаецца <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Апавяшчэнне прапушчана."</string> @@ -532,6 +534,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Галоўная"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Апошнія"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Апавяшчэнні"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Спалучэнні клавіш для хуткага доступу"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Пераключэнне рэжыму ўводу"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Праграмы"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Памочнік"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Браўзер"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Кантакты"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Электронная пошта"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Iмгненныя паведамленнi"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музыка"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Каляндар"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Паказаць з рэгулятарамі гучнасці"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Не турбаваць"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Доступ праз кнопкі рэгулявання гучнасці"</string> @@ -588,12 +602,12 @@ <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Перамясціць управа"</string> <string name="forced_resizable_info_text" msgid="7591061837558867999">"Праграма можа не працаваць у рэжыме некалькіх вокнаў"</string> <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Месца: <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Краніце двойчы, каб рэдагаваць."</string> - <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>, краніце двойчы, каб дадаць."</string> + <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Краніце двойчы, каб дадаць."</string> <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Месца: <xliff:g id="POSITION">%1$d</xliff:g>. Краніце двойчы, каб выбраць."</string> <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"Перамясціць <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> <string name="accessibility_qs_edit_remove_tile" msgid="7484493384665907197">"Выдаліць <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> - <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"<xliff:g id="TILE_NAME">%1$s</xliff:g> дададзена ў наступнае месца: <xliff:g id="POSITION">%2$d</xliff:g>"</string> - <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> выдалена"</string> + <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"Плітка <xliff:g id="TILE_NAME">%1$s</xliff:g> дададзена ў наступнае месца: <xliff:g id="POSITION">%2$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Плітка <xliff:g id="TILE_NAME">%1$s</xliff:g> выдалена"</string> <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> перамешчана ў наступнае месца: <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Рэдактар хуткіх налад."</string> </resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 1479beaa8706..479087ac9c87 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Отхвърляне на <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Приложението <xliff:g id="APP">%s</xliff:g> е отхвърлено."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Всички скорошни приложения са отхвърлени."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> се стартира."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Известието е отхвърлено."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Начало"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Скорошни"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Известия"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Клавишни комбинации"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Превключване на метода на въвеждане"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Приложения"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Помощно приложение"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Браузър"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Контакти"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Електронна поща"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Незабавни съобщения"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музика"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Календар"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Показване с контролите за силата на звука"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Не безпокойте"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Пряк път към бутоните за силата на звука"</string> diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml index ed8b06678bcb..ccbcb6ec1647 100644 --- a/packages/SystemUI/res/values-bn-rBD/strings.xml +++ b/packages/SystemUI/res/values-bn-rBD/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> খারিজ করুন।"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> খারিজ করা হয়েছে৷"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"সমস্ত সাম্প্রতিক অ্যাপ্লিকেশন খারিজ করা হয়েছে।"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> তারাঙ্কিত করা হচ্ছে।"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"বিজ্ঞপ্তি খারিজ করা হয়েছে৷"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"হোম"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"সাম্প্রতিকগুলি"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"পিছনে"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"বিজ্ঞপ্তিগুলি"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"কীবোর্ড শর্টকাট"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ইনপুট পদ্ধতি পাল্টান"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"অ্যাপ্লিকেশানগুলি"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"সহযোগিতা"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ব্রাউজার"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"পরিচিতি"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ইমেল"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"সংগীত"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ক্যালেন্ডার"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"ভলিউম নিয়ন্ত্রণ সহ দেখান"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"বিরক্ত করবেন না"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"ভলিউম বোতামের শর্টকাট"</string> diff --git a/packages/SystemUI/res/values-bs-rBA/strings.xml b/packages/SystemUI/res/values-bs-rBA/strings.xml index c6201786c00f..c5398a2cb6e2 100644 --- a/packages/SystemUI/res/values-bs-rBA/strings.xml +++ b/packages/SystemUI/res/values-bs-rBA/strings.xml @@ -169,6 +169,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Odbaci aplikaciju <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikacija <xliff:g id="APP">%s</xliff:g> uklonjena."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Sve nedavno korištene aplikacije su odbačene."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Pokrećem aplikaciju <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obavještenje je uklonjeno."</string> @@ -529,6 +531,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početak"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni ekrani"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nazad"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Obavještenja"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Skracenice tastature"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Promijeni način unosa"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikacije"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Pomoć"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Preglednik"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakti"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-pošta"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muzika"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendar"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Prikazati sa kontrolama jačine zvuka"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ne ometaj"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Prečica za dugmad za Jačinu zvuka"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 0145c2a93b37..b7fffb7fda52 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ignora <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"S\'ha omès <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"S\'han descartat totes les aplicacions recents."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"S\'està iniciant <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificació omesa."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inici"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recents"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Enrere"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notificacions"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Tecles de drecera"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Canvia el mètode d\'introducció"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplicacions"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assistència"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navegador"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contactes"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Correu electrònic"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"MI"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendari"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Mostra amb els controls de volum"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"No molesteu"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Drecera per als botons de volum"</string> @@ -583,13 +597,13 @@ <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mou a l\'esquerra"</string> <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mou a la dreta"</string> <string name="forced_resizable_info_text" msgid="7591061837558867999">"És possible que l\'aplicació no funcioni amb el Mode multifinestra"</string> - <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posició <xliff:g id="POSITION">%1$d</xliff:g>, mosaic <xliff:g id="TILE_NAME">%2$s</xliff:g>. Fes doble toc per editar-la."</string> - <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"Mosaic <xliff:g id="TILE_NAME">%1$s</xliff:g>. Fes doble toc per afegir-lo."</string> + <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posició <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Fes doble toc per editar-la."</string> + <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Fes doble toc per afegir-ho."</string> <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posició <xliff:g id="POSITION">%1$d</xliff:g>. Fes doble toc per seleccionar-la."</string> - <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"Mou el mosaic <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> - <string name="accessibility_qs_edit_remove_tile" msgid="7484493384665907197">"Suprimeix el mosaic <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> - <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"El mosaic <xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha afegit a la posició <xliff:g id="POSITION">%2$d</xliff:g>"</string> - <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"El mosaic <xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha suprimit"</string> - <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"El mosaic <xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha mogut a la posició <xliff:g id="POSITION">%2$d</xliff:g>"</string> + <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"Mou <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> + <string name="accessibility_qs_edit_remove_tile" msgid="7484493384665907197">"Suprimeix <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"<xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha afegit a la posició <xliff:g id="POSITION">%2$d</xliff:g>"</string> + <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha suprimit"</string> + <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> s\'ha mogut a la posició <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Editor de la configuració ràpida."</string> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index ec2011f9882b..b707ece9e9eb 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -170,6 +170,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Zavřít aplikaci <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikace <xliff:g id="APP">%s</xliff:g> byla odebrána."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Všechny naposledy použité aplikace byly odstraněny."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Spouštění aplikace <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Oznámení je zavřeno."</string> @@ -530,6 +532,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Plocha"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Poslední"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Zpět"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Oznámení"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Klávesové zkratky"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Přepnout metodu zadávání"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikace"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Asistence"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Prohlížeč"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakty"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Chat"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Hudba"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendář"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Zobrazit včetně ovládacích prvků hlasitosti"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Nerušit"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Zkratka tlačítek hlasitosti"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 87111003ddd0..7a25141257aa 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Afvis <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> er annulleret."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle de seneste applikationer er lukket."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> startes."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Underretningen er annulleret."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Start"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Seneste"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Tilbage"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Underretninger"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Tastaturgenveje"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Skift indtastningsmetode"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Applikationer"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assistance"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktpersoner"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Chat"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musik"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Vis med lydstyrkeregulering"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Forstyr ikke"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Genvej til lydstyrkeknapper"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index 2daa00f085d3..e10eb649af41 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> beenden"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> entfernt"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle kürzlich verwendeten Apps wurden entfernt."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> wird gestartet."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Benachrichtigung geschlossen"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startseite"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Letzte"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Zurück"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Benachrichtigungen"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Tastenkombinationen"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Eingabemethode wechseln"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Apps"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assistent"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakte"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-Mail"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Einschließlich Lautstärkeregler anzeigen"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Bitte nicht stören"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Tastenkombination für Lautstärketasten"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 34385f335307..5ec313398fb3 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Παράβλεψη <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Απορρίφθηκαν <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Έγινε παράβλεψη όλων των πρόσφατων εφαρμογών."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Έναρξη <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Η ειδοποίηση έχει απορριφθεί."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Αρχική οθόνη"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Πρόσφατα"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Πίσω"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Ειδοποιήσεις"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Συντομεύσεις πληκτρολογίου"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Εναλλαγή μεθόδου εισαγωγής"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Εφαρμογές"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Υποβοήθηση"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Πρόγραμμα περιήγησης"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Επαφές"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Ηλεκτρονικό ταχυδρομείο"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Άμεσα μηνύματα (ΙΜ)"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Μουσική"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Ημερολόγιο"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Εμφάνιση με στοιχεία ελέγχου έντασης ήχου"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Μην ενοχλείτε"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Συντόμευση κουμπιών έντασης ήχου"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 71a8ad783893..f08894fb39b8 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Dismiss <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> dismissed."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"All recent applications dismissed."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Starting <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification dismissed."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Back"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notifications"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Keyboard Shortcuts"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Switch input method"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Applications"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assist"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacts"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendar"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Show with volume controls"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Do not disturb"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Volume buttons shortcut"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 71a8ad783893..f08894fb39b8 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Dismiss <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> dismissed."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"All recent applications dismissed."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Starting <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification dismissed."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Back"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notifications"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Keyboard Shortcuts"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Switch input method"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Applications"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assist"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacts"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendar"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Show with volume controls"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Do not disturb"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Volume buttons shortcut"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 71a8ad783893..f08894fb39b8 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Dismiss <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> dismissed."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"All recent applications dismissed."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Starting <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification dismissed."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Back"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notifications"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Keyboard Shortcuts"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Switch input method"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Applications"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assist"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacts"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendar"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Show with volume controls"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Do not disturb"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Volume buttons shortcut"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 35d0f470fc7d..b5a10e1f5e4d 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Rechazar <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> descartada."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Se descartaron todas las aplicaciones recientes."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iniciando <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación ignorada"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Pantalla principal"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recientes"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atrás"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notificaciones"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Combinación de teclas"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Cambiar método de entrada"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplicaciones"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Asistencia"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navegador"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contactos"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Correo electrónico"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"MI"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Música"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendario"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Mostrar con controles de volumen"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"No interrumpir"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Combinación de teclas de botones de volumen"</string> @@ -582,7 +596,7 @@ <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Mover hacia arriba"</string> <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Mover a la izquierda"</string> <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Mover a la derecha"</string> - <string name="forced_resizable_info_text" msgid="7591061837558867999">"Es posible que la app no funcione con la función Multiventana"</string> + <string name="forced_resizable_info_text" msgid="7591061837558867999">"Es posible que la app no se ejecute con la función Multiventana"</string> <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posición <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Presiona dos veces para editarla."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Presiona dos veces para agregarlo."</string> <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posición <xliff:g id="POSITION">%1$d</xliff:g>. Presiona dos veces para seleccionarla."</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index a976a9c40a53..d8affc9f81dd 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ignorar <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Se ha eliminado <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Se han ignorado todas las aplicaciones recientes."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iniciando <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación ignorada"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inicio"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recientes"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atrás"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notificaciones"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Combinaciones de teclas"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Cambiar método de introducción"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplicaciones"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Asistencia"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navegador"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contactos"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Correo electrónico"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"MI"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Música"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendario"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Mostrar con controles de volumen"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"No molestar"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Combinación de teclas para los botones de volumen"</string> diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml index e7bfdffe94d1..f18bf05f1599 100644 --- a/packages/SystemUI/res/values-et-rEE/strings.xml +++ b/packages/SystemUI/res/values-et-rEE/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Rakendusest <xliff:g id="APP">%s</xliff:g> loobumine."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Loobusite rakendusest <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Kõikidest hiljutistest rakendustest on loobutud"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Rakenduse <xliff:g id="APP">%s</xliff:g> käivitamine."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g>, <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Märguandest on loobutud."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Avaekraan"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Hiljutised"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Tagasi"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Märguanded"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Klaviatuuri otseteed"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Sisestusmeetodi vahetamine"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Rakendused"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Abi"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Brauser"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktid"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-post"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM (kiirsuhtlus)"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muusika"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Kuva koos helitugevuse juhtnuppudega"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Mitte segada"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Helitugevuse nuppude otsetee"</string> diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml index b9cb78e02914..575f87496e97 100644 --- a/packages/SystemUI/res/values-eu-rES/strings.xml +++ b/packages/SystemUI/res/values-eu-rES/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Baztertu <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> baztertu da."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Azken aplikazio guztiak baztertu da."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> hasten."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Jakinarazpena baztertu da."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Hasierako pantaila"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Azkenak"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atzera"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Jakinarazpenak"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Lasterbideak"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Aldatu idazketa-metodoa"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikazioak"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Laguntzailea"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Arakatzailea"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktuak"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Helbide elektronikoa"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Istanteko mezularitza"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musika"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Egutegia"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Erakutsi bolumena kontrolatzeko aukerekin"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ez molestatu"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Bolumen-botoietarako lasterbidea"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index af744351445b..322197e1c990 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"رد کردن <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> نادیده گرفته شد."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"همه برنامههای اخیر رد شدند."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> در حال شروع به کار است."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"اعلان ردشد."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"صفحه اصلی"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"موارد اخیر"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"برگشت"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"اعلانها"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"میانبرهای صفحهکلید"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"تغییر روش ورودی"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"برنامهها"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"دستیار"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"مرورگر"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"مخاطبین"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"رایانامه"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"پیام فوری"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"موسیقی"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"تقویم"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"نمایش با کنترلهای صدا"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"مزاحم نشوید"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"میانبر دکمههای صدا"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index 3b28199dc180..6db0a3e37848 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Hylätään <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> hylättiin."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Kaikki viimeisimmät sovellukset on hylätty."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Käynnistetään <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Ilmoitus hylätty."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Aloitusnäyttö"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Viimeaikaiset"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Takaisin"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Ilmoitukset"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Pikanäppäimet"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Vaihda syöttötapaa"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Sovellukset"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Apusovellus"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Selain"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Yhteystiedot"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Sähköposti"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Pikaviesti"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musiikki"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalenteri"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Näytä äänenvoimakkuuden säätimien yhteydessä"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Älä häiritse"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Äänenvoimakkuuspainikkeiden pikanäppäin"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 2ef24db03921..89c682634d25 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Supprimer <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Application \"<xliff:g id="APP">%s</xliff:g>\" ignorée."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Toutes les applications récentes ont été supprimées."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Lancement de <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification masquée"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Accueil"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Récents"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Précédent"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notifications"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Raccourcis clavier"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Changer de méthode d\'entrée"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Applications"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assistance"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navigateur"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacts"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Courriel"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"MI"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musique"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Agenda"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Afficher avec les commandes de volume"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ne pas déranger"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Raccourci des boutons de volume"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 93d9e14a9e6f..2f99b946a7aa 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Supprimer <xliff:g id="APP">%s</xliff:g>"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Application \"<xliff:g id="APP">%s</xliff:g>\" ignorée."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Toutes les applications récentes ont été supprimées."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Lancement de <xliff:g id="APP">%s</xliff:g>"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> : <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notification masquée"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Accueil"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Récents"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Précédent"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notifications"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Raccourcis clavier"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Changer le mode de saisie"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Applications"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assistance"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navigateur"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacts"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Messagerie"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Messagerie instantanée"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musique"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Agenda"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Afficher avec les commandes de volume"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ne pas déranger"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Raccourci des boutons de volume"</string> diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml index 86a0bfa44ea5..45c3626b0c6e 100644 --- a/packages/SystemUI/res/values-gl-rES/strings.xml +++ b/packages/SystemUI/res/values-gl-rES/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Rexeitar <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Rexeitouse <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Rexeitáronse todas as aplicacións recentes."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iniciando <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificación rexeitada"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Inicio"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Volver"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notificacións"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Atallos de teclado"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Cambiar de método de entrada"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplicacións"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Asistente"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navegador"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contactos"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Correo electrónico"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"MI"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Música"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendario"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Mostrar cos controis de volume"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Non molestar"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Atallo dos botóns de volume"</string> diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml index d52226df4b8c..ef6a49c1043e 100644 --- a/packages/SystemUI/res/values-gu-rIN/strings.xml +++ b/packages/SystemUI/res/values-gu-rIN/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> કાઢી નાખો."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> કાઢી નાખી."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"તમામ તાજેતરની એપ્લિકેશનો કાઢી નાખી."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> પ્રારંભ કરી રહ્યું છે."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"સૂચના કાઢી નાખી."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"હોમ"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"તાજેતરના"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"પાછળ"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"સૂચનાઓ"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"કીબોર્ડ શૉર્ટકટ્સ"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ઇનપુટ પદ્ધતિ સ્વિચ કરો"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"ઍપ્લિકેશનો"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"સહાય"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"બ્રાઉઝર"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"સંપર્કો"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ઇમેઇલ"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"સંગીત"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"કૅલેન્ડર"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"વૉલ્યૂમ નિયંત્રણ સાથે બતાવો"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"ખલેલ પાડશો નહીં"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"વૉલ્યૂમ બટન્સ શૉર્ટકટ"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 160d4a09a203..1ba0cafe9806 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> को ख़ारिज करें."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> खा़रिज कर दिया गया."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"हाल ही के सभी ऐप्लिकेशन ख़ारिज कर दिए गए."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> प्रारंभ हो रहा है."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"नोटिफिकेशन खारिज की गई."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"होम"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"हाल ही के"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"वापस जाएं"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"नोटिफ़िकेशन"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"कीबोर्ड शॉर्टकट"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"इनपुट पद्धति बदलें"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"ऐप्लिकेशन"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"सहायक"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ब्राउज़र"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"संपर्क"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ईमेल"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"संगीत"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"कैलेंडर"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"वॉल्यूम नियंत्रणों के साथ दिखाएं"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"परेशान न करें"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"वॉल्यूम बटन का शॉर्टकट"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index ddfcb553b180..81c627600613 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -169,6 +169,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Odbacivanje aplikacije <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikacija <xliff:g id="APP">%s</xliff:g> odbačena je."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Odbačene su sve nedavne aplikacije."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Pokretanje aplikacije <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obavijest je odbačena."</string> @@ -529,6 +531,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Početni zaslon"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Najnovije"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Natrag"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Obavijesti"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Tipkovni prečaci"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Promjena načina unosa"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikacije"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Pomoć"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Preglednik"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakti"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-pošta"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Izravna poruka"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Glazba"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendar"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Prikaži s kontrolama glasnoće"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ne uznemiravaj"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Prečac tipki za glasnoću"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index c026926ebb24..b7ac8a4ed1ba 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"A(z) <xliff:g id="APP">%s</xliff:g> elvetése."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> eltávolítva."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Az összes alkalmazás eltávolítva a nemrég használtak közül."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"A(z) <xliff:g id="APP">%s</xliff:g> indítása."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Értesítés elvetve."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Otthon"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Legutóbbiak"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Vissza"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Értesítések"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Billentyűkódok"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Beviteli mód váltása"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Alkalmazások"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Segédalkalmazás"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Böngésző"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Névjegyek"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Azonnali üzenetküldés"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Zene"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Naptár"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Megjelenítés hangerőszabályzóval"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ne zavarjanak"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"A hangerőgombok gyorsbillentyűk"</string> diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml index a9d122a0c899..7e4e01a4ccf9 100644 --- a/packages/SystemUI/res/values-hy-rAM/strings.xml +++ b/packages/SystemUI/res/values-hy-rAM/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Անտեսել <xliff:g id="APP">%s</xliff:g>-ը:"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>-ը անտեսված է:"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Բոլոր վերջին հավելվածները հեռացվել են ցուցակից:"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Մեկնարկել <xliff:g id="APP">%s</xliff:g>-ը:"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Ծանուցումը անտեսվեց:"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Գլխավոր էջ"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Վերջինները"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Հետ"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Ծանուցումներ"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Ստեղնային դյուրանցումներ"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Փոխարկել մուտքագրման եղանակը"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Գործադիրներ"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Օգնություն"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Դիտարկիչ"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Կոնտակտներ"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Էլփոստ"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Երաժշտություն"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Օրացույց"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Ցույց տալ ձայնի ուժգնության կառավարման տարրերի հետ"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Չընդհատել"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Ձայնի կոճակների դյուրանցում"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 876034ce90b5..2b5142636535 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Menyingkirkan <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> disingkirkan."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Semua aplikasi terbaru telah ditutup."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Memulai <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notifikasi disingkirkan."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Layar Utama"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Terbaru"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Kembali"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notifikasi"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Pintasan Keyboard"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Beralih metode masukan"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikasi"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Bantuan"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontak"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musik"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Tampilkan dengan kontrol volume"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Jangan ganggu"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Pintasan tombol volume"</string> diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml index 4ce5f548e25e..1dc37df36651 100644 --- a/packages/SystemUI/res/values-is-rIS/strings.xml +++ b/packages/SystemUI/res/values-is-rIS/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Hunsa <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> vísað frá."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Öll nýleg forrit fjarlægð."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Ræsir <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Tilkynningu lokað."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Heim"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nýlegt"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Til baka"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Tilkynningar"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Flýtilyklar"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Skipta um innsláttaraðferð"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Forrit"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Aðstoð"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Vafri"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Tengiliðir"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Tölvupóstur"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Spjall"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Tónlist"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Dagatal"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Sýna með hljóðstyrksstillingum"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ónáðið ekki"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Flýtihnappar fyrir hljóðstyrk"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 62c18f2fc0d0..4a8ba9931f2f 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Elimina <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> eliminata."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Tutte le applicazioni recenti sono state rimosse."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Avvio di <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notifica eliminata."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recenti"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Indietro"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notifiche"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Scorciatoie da tastiera"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Cambia metodo di immissione"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Applicazioni"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assistenza"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contatti"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Chat"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musica"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendario"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Mostra con controlli volume"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Non disturbare"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Pulsanti del volume come scorciatoia"</string> @@ -585,7 +599,7 @@ <string name="forced_resizable_info_text" msgid="7591061837558867999">"L\'app potrebbe non funzionare con la modalità multi-finestra"</string> <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Posizione <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Tocca due volte per modificare."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Tocca due volte per aggiungere."</string> - <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Positione <xliff:g id="POSITION">%1$d</xliff:g>. Tocca due volte per selezionare."</string> + <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Posizione <xliff:g id="POSITION">%1$d</xliff:g>. Tocca due volte per selezionare."</string> <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"Sposta <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> <string name="accessibility_qs_edit_remove_tile" msgid="7484493384665907197">"Rimuovi <xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"Il riquadro <xliff:g id="TILE_NAME">%1$s</xliff:g> è stato aggiunto alla posizione <xliff:g id="POSITION">%2$d</xliff:g>"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 097b427cdd97..d41d50d399f4 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -170,6 +170,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"סגור את <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> נדחה."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"כל האפליקציות האחרונות נסגרו."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"מפעיל את <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"הודעה נדחתה."</string> @@ -530,6 +532,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"דף הבית"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"אחרונים"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"הקודם"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"הודעות"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"מקשי קיצור במקלדת"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"החלפת שיטת קלט"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"אפליקציות"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"מסייע"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"דפדפן"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"אנשי קשר"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"אימייל"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"שליחת הודעות מיידיות"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"מוזיקה"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"יומן"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"הצג עם פקדי עוצמת הקול"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"נא לא להפריע"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"מקש קיצור ללחצני עוצמת קול"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index 61ff6d42ca3b..83a9888f2231 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>を削除します。"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>は削除されました。"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"最近のアプリケーションをすべて消去しました。"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g>を開始しています。"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"通知が削除されました。"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ホーム"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"戻る"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"通知"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"キーボード ショートカット"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"入力方法の切り替え"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"アプリ"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"アシスト"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ブラウザ"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"連絡先"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"メール"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"音楽"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"カレンダー"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"音量調節を表示"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"通知の非表示"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"音量ボタンのショートカット"</string> diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml index 26f25293ca13..5008fe05e998 100644 --- a/packages/SystemUI/res/values-ka-rGE/strings.xml +++ b/packages/SystemUI/res/values-ka-rGE/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>-ის უგულებელყოფა."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ამოშლილია სიიდან."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ყველა ბოლო აპლიკაცია გაუქმდა."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> იწყება."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"შეტყობინება წაიშალა."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"მთავარი"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ბოლოს გამოყენებული"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"უკან"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"შეტყობინებები"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"კლავიატურის მალსახმობები"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"შეყვანის მეთოდის გადართვა"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"აპლიკაციები"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"დახმარება"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ბრაუზერი"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"კონტაქტები"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ელფოსტა"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"მუსიკა"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"კალენდარი"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"ხმის მართვის საშუალებების ჩვენება"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"არ შემაწუხოთ"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"ხმის ღილაკების მალსახმობი"</string> diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml index 737041e3a045..ff33f0504ddd 100644 --- a/packages/SystemUI/res/values-kk-rKZ/strings.xml +++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> қолданбасынан бас тарту."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> алынып тасталған."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Барлық жақындағы қабылданбаған қолданбалар."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> іске қосылуда."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Хабар алынып тасталды."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Негізгі бет"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Жақындағылар"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Артқа"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Хабарландырулар"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Пернелер тіркесімдері"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Енгізу әдісін ауыстыру"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Қолданбалар"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Көмекші"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Браузер"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Контактілер"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Электрондық пошта"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Mузыка"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Күнтізбе"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Дыбыс деңгейін басқару элементтерімен бірге көрсету"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Мазаламау"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Дыбыс деңгейі түймелерінің төте жолы"</string> diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml index 1cec0b002647..b69f893f0fbb 100644 --- a/packages/SystemUI/res/values-km-rKH/strings.xml +++ b/packages/SystemUI/res/values-km-rKH/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"បោះបង់ <xliff:g id="APP">%s</xliff:g> ។"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> បដិសេធ។"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"កម្មវិធីថ្មីៗទាំងអស់ត្រូវបានបោះបង់។"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"ចាប់ផ្ដើម <xliff:g id="APP">%s</xliff:g> ។"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"បានបដិសេធការជូនដំណឹង"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ដើម"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ថ្មីៗ"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ថយក្រោយ"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"ការជូនដំណឹង"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"ផ្លូវកាត់ក្ដារចុច"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ប្ដូរវិធីសាស្ត្របញ្ចូល"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"កម្មវិធី"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"ជំនួយ"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"កម្មវិធីរុករក"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"ទំនាក់ទំនង"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"អ៊ីមែល"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"តន្ត្រី"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ប្រតិទិន"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"បង្ហាញជាមួយការគ្រប់គ្រងកម្រិតសំឡេង"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"កុំរំខាន"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"ផ្លូវកាត់ប៊ូតុងកម្រិតសំឡេង"</string> diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml index 2eb614163e88..1ce14dd58df6 100644 --- a/packages/SystemUI/res/values-kn-rIN/strings.xml +++ b/packages/SystemUI/res/values-kn-rIN/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ವಜಾಗೊಳಿಸು."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ಇತ್ತೀಚಿನ ಎಲ್ಲಾ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ವಜಾಗೊಳಿಸಲಾಗಿದೆ."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ಪ್ರಾರಂಭಿಸಲಾಗುತ್ತಿದೆ."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"ಅಧಿಸೂಚನೆ ವಜಾಗೊಂಡಿದೆ."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ಮುಖಪುಟ"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ಇತ್ತೀಚಿನವುಗಳು"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ಹಿಂದೆ"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"ಅಧಿಸೂಚನೆಗಳು"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"ಕೀಬೋರ್ಡ್ ಶಾರ್ಟ್ಕಟ್ಗಳು"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ಇನ್ಪುಟ್ ವಿಧಾನ ಬದಲಿಸಿ"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"ಅಪ್ಲಿಕೇಶನ್ಗಳು"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"ಸಹಾಯ ಮಾಡು"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ಬ್ರೌಸರ್"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"ಸಂಪರ್ಕಗಳು"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ಇಮೇಲ್"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"ಸಂಗೀತ"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ಕ್ಯಾಲೆಂಡರ್"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"ವಾಲ್ಯೂಮ್ ನಿಯಂತ್ರಣಗಳ ಜೊತೆಗೆ ತೋರಿಸು"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"ವಾಲ್ಯೂಮ್ ಬಟನ್ಗಳ ಶಾರ್ಟ್ಕಟ್"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index ae60d0eeaa85..a8a2a0a2758e 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>을(를) 숨깁니다."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>이(가) 제거되었습니다."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"최근 사용한 애플리케이션을 모두 닫았습니다."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g>을(를) 시작하는 중입니다."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"알림이 제거되었습니다."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"홈"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"최근"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"뒤로"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"알림"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"단축키"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"입력 방법 전환"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"애플리케이션"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"지원"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"브라우저"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"주소록"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"이메일"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"메신저"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"음악"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"캘린더"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"볼륨 컨트롤과 함께 표시"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"알림 일시중지"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"볼륨 버튼 단축키"</string> diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml index b035bbb1d13f..6a2d77fe0a04 100644 --- a/packages/SystemUI/res/values-ky-rKG/strings.xml +++ b/packages/SystemUI/res/values-ky-rKG/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> этибарга албоо."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> жок болду."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Акыркы колдонмолордун баары көз жаздымда калтырылды."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> иштеп баштоодо."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Эскертме жок кылынды."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Башкы бет"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Акыркылар"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Артка"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Эскертмелер"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Баскычтоптун кыска жолдору"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Киргизүү ыкмасын которуштуруу"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Колдонмолор"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Көмөкчү"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Серепчи"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Байланыштар"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Электрондук почта"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музыка"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Жылнаама"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Үн көзөмөлдөгүчтөрү менен көрсөтүлсүн"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Тынчымды алба"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Үндү көзөмөлдөөчү баскычтардын кыска жолдору"</string> @@ -582,7 +596,7 @@ <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"Жогору жылдыруу"</string> <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"Солго жылдыруу"</string> <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"Оңго жылдыруу"</string> - <string name="forced_resizable_info_text" msgid="7591061837558867999">"Көп терезе режиминде колдонмо иштебей калышы мүмкүн"</string> + <string name="forced_resizable_info_text" msgid="7591061837558867999">"Бир нече терезе режиминде колдонмо иштебей калышы мүмкүн"</string> <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"Орду - <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>. Түзөтүү үчүн эки жолу таптаңыз."</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>. Кошуу үчүн эки жолу таптаңыз."</string> <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"Орду - <xliff:g id="POSITION">%1$d</xliff:g>. Тандоо үчүн эки жолу таптаңыз."</string> diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml index 26a81c8d835c..c40797c6ebaa 100644 --- a/packages/SystemUI/res/values-land/dimens.xml +++ b/packages/SystemUI/res/values-land/dimens.xml @@ -24,4 +24,14 @@ <dimen name="docked_divider_handle_width">2dp</dimen> <dimen name="docked_divider_handle_height">16dp</dimen> + + <dimen name="qs_tile_margin_top">2dp</dimen> + <dimen name="qs_brightness_padding_top">0dp</dimen> + + <dimen name="battery_detail_graph_space_top">9dp</dimen> + <dimen name="battery_detail_graph_space_bottom">9dp</dimen> + + <integer name="quick_settings_num_columns">4</integer> + <bool name="quick_settings_wide">true</bool> + <dimen name="qs_detail_margin_top">0dp</dimen> </resources> diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml index 2355a84d9cb3..601cc2a6c075 100644 --- a/packages/SystemUI/res/values-lo-rLA/strings.xml +++ b/packages/SystemUI/res/values-lo-rLA/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"ປິດ <xliff:g id="APP">%s</xliff:g> ໄວ້."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"ປິດ <xliff:g id="APP">%s</xliff:g> ແລ້ວ."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ທຸກແອັບພລິເຄຊັນບໍ່ດົນມານີ້ຖືກປ່ອຍໄປ."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"ກຳລັງເປີດ <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"ປິດການແຈ້ງເຕືອນແລ້ວ."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ໜ້າຫຼັກ"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ຫາກໍໃຊ້"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ກັບຄືນ"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"ການແຈ້ງເຕືອນ"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"ປຸ່ມລັດແປ້ນພິມ"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ສະລັບຮູບແບບການປ້ອນຂໍ້ມູນ"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"ແອັບພລິເຄຊັນ"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"ຕົວຊ່ວຍ"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ໂປຣແກຣມທ່ອງເວັບ"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"ລາຍຊື່ຜູ້ຕິດຕໍ່"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ອີເມວ"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"ດົນຕີ"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ປະຕິທິນ"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"ສະແດງສ່ວນຄວບຄຸມສຽງ"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"ຫ້າມລົບກວນ"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"ທາງລັດປຸ່ມສຽງ"</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 93c0b6941208..866abf3f6e2f 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -170,6 +170,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Atsisakyti <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Atsisakyta programos „<xliff:g id="APP">%s</xliff:g>“."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Atsisakyta visų naujausių programų."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Paleidžiama <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"„<xliff:g id="APP">%1$s</xliff:g>“ <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Pranešimo atsisakyta."</string> @@ -530,6 +532,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Pagrindinis ekranas"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Naujausios veiklos ekranas"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atgal"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Pranešimai"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Spartieji klavišai"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Perjungti įvesties metodą"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Programos"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Pagalbinė programa"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Naršyklė"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktai"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"El. paštas"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"TP"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muzika"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendorius"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Rodyti su garsumo valdikliais"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Netrukdymo režimas"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Garsumo mygtukų spartusis klavišas"</string> @@ -590,7 +604,7 @@ <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"<xliff:g id="POSITION">%1$d</xliff:g> padėtis. Dukart palieskite, kad pasirinktumėte."</string> <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"Perkelti išklotinės elementą „<xliff:g id="TILE_NAME">%1$s</xliff:g>“"</string> <string name="accessibility_qs_edit_remove_tile" msgid="7484493384665907197">"Pašalinti išklotinės elementą „<xliff:g id="TILE_NAME">%1$s</xliff:g>“"</string> - <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"Išklotinės elementas „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ pridėtas prie <xliff:g id="POSITION">%2$d</xliff:g> pozicijos"</string> + <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"Išklotinės elementas „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ pridėtas prie <xliff:g id="POSITION">%2$d</xliff:g> padėties"</string> <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"Išklotinės elementas „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ pašalintas"</string> <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"Išklotinės elementas „<xliff:g id="TILE_NAME">%1$s</xliff:g>“ perkeltas į <xliff:g id="POSITION">%2$d</xliff:g> padėtį"</string> <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"Sparčiųjų nustatymų redagavimo priemonė."</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 0ee306be07da..9c32b3190744 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -169,6 +169,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Nerādīt lietotni <xliff:g id="APP">%s</xliff:g>"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Lietotne <xliff:g id="APP">%s</xliff:g> vairs netiek rādīta."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Visas nesen izmantotās lietojumprogrammas tika noņemtas."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Notiek lietotnes <xliff:g id="APP">%s</xliff:g> palaišana."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Paziņojums netiek rādīts."</string> @@ -529,6 +531,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Sākums"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Pēdējie"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Atpakaļ"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Paziņojumi"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Īsinājumtaustiņi"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Pārslēgt ievades metodi"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Lietojumprogrammas"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Palīgs"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Pārlūkprogramma"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktpersonas"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-pasts"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Tūlītējā ziņojumapmaiņa"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Mūzika"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendārs"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Rādīt ar skaļuma vadīklām"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Netraucēt"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Skaļuma pogu saīsne"</string> diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml index cfacc43dafa3..7f2fc15ada68 100644 --- a/packages/SystemUI/res/values-mk-rMK/strings.xml +++ b/packages/SystemUI/res/values-mk-rMK/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Отфрли <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> е отфрлена."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Сите неодамнешни апликации се отфрлени."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Се стартува <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Известувањето е отфрлено."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Почетна страница"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Неодамнешни"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Известувања"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Кратенки на тастатурата"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Префрли метод за внесување"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Апликации"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Помош"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Прелистувач"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Контакти"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Е-пошта"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музика"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Календар"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Прикажи со контроли за јачина на звук"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Не вознемирувај"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Кратенка за копчињата за јачина на звук"</string> diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml index deca89887f58..dfe992c31e9f 100644 --- a/packages/SystemUI/res/values-ml-rIN/strings.xml +++ b/packages/SystemUI/res/values-ml-rIN/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> നിരസിക്കുക."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> നിരസിച്ചു."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"അടുത്തിടെയുള്ള എല്ലാ അപ്ലിക്കേഷനും നിരസിച്ചു."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ആരംഭിക്കുന്നു."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"അറിയിപ്പ് നിരസിച്ചു."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"വീട്"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"പുതിയവ"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"മടങ്ങുക"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"അറിയിപ്പുകൾ"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"കീബോർഡ് കുറുക്കുവഴികൾ"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ടൈപ്പിംഗ് രീതി മാറുക"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"അപ്ലിക്കേഷനുകൾ"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"അസിസ്റ്റ്"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ബ്രൗസർ"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"കോൺടാക്റ്റുകൾ"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ഇമെയിൽ"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"സംഗീതം"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"കലണ്ടർ"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"വോളിയം നിയന്ത്രണങ്ങളോടൊപ്പം കാണിക്കുക"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"ശല്യപ്പെടുത്തരുത്"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"വോളിയം ബട്ടൺ കുറുക്കുവഴി"</string> diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml index b701e21af902..80cb8f278dd4 100644 --- a/packages/SystemUI/res/values-mn-rMN/strings.xml +++ b/packages/SystemUI/res/values-mn-rMN/strings.xml @@ -166,6 +166,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>-г хаах."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> байхгүй."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Хамгийн сүүлийн бүх програмыг арилгасан байна."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g>-г эхлүүлж байна."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Мэдэгдэл хаагдсан."</string> @@ -526,6 +528,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Нүүр хуудас"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Саяхны"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Буцах"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Мэдэгдэл"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Гарын товчлол"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Оролтын аргыг солих"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Апп"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Дэмжлэг"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Хөтөч"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Харилцагчид"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Имэйл"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Хөгжим"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Хуанли"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Түвшний хяналттай харуулах"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Бүү саад бол"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Түвшний товчлуурын товчлол"</string> diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml index 6c6e6340a832..76dfcd555300 100644 --- a/packages/SystemUI/res/values-mr-rIN/strings.xml +++ b/packages/SystemUI/res/values-mr-rIN/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> डिसमिस करा."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> डिसमिस केला."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"अलीकडील सर्व अनुप्रयोग डिसमिस झाले."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> प्रारंभ करीत आहे."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"सूचना डिसमिस केल्या."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"मुख्यपृष्ठ"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"अलीकडील"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"परत"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"सूचना"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"कीबोर्ड शॉर्टकट"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"इनपुट पद्धत स्विच करा"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"अनुप्रयोग"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"सहाय्य"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ब्राउझर"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"संपर्क"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ईमेल"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"संगीत"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"कॅलेंडर"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"आवाज नियंत्रणांसह दर्शवा"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"व्यत्यय आणू नका"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"आवाजाच्या बटणांचा शार्टकट"</string> diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml index 335ff4c465e0..9401198ec56b 100644 --- a/packages/SystemUI/res/values-ms-rMY/strings.xml +++ b/packages/SystemUI/res/values-ms-rMY/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ketepikan <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ditolak."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Semua aplikasi terbaharu diketepikan."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Memulakan <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Pemberitahuan diketepikan."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Skrin Utama"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Terbaharu"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Kembali"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Pemberitahuan"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Pintasan Papan Kekunci"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Tukar kaedah input"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikasi"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Bantu"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Penyemak imbas"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kenalan"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mel"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muzik"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendar"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Tunjukkan dengan kawalan kelantangan"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Jangan ganggu"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Pintasan butang kelantangan"</string> diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml index d309991a7467..69647503a056 100644 --- a/packages/SystemUI/res/values-my-rMM/strings.xml +++ b/packages/SystemUI/res/values-my-rMM/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>ကို ပယ်လိုက်ရန်"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ထုတ်ထားသည်။"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"မကြာသေးမီက အပလီကေးရှင်းများအားလုံး ဖယ်ထုတ်ပြီးပါပြီ။"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g>ကို စတင်နေသည်။"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g><xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"အကြောင်းကြားချက်ကိုဖယ်ရှားပြီး"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ပင်မ"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"မကြာသေးခင်က"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"နောက်သို့"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"အကြောင်းကြားချက်များ"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"ကီးဘုတ် ဖြတ်လမ်းများ"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ထည့်သွင်းမှုနည်းလမ်းကို ပြောင်းလဲပါ"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"အက်ပ်များ"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"အထောက်အကူ"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ဘရောင်ဇာ"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"အဆက်အသွယ်များ"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"အီးမေးလ်"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"အမြန်စာတိုစနစ်"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ပြက္ခဒိန်"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"အသံထိန်းချုပ်သည့်ခလုတ်များဖြင့် ပြပါ"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"မနှောက်ယှက်ပါနှင့်"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"အသံထိန်းချုပ်သည့်ခလုတ် ဖြတ်လမ်း"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 8a961fc02c57..eed5f36ae95c 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Avvis <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> avvist."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle nylig brukte apper er avvist."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Starter <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Varselet ble skjult."</string> @@ -400,7 +402,7 @@ <string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"Enheten forblir låst til du låser den opp manuelt"</string> <string name="hidden_notifications_title" msgid="7139628534207443290">"Motta varsler raskere"</string> <string name="hidden_notifications_text" msgid="2326409389088668981">"Se dem før du låser opp"</string> - <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nei, takk"</string> + <string name="hidden_notifications_cancel" msgid="3690709735122344913">"Nei takk"</string> <string name="hidden_notifications_setup" msgid="41079514801976810">"Konfigurer"</string> <string name="zen_mode_and_condition" msgid="4462471036429759903">"<xliff:g id="ZEN_MODE">%1$s</xliff:g>. <xliff:g id="EXIT_CONDITION">%2$s</xliff:g>"</string> <string name="volume_zen_end_now" msgid="3179845345429841822">"Avslutt nå"</string> @@ -409,7 +411,7 @@ <string name="screen_pinning_title" msgid="3273740381976175811">"Skjermen er låst"</string> <string name="screen_pinning_description" msgid="3577937698406151604">"På denne måten blir skjermen synlig frem til du låser den opp. Trykk og hold inne Tilbake for å låse opp."</string> <string name="screen_pinning_positive" msgid="3783985798366751226">"Skjønner"</string> - <string name="screen_pinning_negative" msgid="3741602308343880268">"Nei, takk"</string> + <string name="screen_pinning_negative" msgid="3741602308343880268">"Nei takk"</string> <string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"Vil du skjule <xliff:g id="TILE_LABEL">%1$s</xliff:g>?"</string> <string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"Den vises igjen neste gang du slår den på i innstillingene."</string> <string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"Skjul"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startside"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nylige"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Tilbake"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Varsler"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Hurtigtaster"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Bytt inndatametode"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Apper"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assist"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Nettleser"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakter"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-post"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Chat"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musikk"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Vis med volumkontrollene"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ikke forstyrr"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Hurtigtast for volumknappene"</string> diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml index 7e91a5383791..836dc4bf8fa3 100644 --- a/packages/SystemUI/res/values-ne-rNP/strings.xml +++ b/packages/SystemUI/res/values-ne-rNP/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> खारेज गर्नुहोस्।"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> खारेज गरिएको छ।"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"सबै हालका अनुप्रयोगहरू खारेज गरियो।"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g>सुरु गर्दै।"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"सूचना खारेज।"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"गृह"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"हालैका"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"पछाडि"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"सूचनाहरू"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"किबोर्ड सर्टकटहरू"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"इनपुट विधिलाई स्विच गर्नुहोस्"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"अनुप्रयोगहरू"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"सहायता"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ब्राउजर"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"सम्पर्कहरू"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"इमेल"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"संगीत"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"पात्रो"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"भोल्युम नियन्त्रणसहित देखाउनुहोस्"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"बाधा नपुर्याउनुहोस्"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"भोल्युम बटनका सर्टकट"</string> @@ -582,7 +596,7 @@ <string name="accessibility_action_divider_move_up" msgid="4580103171609248006">"माथि सार्नुहोस्"</string> <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"बाँया सार्नुहोस्"</string> <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"दायाँ सार्नुहोस्"</string> - <string name="forced_resizable_info_text" msgid="7591061837558867999">"अनुप्रयोगले बहु-विन्डोमा काम नगर्न सक्छ"</string> + <string name="forced_resizable_info_text" msgid="7591061837558867999">"अनुप्रयोग बहु-विन्डोमा काम नगर्न सक्छ"</string> <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>, <xliff:g id="TILE_NAME">%2$s</xliff:g>। सम्पादन गर्नका लागि डबल ट्याप गर्नुहोस्।"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>। थप्नका लागि डबल ट्याप गर्नुहोस्।"</string> <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"स्थिति <xliff:g id="POSITION">%1$d</xliff:g>। चयन गर्नका लागि डबल ट्याप गर्नुहोस्।"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 3cad1fae9ca7..41075e397ccc 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> sluiten."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> verwijderd."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alle recente apps gesloten."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> starten."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Melding verwijderd."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startpagina"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recent"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Terug"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Meldingen"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Sneltoetsen"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Invoermethode schakelen"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Apps"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assistentie"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contacten"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Chat"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muziek"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Agenda"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Weergeven met volumeknoppen"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Niet storen"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Volumeknoppen als sneltoets"</string> diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml index 91baa9b74215..1703a2fa630e 100644 --- a/packages/SystemUI/res/values-pa-rIN/strings.xml +++ b/packages/SystemUI/res/values-pa-rIN/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ਨੂੰ ਰੱਦ ਕਰੋ।"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ਰੱਦ ਕੀਤਾ।"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ਸਾਰੀਆਂ ਹਾਲੀਆ ਐਪਲੀਕੇਸ਼ਨਾਂ ਰੱਦ ਕੀਤੀਆਂ।"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ਚਾਲੂ ਕਰ ਰਿਹਾ ਹੈ।"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"ਸੂਚਨਾ ਰੱਦ ਕੀਤੀ।"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ਮੁੱਖ ਸਕ੍ਰੀਨ"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ਹਾਲੀਆ"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ਪਿੱਛੇ"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"ਸੂਚਨਾਵਾਂ"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"ਕੀ-ਬੋਰਡ ਸ਼ਾਰਟਕੱਟ"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ਵਾਪਸ ਇਨਪੁੱਟ ਵਿਧੀ \'ਤੇ ਬਦਲੋ"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"ਐਪਲੀਕੇਸ਼ਨਾਂ"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"ਸਹਾਇਕ"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"ਬ੍ਰਾਊਜ਼ਰ"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"ਸੰਪਰਕ"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ਈਮੇਲ"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"ਸੰਗੀਤ"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ਕੈਲੰਡਰ"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"ਵੌਲਯੂਮ ਕੰਟਰੋਲਾਂ ਨਾਲ ਵਿਖਾਓ"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"ਵੌਲਯੂਮ ਬਟਨ ਸ਼ਾਰਟਕੱਟ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 3aed4b25719e..297b849b14a3 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -170,6 +170,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Usuń stąd <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g>: zamknięto."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Wszystkie ostatnie aplikacje zostały zamknięte."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Uruchamiam <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Zamknięto powiadomienie."</string> @@ -530,6 +532,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ekran główny"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Ostatnie"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Wstecz"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Powiadomienia"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Skróty klawiszowe"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Przełącz metodę wprowadzania"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikacje"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Pomoc"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Przeglądarka"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakty"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Komunikator"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muzyka"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendarz"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Pokazuj z regulacją głośności"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Nie przeszkadzać"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Wł./wył. przyciskami głośności"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 055a2981a9c6..eb08d997f064 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Descartar <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> descartado."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Todos os apps recentes foram dispensados."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iniciando <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificação dispensada."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Início"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Voltar"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notificações"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Atalhos do teclado"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Alterar o método de entrada"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplicativos"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assistente"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navegador"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contatos"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Mensagens instantâneas"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Música"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Agenda"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Mostrar com controles de volume"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Não perturbe"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Atalho de botões de volume"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index f40c7c7fc234..bba2f3e63611 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ignorar <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ignorado."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Todas as aplicações recentes foram ignoradas."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"A iniciar <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificação ignorada."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Página inicial"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Anterior"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notificações"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Atalhos de teclado"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Alternar o método de introdução"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplicações"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assistência"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navegador"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contactos"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Música"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendário"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Mostrar com controlos de volume"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Não incomodar"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Atalho dos botões de volume"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 055a2981a9c6..eb08d997f064 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Descartar <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> descartado."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Todos os apps recentes foram dispensados."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iniciando <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificação dispensada."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Início"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recentes"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Voltar"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notificações"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Atalhos do teclado"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Alterar o método de entrada"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplicativos"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Assistente"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Navegador"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Contatos"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Mensagens instantâneas"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Música"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Agenda"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Mostrar com controles de volume"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Não perturbe"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Atalho de botões de volume"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index a307698fabf3..81d0456e5bda 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -169,6 +169,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Închideți <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> a fost eliminată."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Toate aplicațiile recente au fost închise."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Se inițiază <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificarea a fost închisă."</string> @@ -529,6 +531,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ecran de pornire"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Recente"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Înapoi"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Notificări"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Comenzi rapide de la tastatură"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Comutați metoda de introducere a textului"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplicații"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Asistent"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Agendă"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muzică"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Calendar"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Afișează cu comenzile de volum"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Nu deranja"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Comandă rapidă din butoanele de volum"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 55216641baa9..86f0ec4c2ba9 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -170,6 +170,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Удаление приложения <xliff:g id="APP">%s</xliff:g> из списка."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Приложение \"<xliff:g id="APP">%s</xliff:g>\" удалено из списка."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Все недавние приложения закрыты."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Запуск приложения <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Уведомление закрыто"</string> @@ -514,8 +516,8 @@ <string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string> <string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Воспроизведение/пауза"</string> <string name="keyboard_key_media_stop" msgid="2859963958595908962">"Стоп"</string> - <string name="keyboard_key_media_next" msgid="1894394911630345607">"Далее"</string> - <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Назад"</string> + <string name="keyboard_key_media_next" msgid="1894394911630345607">"Следующий трек"</string> + <string name="keyboard_key_media_previous" msgid="4256072387192967261">"Предыдущий трек"</string> <string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Перемотка назад"</string> <string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Перемотка вперед"</string> <string name="keyboard_key_page_up" msgid="5654098530106845603">"Page Up"</string> @@ -525,11 +527,23 @@ <string name="keyboard_key_move_end" msgid="5901174332047975247">"End"</string> <string name="keyboard_key_insert" msgid="8530501581636082614">"Insert"</string> <string name="keyboard_key_num_lock" msgid="5052537581246772117">"Num Lock"</string> - <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"Цифровая клавиатура <xliff:g id="NAME">%1$s</xliff:g>"</string> + <string name="keyboard_key_numpad_template" msgid="8729216555174634026">"<xliff:g id="NAME">%1$s</xliff:g> на цифровой панели"</string> <string name="keyboard_shortcut_group_system" msgid="6472647649616541064">"Система"</string> <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Главный экран"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Недавние"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Уведомления"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Быстрые клавиши"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Сменить способ ввода"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Приложения"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Помощник"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Браузер"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Контакты"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Эл. почта"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Чат"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музыка."</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Календарь"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Показывать при нажатии кнопок регулировки громкости"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Не беспокоить"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Кнопки регулировки громкости"</string> diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml index 61411d6b5e8d..5a2f849f3db3 100644 --- a/packages/SystemUI/res/values-si-rLK/strings.xml +++ b/packages/SystemUI/res/values-si-rLK/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ඉවතලන්න."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> අස් කර ඇත."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"සියලුම මෑත යෙඳුම් අස් කරන ලදි."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ආරම්භ කරමින්."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"දැනුම්දීම නිෂ්ප්රභා කරඇත."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"මුල් පිටුව"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"මෑත"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"ආපසු"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"දැනුම්දීම්"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"යතුරු පුවරු කෙටිමං"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ආදාන ක්රමය මාරු කිරීම"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"යෙදුම්"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"සහාය"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"බ්රවුසරය"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"සම්බන්ධතා"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ඊ-තැපෑල"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"සංගීතය"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"දින දර්ශනය"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"හඩ පරිමා පාලන සහිතව පෙන්වන්න"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"බාධා නොකරන්න"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"හඩ පරිමා බොත්තම් කෙටිමග"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index f7967e339371..9468fcffb674 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -170,6 +170,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Zrušiť aplikáciu <xliff:g id="APP">%s</xliff:g>"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikácia <xliff:g id="APP">%s</xliff:g> bola zrušená."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Všetky nedávne aplikácie boli odmietnuté."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Spúšťa sa aplikácia <xliff:g id="APP">%s</xliff:g>"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Upozornenie bolo zrušené."</string> @@ -530,6 +532,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Domovská stránka"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedávne"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Späť"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Upozornenia"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Klávesové skratky"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Prepnúť metódu vstupu"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikácie"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Pomocná aplikácia"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Prehliadač"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakty"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-mail"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Okamžité správy"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Hudba"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendár"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Zobrazovať s ovládacími prvkami hlasitosti"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Nerušiť"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Skratka tlačidiel hlasitosti"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index f0b7bc7e146a..c5a43f9f05da 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -170,6 +170,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Opusti aplikacijo <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Aplikacija <xliff:g id="APP">%s</xliff:g> je bila odstranjena."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Vse nedavne aplikacije so bile opuščene."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Zaganjanje aplikacije <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Obvestilo je bilo odstranjeno."</string> @@ -530,6 +532,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Začetni zaslon"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Nedavni"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nazaj"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Obvestila"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Bližnjične tipke"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Preklop načina vnosa"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikacije"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Pomoč"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Brskalnik"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Stiki"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-pošta"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Neposredno sporočanje"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Glasba"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Koledar"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Prikaži s kontrolniki glasnosti"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ne moti"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Bližnjica z gumboma za glasnost"</string> diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml index 893e47190cd6..0188e5ba98d5 100644 --- a/packages/SystemUI/res/values-sq-rAL/strings.xml +++ b/packages/SystemUI/res/values-sq-rAL/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Largo <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> është hequr."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Të gjitha aplikacionet e fundit u larguan."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Po nis <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Njoftimi është hequr."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Kreu"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Të fundit"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Prapa"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Njoftimet"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Shkurtoret e tastierës"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Ndërro metodën e hyrjes"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Aplikacionet"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Asistenti"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Shfletuesi"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktet"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Mail-i"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Mesazh i çastit"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muzikë"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendari"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Shfaq me kontrollet e volumit"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Mos shqetëso"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Shkurtorja e butonave të volumit"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 6cfd7b04f0ba..501a3e346af9 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -169,6 +169,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Одбаците <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Апликација <xliff:g id="APP">%s</xliff:g> је одбачена."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Све недавно коришћене апликације су одбачене."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Покрећемо <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Обавештење је одбачено."</string> @@ -529,6 +531,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Почетни"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Недавни садржај"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Обавештења"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Тастерске пречице"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Промени метод уноса"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Апликације"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Апликација за помоћ"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Прегледач"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Контакти"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Имејл"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Размена тренутних порука"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музика"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Календар"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Прикажи са контролама јачине звука"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Не узнемиравај"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Пречица за дугмад за јачину звука"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index 6b1e949f8dce..959128e818b2 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ta bort <xliff:g id="APP">%s</xliff:g> från listan."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> togs bort permanent."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Alla appar har tagits bort från listan Senaste."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Startar <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Meddelandet ignorerades."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Startsida"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Senaste"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Tillbaka"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Aviseringar"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Kortkommandon"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Byt inmatningsmetod"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Appar"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Hjälp"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Webbläsare"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontakter"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-post"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Snabbmeddelanden"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musik"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalender"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Visa med volymkontroller"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Stör ej"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Genväg till volymknappar"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 5acf6c022a2c..4b936c9b0dd9 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Ondoa <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> imeondolewa."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Programu za hivi majuzi zimeondolewa."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Inaanzisha <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Arifa imetupwa."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Mwanzo"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Zilizotumika majuzi"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Nyuma"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Arifa"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Mikato ya Kibodi"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Badilisha mbinu ya kuingiza data"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Programu"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Programu ya maagizo ya sauti"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Kivinjari"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Anwani"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Barua pepe"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Ujumbe wa papo kwa papo"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Muziki"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalenda"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Onyesha katika vidhibiti vya sauti"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Usinisumbue"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Njia ya mkato ya vitufe vya sauti"</string> diff --git a/packages/SystemUI/res/values-sw410dp/config.xml b/packages/SystemUI/res/values-sw410dp/config.xml new file mode 100644 index 000000000000..08b2f8876470 --- /dev/null +++ b/packages/SystemUI/res/values-sw410dp/config.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2016, 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. +*/ +--> + +<!-- These resources are around just to allow their values to be customized + for different hardware and product builds. --> +<resources> + <integer name="quick_settings_num_rows">2</integer> +</resources> diff --git a/packages/SystemUI/res/values-sw410dp/dimens.xml b/packages/SystemUI/res/values-sw410dp/dimens.xml new file mode 100644 index 000000000000..5ce65241c9ca --- /dev/null +++ b/packages/SystemUI/res/values-sw410dp/dimens.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2016, 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. +*/ +--> + +<!-- These resources are around just to allow their values to be customized + for different hardware and product builds. --> +<resources> + <dimen name="qs_detail_items_padding_top">16dp</dimen> +</resources> diff --git a/packages/SystemUI/res/values-sw540dp/config.xml b/packages/SystemUI/res/values-sw540dp/config.xml new file mode 100644 index 000000000000..e554fc6dd4d1 --- /dev/null +++ b/packages/SystemUI/res/values-sw540dp/config.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2016, 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. +*/ +--> + +<!-- These resources are around just to allow their values to be customized + for different hardware and product builds. --> +<resources> + <integer name="quick_settings_num_rows">3</integer> +</resources> diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml index 4ed15d5c400b..49a7a299ec75 100644 --- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml @@ -40,4 +40,8 @@ <dimen name="battery_detail_graph_space_top">27dp</dimen> <dimen name="battery_detail_graph_space_bottom">27dp</dimen> + + <dimen name="qs_tile_margin_top">16dp</dimen> + <dimen name="qs_brightness_padding_top">6dp</dimen> + <dimen name="qs_detail_margin_top">28dp</dimen> </resources> diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml index 1c2f0deba5c1..5489be93b47f 100644 --- a/packages/SystemUI/res/values-ta-rIN/strings.xml +++ b/packages/SystemUI/res/values-ta-rIN/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> ஐ நிராகரி."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> விலக்கப்பட்டது."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"எல்லா சமீபத்திய பயன்பாடுகளும் விலக்கப்பட்டன."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ஐத் தொடங்குகிறது."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"அறிவிப்பு நிராகரிக்கப்பட்டது."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"முகப்பு"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"சமீபத்தியவை"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"முந்தையது"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"அறிவிப்புகள்"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"விசைப்பலகைக் குறுக்குவழிகள்"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"உள்ளீட்டு முறையை மாற்று"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"பயன்பாடுகள்"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"அசிஸ்ட்"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"உலாவி"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"தொடர்புகள்"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"மின்னஞ்சல்"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"மியூசிக்"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"கேலெண்டர்"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"ஒலிக் கட்டுப்பாடுகளுடன் காட்டு"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"தொந்தரவு செய்ய வேண்டாம்"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"ஒலியளவுப் பொத்தான்களுக்கான குறுக்குவழி"</string> diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml index bbefad299804..3a72809ac226 100644 --- a/packages/SystemUI/res/values-te-rIN/strings.xml +++ b/packages/SystemUI/res/values-te-rIN/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g>ని తీసివేయండి."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> తీసివేయబడింది."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"అన్ని ఇటీవలి అనువర్తనాలు తీసివేయబడ్డాయి."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g>ని ప్రారంభిస్తోంది."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"నోటిఫికేషన్ తీసివేయబడింది."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"హోమ్"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ఇటీవలివి"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"వెనుకకు"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"నోటిఫికేషన్లు"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"కీబోర్డ్ సత్వరమార్గాలు"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"ఇన్పుట్ పద్ధతిని మార్చండి"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"అనువర్తనాలు"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"సహాయకం"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"బ్రౌజర్"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"పరిచయాలు"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ఇమెయిల్"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"సంగీతం"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"క్యాలెండర్"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"వాల్యూమ్ నియంత్రణలతో చూపు"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"అంతరాయం కలిగించవద్దు"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"వాల్యూమ్ బటన్ల సత్వరమార్గం"</string> @@ -588,8 +602,8 @@ <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"స్థానం <xliff:g id="POSITION">%1$d</xliff:g>. ఎంచుకోవడానికి రెండుసార్లు నొక్కండి."</string> <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"<xliff:g id="TILE_NAME">%1$s</xliff:g>ని తరలిస్తుంది"</string> <string name="accessibility_qs_edit_remove_tile" msgid="7484493384665907197">"<xliff:g id="TILE_NAME">%1$s</xliff:g>ని తీసివేస్తుంది"</string> - <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"<xliff:g id="TILE_NAME">%1$s</xliff:g> స్థానం <xliff:g id="POSITION">%2$d</xliff:g>కి జోడించబడింది"</string> + <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g>వ స్థానానికి జోడించబడింది"</string> <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> తీసివేయబడింది"</string> - <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> స్థానం <xliff:g id="POSITION">%2$d</xliff:g>కి తరలించబడింది"</string> + <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="TILE_NAME">%1$s</xliff:g> <xliff:g id="POSITION">%2$d</xliff:g>వ స్థానానికి తరలించబడింది"</string> <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"శీఘ్ర సెట్టింగ్ల ఎడిటర్."</string> </resources> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 809d425177a6..4844c843df6c 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"ยกเลิก <xliff:g id="APP">%s</xliff:g>"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ถูกลบไปแล้ว"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"ปิดแอปพลิเคชันล่าสุดทั้งหมดแล้ว"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"กำลังเริ่มต้น <xliff:g id="APP">%s</xliff:g>"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"ปิดการแจ้งเตือนแล้ว"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"หน้าแรก"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"ล่าสุด"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"กลับ"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"การแจ้งเตือน"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"แป้นพิมพ์ลัด"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"สลับวิธีการป้อนข้อมูล"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"แอปพลิเคชัน"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"การสนับสนุน"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"เบราว์เซอร์"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"รายชื่อติดต่อ"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"อีเมล"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"เพลง"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"ปฏิทิน"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"แสดงพร้อมการควบคุมระดับเสียง"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"ห้ามรบกวน"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"ทางลัดปุ่มปรับระดับเสียง"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 7e6ff8adf3f8..0672959fccba 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"I-dismiss ang <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Hindi pinansin ang <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Na-dismiss ang lahat ng kamakailang application."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Sinisimulan ang <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Na-dismiss ang notification."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Home"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Mga Kamakailang Ginamit"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Bumalik"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Mga Notification"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Mga Keyboard Shortcut"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Magpalit ng pamamaraan ng pag-input"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Mga Application"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Tulong"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Browser"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Mga Contact"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Music"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Kalendaryo"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Ipakita nang may mga kontrol ng volume"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Huwag istorbohin"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Shortcut ng mga button ng volume"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index 05621a550c3a..58d488c50385 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> uygulamasını kapat."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> kaldırıldı."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Tüm son uygulamalar kapatıldı."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> başlatılıyor."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Bildirim kapatıldı."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ana ekran"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Son çağrılar"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Geri"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Bildirimler"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Klavye Kısayolları"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Giriş yöntemini değiştir"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Uygulamalar"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Asist"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Tarayıcı"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kişiler"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-posta"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Müzik"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Takvim"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Ses seviyesi kontrolleriyle göster"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Rahatsız etmeyin"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Ses düğmeleri kısayolu"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index ac796491e32f..c75891c7d484 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -170,6 +170,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Видалити додаток <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"Програму <xliff:g id="APP">%s</xliff:g> закрито."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Усі останні додатки закрито."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Запуск додатка <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Сповіщення відхилено."</string> @@ -530,6 +532,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Головний екран"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Останні"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Назад"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Сповіщення"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Комбінації клавіш"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Змінити метод введення"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Додатки"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Помічник"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Веб-переглядач"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Контакти"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Електронна пошта"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Чат"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Музика"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Календар"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Показувати регулятори гучності"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Не турбувати"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Кнопки гучності на корпусі"</string> diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml index a4a664b41de4..807a92379567 100644 --- a/packages/SystemUI/res/values-ur-rPK/strings.xml +++ b/packages/SystemUI/res/values-ur-rPK/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"<xliff:g id="APP">%s</xliff:g> کو مسترد کریں۔"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> کو ہٹا دیا گیا۔"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"سبھی حالیہ ایپلیکیشنز کو برخاست کر دیا گیا۔"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> شروع ہو رہی ہے۔"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"اطلاع مسترد ہوگئی۔"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"ہوم"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"حالیہ"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"پیچھے"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"اطلاعات"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"کی بورڈ شارٹ کٹس"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"اندراج کا طریقہ سوئچ کریں"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"ایپلیکیشنز"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"اسسٹ"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"براؤزر"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"رابطے"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"ای میل"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"موسیقی"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"کیلنڈر"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"والیوم کنٹرولز کے ساتھ دکھائیں"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"ڈسٹرب نہ کریں"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"والیوم بٹنز کے شارٹ کٹ"</string> @@ -591,5 +605,5 @@ <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"<xliff:g id="POSITION">%2$d</xliff:g> پوزیشن پر <xliff:g id="TILE_NAME">%1$s</xliff:g> شامل ہو گیا ہے"</string> <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"<xliff:g id="TILE_NAME">%1$s</xliff:g> ہٹا دیا گیا"</string> <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"<xliff:g id="POSITION">%2$d</xliff:g> پوزیشن پر <xliff:g id="TILE_NAME">%1$s</xliff:g> منتقل ہو گیا ہے"</string> - <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"فوری ترتیبات ایڈیٹر۔"</string> + <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"فوری ترتیبات کا ایڈیٹر۔"</string> </resources> diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml index f5bcc3dde6b9..fe67b527f913 100644 --- a/packages/SystemUI/res/values-uz-rUZ/strings.xml +++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Olib tashlash: <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> olib tashlangan."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Yaqinda ishlatilgan barcha ilovalar olib tashlandi."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"<xliff:g id="APP">%s</xliff:g> ishga tushirilmoqda."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Xabarnoma e‘tiborsiz qoldirildi."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Bosh ekran"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"So‘nggi ishlatilganlar"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Orqaga"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Bildirishnomalar"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Tezkor tugmalar"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Matn kiritish usulini o‘zgartirish"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Ilovalar"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Yordamchi"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Brauzer"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Kontaktlar"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"E-pochta"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Musiqa"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Taqvim"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Ovoz balandligini boshqarish tugmalari bilan ko‘rsatish"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Bezovta qilinmasin"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Ovoz balandligini boshqarish tugmalari"</string> @@ -563,7 +577,7 @@ <string name="select_keycode" msgid="7413765103381924584">"Klaviatura tugmasini tanlang"</string> <string name="preview" msgid="9077832302472282938">"Oldindan ko‘rish"</string> <string name="drag_to_add_tiles" msgid="7058945779098711293">"Fragmentlar qo‘shish uchun torting"</string> - <string name="drag_to_remove_tiles" msgid="3361212377437088062">"O‘chirish uchun bu yerga sudrang"</string> + <string name="drag_to_remove_tiles" msgid="3361212377437088062">"O‘chirish uchun bu yerga torting"</string> <string name="qs_edit" msgid="2232596095725105230">"Tahrirlash"</string> <string name="tuner_time" msgid="6572217313285536011">"Vaqt"</string> <string-array name="clock_options"> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index ed3e8f369c5b..ca7c59b72663 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Xóa bỏ <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> đã bị loại bỏ."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Đã bỏ qua tất cả các ứng dụng gần đây."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Bắt đầu <xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Đã loại bỏ thông báo."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Màn hình chính"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Gần đây"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Quay lại"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Thông báo"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Phím tắt"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Chuyển phương thức nhập"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Ứng dụng"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Trợ lý"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Trình duyệt"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Danh bạ"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"Email"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"Nhắn tin nhanh"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Âm nhạc"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Lịch"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Hiển thị với các điều khiển âm lượng"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Không làm phiền"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Phím tắt các nút âm lượng"</string> diff --git a/packages/SystemUI/res/values-w550dp-land/dimens.xml b/packages/SystemUI/res/values-w550dp-land/dimens.xml index cd17bedcec32..4160c83683cc 100644 --- a/packages/SystemUI/res/values-w550dp-land/dimens.xml +++ b/packages/SystemUI/res/values-w550dp-land/dimens.xml @@ -20,7 +20,4 @@ <dimen name="notification_panel_width">544dp</dimen> <dimen name="qs_expand_margin">32dp</dimen> - - <dimen name="battery_detail_graph_space_top">9dp</dimen> - <dimen name="battery_detail_graph_space_bottom">9dp</dimen> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 3b0c02302b3d..a25b9f125cc2 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -34,14 +34,14 @@ <string name="status_bar_latest_events_title" msgid="6594767438577593172">"通知"</string> <string name="battery_low_title" msgid="6456385927409742437">"电池电量偏低"</string> <string name="battery_low_percent_format" msgid="2900940511201380775">"剩余<xliff:g id="PERCENTAGE">%s</xliff:g>"</string> - <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"剩余<xliff:g id="PERCENTAGE">%s</xliff:g>。节电助手已开启。"</string> + <string name="battery_low_percent_format_saver_started" msgid="6859235584035338833">"剩余<xliff:g id="PERCENTAGE">%s</xliff:g>。省电模式已开启。"</string> <string name="invalid_charger" msgid="4549105996740522523">"不支持USB充电功能。\n只能使用随附的充电器充电。"</string> <string name="invalid_charger_title" msgid="3515740382572798460">"不支持USB充电。"</string> <string name="invalid_charger_text" msgid="5474997287953892710">"仅限使用设备随附的充电器。"</string> <string name="battery_low_why" msgid="4553600287639198111">"设置"</string> - <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"要开启节电助手吗?"</string> + <string name="battery_saver_confirmation_title" msgid="5299585433050361634">"要开启省电模式吗?"</string> <string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"开启"</string> - <string name="battery_saver_start_action" msgid="5576697451677486320">"开启节电助手"</string> + <string name="battery_saver_start_action" msgid="5576697451677486320">"开启省电模式"</string> <string name="status_bar_settings_settings_button" msgid="3023889916699270224">"设置"</string> <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"WLAN"</string> <string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"自动旋转屏幕"</string> @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"移除<xliff:g id="APP">%s</xliff:g>。"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"已删除<xliff:g id="APP">%s</xliff:g>"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"已关闭所有最近用过的应用。"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"正在启动<xliff:g id="APP">%s</xliff:g>。"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"已关闭通知。"</string> @@ -371,9 +373,9 @@ <string name="user_remove_user_title" msgid="4681256956076895559">"是否移除用户?"</string> <string name="user_remove_user_message" msgid="1453218013959498039">"此用户的所有应用和数据均将被删除。"</string> <string name="user_remove_user_remove" msgid="7479275741742178297">"移除"</string> - <string name="battery_saver_notification_title" msgid="237918726750955859">"节电助手已开启"</string> + <string name="battery_saver_notification_title" msgid="237918726750955859">"省电模式已开启"</string> <string name="battery_saver_notification_text" msgid="820318788126672692">"降低性能并限制后台流量"</string> - <string name="battery_saver_notification_action_text" msgid="109158658238110382">"关闭节电助手"</string> + <string name="battery_saver_notification_action_text" msgid="109158658238110382">"关闭省电模式"</string> <string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g>将开始截取您的屏幕上显示的所有内容。"</string> <string name="media_projection_remember_text" msgid="3103510882172746752">"不再显示"</string> <string name="clear_all_notifications_text" msgid="814192889771462828">"全部清除"</string> @@ -495,8 +497,8 @@ <string name="color_revert_title" msgid="4746666545480534663">"确认设置"</string> <string name="color_revert_message" msgid="9116001069397996691">"部分颜色设置可能会导致此设备无法使用。请点击“确定”确认这些颜色设置,否则,系统将在 10 秒后重置这些设置。"</string> <string name="battery_panel_title" msgid="7944156115535366613">"电池使用情况"</string> - <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充电过程中无法使用节电助手"</string> - <string name="battery_detail_switch_title" msgid="6285872470260795421">"节电助手"</string> + <string name="battery_detail_charging_summary" msgid="1279095653533044008">"充电过程中无法使用省电模式"</string> + <string name="battery_detail_switch_title" msgid="6285872470260795421">"省电模式"</string> <string name="battery_detail_switch_summary" msgid="9049111149407626804">"降低性能并限制后台流量"</string> <string name="keyboard_key_button_template" msgid="6230056639734377300">"<xliff:g id="NAME">%1$s</xliff:g>按钮"</string> <string name="keyboard_key_home" msgid="2243500072071305073">"Home"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主屏幕"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"返回"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"通知"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"键盘快捷键"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"切换输入法"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"应用"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"辅助应用"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"浏览器"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"通讯录"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"电子邮件"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"即时通讯"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"音乐"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"日历"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"与音量控件一起显示"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"请勿打扰"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"音量按钮快捷键"</string> @@ -583,7 +597,7 @@ <string name="accessibility_action_divider_move_left" msgid="9218189832115847253">"左移"</string> <string name="accessibility_action_divider_move_right" msgid="4671522715182567972">"右移"</string> <string name="forced_resizable_info_text" msgid="7591061837558867999">"应用可能无法在多窗口模式下正常运行"</string> - <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"位置 <xliff:g id="POSITION">%1$d</xliff:g>,<xliff:g id="TILE_NAME">%2$s</xliff:g>。点按再次即可修改。"</string> + <string name="accessibility_qs_edit_tile_label" msgid="8374924053307764245">"位置 <xliff:g id="POSITION">%1$d</xliff:g>,<xliff:g id="TILE_NAME">%2$s</xliff:g>。点按两次即可修改。"</string> <string name="accessibility_qs_edit_add_tile_label" msgid="8133209638023882667">"<xliff:g id="TILE_NAME">%1$s</xliff:g>。点按两次即可添加。"</string> <string name="accessibility_qs_edit_position_label" msgid="5055306305919289819">"位置 <xliff:g id="POSITION">%1$d</xliff:g>。点按两次即可选择。"</string> <string name="accessibility_qs_edit_move_tile" msgid="2461819993780159542">"移动<xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> @@ -591,5 +605,5 @@ <string name="accessibility_qs_edit_tile_added" msgid="8050200862063548309">"已将<xliff:g id="TILE_NAME">%1$s</xliff:g>添加到位置 <xliff:g id="POSITION">%2$d</xliff:g>"</string> <string name="accessibility_qs_edit_tile_removed" msgid="8584304916627913440">"已移除<xliff:g id="TILE_NAME">%1$s</xliff:g>"</string> <string name="accessibility_qs_edit_tile_moved" msgid="4343693412689365038">"已将<xliff:g id="TILE_NAME">%1$s</xliff:g>移至位置 <xliff:g id="POSITION">%2$d</xliff:g>"</string> - <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"快速设置编辑器。"</string> + <string name="accessibility_desc_quick_settings_edit" msgid="8073587401747016103">"快捷设置编辑器。"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index dc4a6dd90a67..083cd5eb035d 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"關閉「<xliff:g id="APP">%s</xliff:g>」。"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"「<xliff:g id="APP">%s</xliff:g>」已關閉。"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"所有最近使用的應用程式均已關閉。"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"正在啟動「<xliff:g id="APP">%s</xliff:g>」。"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g><xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"通知已關閉。"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"最近的活動"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"返回"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"通知"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"鍵盤快速鍵"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"切換輸入法"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"應用程式"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"輔助"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"瀏覽器"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"通訊錄"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"電郵"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"即時通訊"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"音樂"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"日曆"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"與音量控制一起顯示"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"請勿騷擾"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"音量按鈕快速鍵"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index 72ff27c8b942..3c95a9397cc6 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"關閉「<xliff:g id="APP">%s</xliff:g>」。"</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"「<xliff:g id="APP">%s</xliff:g>」已關閉。"</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"最近使用的應用程式已全部關閉。"</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"正在啟動「<xliff:g id="APP">%s</xliff:g>」。"</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"已關閉通知。"</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"主畫面"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"近期活動"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"返回"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"通知"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"鍵盤快速鍵"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"切換輸入法"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"應用程式"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"小幫手"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"瀏覽器"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"聯絡人"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"電子郵件"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"即時訊息"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"音樂"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"日曆"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"與音量控制項一起顯示"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"零打擾"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"音量按鈕快速鍵"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 2eb96813c126..e03e6422ca22 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -168,6 +168,8 @@ <string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Cashisa i-<xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_item_dismissed" msgid="6803574935084867070">"<xliff:g id="APP">%s</xliff:g> ivaliwe."</string> <string name="accessibility_recents_all_items_dismissed" msgid="4464697366179168836">"Zonke izinhlelo zokusebenza zakamuva zicashisiwe."</string> + <!-- no translation found for accessibility_recents_item_open_app_info (5107479759905883540) --> + <skip /> <string name="accessibility_recents_item_launched" msgid="7616039892382525203">"Iqala i-<xliff:g id="APP">%s</xliff:g>."</string> <string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string> <string name="accessibility_notification_dismissed" msgid="854211387186306927">"Isaziso sichithiwe."</string> @@ -528,6 +530,18 @@ <string name="keyboard_shortcut_group_system_home" msgid="3054369431319891965">"Ekhaya"</string> <string name="keyboard_shortcut_group_system_recents" msgid="3154851905021926744">"Okwakamuva"</string> <string name="keyboard_shortcut_group_system_back" msgid="2207004531216446378">"Emuva"</string> + <string name="keyboard_shortcut_group_system_notifications" msgid="8366964080041773224">"Izaziso"</string> + <string name="keyboard_shortcut_group_system_shortcuts_helper" msgid="4892255911160332762">"Izinqamulelo Zekhibhodi"</string> + <string name="keyboard_shortcut_group_system_switch_input" msgid="2334164096341310324">"Shintsha indlela yokufaka"</string> + <string name="keyboard_shortcut_group_applications" msgid="9129465955073449206">"Izinhlelo zokusebenza"</string> + <string name="keyboard_shortcut_group_applications_assist" msgid="9095441910537146013">"Siza"</string> + <string name="keyboard_shortcut_group_applications_browser" msgid="6465985474000766533">"Isiphequluli"</string> + <string name="keyboard_shortcut_group_applications_contacts" msgid="2064197111278436375">"Oxhumana nabo"</string> + <string name="keyboard_shortcut_group_applications_email" msgid="6257036897441939004">"I-imeyili"</string> + <string name="keyboard_shortcut_group_applications_im" msgid="1892749399083161405">"I-IM"</string> + <string name="keyboard_shortcut_group_applications_music" msgid="4775559515850922780">"Umculo"</string> + <string name="keyboard_shortcut_group_applications_youtube" msgid="6555453761294723317">"I-YouTube"</string> + <string name="keyboard_shortcut_group_applications_calendar" msgid="9043614299194991263">"Ikhalenda"</string> <string name="tuner_full_zen_title" msgid="4540823317772234308">"Bonisa ngezilawuli zevolomu"</string> <string name="volume_and_do_not_disturb" msgid="3373784330208603030">"Ungaphazamisi"</string> <string name="volume_dnd_silent" msgid="4363882330723050727">"Izinqamuleli zezinkinobho zevolomu"</string> diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml index 1e979fda17bd..6dd8c5260b89 100644 --- a/packages/SystemUI/res/values/attrs.xml +++ b/packages/SystemUI/res/values/attrs.xml @@ -97,5 +97,9 @@ <declare-styleable name="DensityContainer"> <attr name="android:layout" /> </declare-styleable> + + <declare-styleable name="AutoSizingList"> + <attr name="itemHeight" format="dimension" /> + </declare-styleable> </resources> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index b9aa26b0c785..b874e7c051db 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -169,6 +169,8 @@ <color name="ksh_system_group_color">#ff00bcd4</color> <color name="ksh_application_group_color">#fff44336</color> <color name="ksh_keyword_color">#d9000000</color> + <color name="ksh_key_item_color">@color/material_grey_600</color> + <color name="ksh_key_item_background">#eeeeee</color> <!-- Background color of edit overflow --> <color name="qs_edit_overflow_bg">#455A64</color> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index fd051b1b371f..42798a49b3af 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -92,11 +92,8 @@ <!-- The number of columns in the QuickSettings --> <integer name="quick_settings_num_columns">3</integer> - <!-- The maximum number of rows in the QuickSettings --> - <integer name="quick_settings_max_rows">4</integer> - - <!-- The maximum number of rows in the QuickSettings when on the keyguard --> - <integer name="quick_settings_max_rows_keyguard">3</integer> + <!-- The number of rows in the QuickSettings --> + <integer name="quick_settings_num_rows">1</integer> <!-- The number of columns that the top level tiles span in the QuickSettings --> <integer name="quick_settings_user_time_settings_tile_span">1</integer> @@ -116,9 +113,6 @@ <integer name="quick_settings_brightness_dialog_short_timeout">2000</integer> <integer name="quick_settings_brightness_dialog_long_timeout">4000</integer> - <!-- The maximum number of items to be displayed in quick settings --> - <integer name="quick_settings_detail_max_item_count">5</integer> - <!-- Should "4G" be shown instead of "LTE" when the network is NETWORK_TYPE_LTE? --> <bool name="config_show4GForLTE">true</bool> @@ -178,7 +172,7 @@ <!-- Recents: The relative range of visible tasks from the current scroll position while the stack is focused. --> <item name="recents_layout_focused_range_min" format="float" type="integer">-3</item> - <item name="recents_layout_focused_range_max" format="float" type="integer">3</item> + <item name="recents_layout_focused_range_max" format="float" type="integer">2</item> <!-- Recents: The relative range of visible tasks from the current scroll position while the stack is not focused. --> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index c094da9db43a..a4eadbfb5601 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -172,6 +172,7 @@ <dimen name="qs_tile_height">88dp</dimen> <dimen name="qs_tile_margin">16dp</dimen> + <dimen name="qs_tile_margin_top">16dp</dimen> <dimen name="qs_quick_tile_size">48dp</dimen> <dimen name="qs_quick_tile_padding">12dp</dimen> <dimen name="qs_date_anim_translation">32dp</dimen> @@ -201,10 +202,12 @@ <dimen name="qs_detail_item_primary_text_size">16sp</dimen> <dimen name="qs_detail_item_secondary_text_size">14sp</dimen> <dimen name="qs_detail_empty_text_size">14sp</dimen> + <dimen name="qs_detail_margin_top">28dp</dimen> <dimen name="qs_data_usage_text_size">14sp</dimen> <dimen name="qs_data_usage_usage_text_size">36sp</dimen> <dimen name="qs_expand_margin">0dp</dimen> <dimen name="qs_battery_padding">2dp</dimen> + <dimen name="qs_detail_items_padding_top">4dp</dimen> <dimen name="segmented_button_spacing">0dp</dimen> <dimen name="borderless_button_radius">2dp</dimen> @@ -561,6 +564,9 @@ <!-- Keyboard shortcuts helper --> <dimen name="ksh_layout_width">@dimen/match_parent</dimen> + <dimen name="ksh_item_text_size">14sp</dimen> + <dimen name="ksh_item_padding">4dp</dimen> + <dimen name="ksh_item_margin_start">4dp</dimen> <!-- Recents Layout --> diff --git a/packages/SystemUI/res/values/dimens_tv.xml b/packages/SystemUI/res/values/dimens_tv.xml index 337513d4daea..4e6a4b1b8212 100644 --- a/packages/SystemUI/res/values/dimens_tv.xml +++ b/packages/SystemUI/res/values/dimens_tv.xml @@ -54,5 +54,7 @@ <!-- Extra space around the PIP and its outline in PIP onboarding activity --> <dimen name="tv_pip_bounds_space">3dp</dimen> + <!-- Extra space around the PIP control button icon to match with the focused circle --> + <dimen name="tv_pip_button_icon_padding">5dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index a01066d70262..060e050ed97c 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -417,6 +417,8 @@ <string name="accessibility_recents_item_dismissed"><xliff:g id="app" example="Calendar">%s</xliff:g> dismissed.</string> <!-- Content description to tell the user all applications has been removed from recents --> <string name="accessibility_recents_all_items_dismissed">All recent applications dismissed.</string> + <!-- Content description to tell the user that this button will open application info for an application in recents --> + <string name="accessibility_recents_item_open_app_info">Open <xliff:g id="app" example="Calendar">%s</xliff:g> application info.</string> <!-- Content description to tell the user an application has been launched from recents --> <string name="accessibility_recents_item_launched">Starting <xliff:g id="app" example="Calendar">%s</xliff:g>.</string> <!-- Content description of individual recents task. --> diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java index aa3f6e5fe4a3..d12ab293ab3e 100644 --- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java +++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java @@ -514,7 +514,7 @@ public class ExpandHelper implements Gefingerpoken { if (canBeExpanded) { if (DEBUG) Log.d(TAG, "working on an expandable child"); mNaturalHeight = mScaler.getNaturalHeight(); - mSmallSize = v.getMinExpandHeight(); + mSmallSize = v.getCollapsedHeight(); } else { if (DEBUG) Log.d(TAG, "working on a non-expandable child"); mNaturalHeight = mOldHeight; diff --git a/packages/SystemUI/src/com/android/systemui/ResizingSpace.java b/packages/SystemUI/src/com/android/systemui/ResizingSpace.java new file mode 100644 index 000000000000..c2bc53e7d553 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/ResizingSpace.java @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui; + +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup.LayoutParams; + +public class ResizingSpace extends View { + + private final int mWidth; + private final int mHeight; + + public ResizingSpace(Context context, AttributeSet attrs) { + super(context, attrs); + if (getVisibility() == VISIBLE) { + setVisibility(INVISIBLE); + } + TypedArray a = context.obtainStyledAttributes(attrs, android.R.styleable.ViewGroup_Layout); + mWidth = a.getResourceId(android.R.styleable.ViewGroup_Layout_layout_width, 0); + mHeight = a.getResourceId(android.R.styleable.ViewGroup_Layout_layout_height, 0); + } + + @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + LayoutParams params = getLayoutParams(); + boolean changed = false; + if (mWidth > 0) { + int width = getContext().getResources().getDimensionPixelOffset(mWidth); + if (width != params.width) { + params.width = width; + changed = true; + } + } + if (mHeight > 0) { + int height = getContext().getResources().getDimensionPixelOffset(mHeight); + if (height != params.height) { + params.height = height; + changed = true; + } + } + if (changed) { + setLayoutParams(params); + } + } + + /** + * Draw nothing. + * + * @param canvas an unused parameter. + */ + @Override + public void draw(Canvas canvas) { + } + + /** + * Compare to: {@link View#getDefaultSize(int, int)} + * If mode is AT_MOST, return the child size instead of the parent size + * (unless it is too big). + */ + private static int getDefaultSize2(int size, int measureSpec) { + int result = size; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + switch (specMode) { + case MeasureSpec.UNSPECIFIED: + result = size; + break; + case MeasureSpec.AT_MOST: + result = Math.min(size, specSize); + break; + case MeasureSpec.EXACTLY: + result = specSize; + break; + } + return result; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension( + getDefaultSize2(getSuggestedMinimumWidth(), widthMeasureSpec), + getDefaultSize2(getSuggestedMinimumHeight(), heightMeasureSpec)); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index 8f79bdabedc9..e83819179c24 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -325,10 +325,11 @@ public class SwipeHelper implements Gefingerpoken { /** * @param view The view to be dismissed * @param velocity The desired pixels/second speed at which the view should move + * @param useAccelerateInterpolator Should an accelerating Interpolator be used */ - public void dismissChild(final View view, float velocity) { + public void dismissChild(final View view, float velocity, boolean useAccelerateInterpolator) { dismissChild(view, velocity, null /* endAction */, 0 /* delay */, - velocity == 0 /* useAccelerateInterpolator */, 0 /* fixedDuration */); + useAccelerateInterpolator, 0 /* fixedDuration */, false /* isDismissAll */); } /** @@ -340,17 +341,22 @@ public class SwipeHelper implements Gefingerpoken { * @param fixedDuration If not 0, this exact duration will be taken */ public void dismissChild(final View animView, float velocity, final Runnable endAction, - long delay, boolean useAccelerateInterpolator, long fixedDuration) { + long delay, boolean useAccelerateInterpolator, long fixedDuration, + boolean isDismissAll) { final boolean canBeDismissed = mCallback.canChildBeDismissed(animView); float newPos; boolean isLayoutRtl = animView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; - if (velocity < 0 - || (velocity == 0 && getTranslation(animView) < 0) - // if we use the Menu to dismiss an item in landscape, animate up - || (velocity == 0 && getTranslation(animView) == 0 && mSwipeDirection == Y) - // if the language is rtl we prefer swiping to the left - || (velocity == 0 && getTranslation(animView) == 0 && isLayoutRtl)) { + // if we use the Menu to dismiss an item in landscape, animate up + boolean animateUpForMenu = velocity == 0 && (getTranslation(animView) == 0 || isDismissAll) + && mSwipeDirection == Y; + // if the language is rtl we prefer swiping to the left + boolean animateLeftForRtl = velocity == 0 && (getTranslation(animView) == 0 || isDismissAll) + && isLayoutRtl; + boolean animateLeft = velocity < 0 + || (velocity == 0 && getTranslation(animView) < 0 && !isDismissAll); + + if (animateLeft || animateLeftForRtl || animateUpForMenu) { newPos = -getSize(animView); } else { newPos = getSize(animView); @@ -569,7 +575,8 @@ public class SwipeHelper implements Gefingerpoken { if (!handleUpEvent(ev, mCurrView, velocity, getTranslation(mCurrView))) { if (isDismissGesture(ev)) { // flingadingy - dismissChild(mCurrView, swipedFastEnough() ? velocity : 0f); + dismissChild(mCurrView, velocity, + !swipedFastEnough() /* useAccelerateInterpolator */); } else { // snappity mCallback.onDragCancelled(mCurrView); @@ -615,11 +622,9 @@ public class SwipeHelper implements Gefingerpoken { protected boolean swipedFastEnough() { float velocity = getVelocity(mVelocityTracker); - float perpendicularVelocity = getPerpendicularVelocity(mVelocityTracker); float translation = getTranslation(mCurrView); - boolean ret = (Math.abs(velocity) > getEscapeVelocity()) && - (Math.abs(velocity) > Math.abs(perpendicularVelocity)) && - (velocity > 0) == (translation > 0); + boolean ret = (Math.abs(velocity) > getEscapeVelocity()) + && (velocity > 0) == (translation > 0); return ret; } diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java index b2b612787fd2..455a69fcc77b 100644 --- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java +++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java @@ -123,6 +123,17 @@ public class SystemUIApplication extends Application { startServicesIfNeeded(SERVICES); } + /** + * Ensures that all the Secondary user SystemUI services are running. If they are already + * running, this is a no-op. This is needed to conditinally start all the services, as we only + * need to have it in the main process. + * + * <p>This method must only be called from the main thread.</p> + */ + void startSecondaryUserServicesIfNeeded() { + startServicesIfNeeded(SERVICES_PER_USER); + } + private void startServicesIfNeeded(Class<?>[] services) { if (mServicesStarted) { return; diff --git a/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java b/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java new file mode 100644 index 000000000000..f619bfbcd047 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/SystemUISecondaryUserService.java @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui; + +import android.app.ActivityManager; +import android.app.Service; +import android.content.Intent; +import android.os.IBinder; +import android.os.Process; + +import java.io.FileDescriptor; +import java.io.PrintWriter; + +public class SystemUISecondaryUserService extends Service { + + @Override + public void onCreate() { + super.onCreate(); + ((SystemUIApplication) getApplication()).startSecondaryUserServicesIfNeeded(); + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + SystemUI[] services = ((SystemUIApplication) getApplication()).getServices(); + if (args == null || args.length == 0) { + for (SystemUI ui: services) { + pw.println("dumping service: " + ui.getClass().getName()); + ui.dump(fd, pw, args); + } + } else { + String svc = args[0]; + for (SystemUI ui: services) { + String name = ui.getClass().getName(); + if (name.endsWith(svc)) { + ui.dump(fd, pw, args); + } + } + } + } +} + diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java index d2c60efd1282..84d359926c50 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java @@ -115,9 +115,9 @@ public class KeyguardService extends Service { } @Override // Binder interface - public void onFinishedGoingToSleep(int reason) { + public void onFinishedGoingToSleep(int reason, boolean cameraGestureTriggered) { checkPermission(); - mKeyguardViewMediator.onFinishedGoingToSleep(reason); + mKeyguardViewMediator.onFinishedGoingToSleep(reason, cameraGestureTriggered); } @Override // Binder interface diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index a5dfc4b2ad85..66754a7fa80c 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -747,7 +747,7 @@ public class KeyguardViewMediator extends SystemUI { notifyStartedGoingToSleep(); } - public void onFinishedGoingToSleep(int why) { + public void onFinishedGoingToSleep(int why, boolean cameraGestureTriggered) { if (DEBUG) Log.d(TAG, "onFinishedGoingToSleep(" + why + ")"); synchronized (this) { mDeviceInteractive = false; @@ -758,6 +758,16 @@ public class KeyguardViewMediator extends SystemUI { notifyFinishedGoingToSleep(); + if (cameraGestureTriggered) { + Log.i(TAG, "Camera gesture was triggered, preventing Keyguard locking."); + + // Just to make sure, make sure the device is awake. + mContext.getSystemService(PowerManager.class).wakeUp(SystemClock.uptimeMillis(), + "com.android.systemui:CAMERA_GESTURE_PREVENT_LOCK"); + mPendingLock = false; + mPendingReset = false; + } + if (mPendingReset) { resetStateLocked(); mPendingReset = false; @@ -771,7 +781,7 @@ public class KeyguardViewMediator extends SystemUI { // We do not have timeout and power button instant lock setting for profile lock. // So we use the personal setting if there is any. But if there is no device // we need to make sure we lock it immediately when the screen is off. - if (!mLockLater) { + if (!mLockLater && !cameraGestureTriggered) { doKeyguardForChildProfilesLocked(); } @@ -794,7 +804,7 @@ public class KeyguardViewMediator extends SystemUI { // From DevicePolicyAdmin final long policyTimeout = mLockPatternUtils.getDevicePolicyManager() - .getMaximumTimeToLock(null, userId); + .getMaximumTimeToLockForUserAndProfiles(userId); long timeout; diff --git a/packages/SystemUI/src/com/android/systemui/qs/AutoSizingList.java b/packages/SystemUI/src/com/android/systemui/qs/AutoSizingList.java new file mode 100644 index 000000000000..00e62213ff46 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/AutoSizingList.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.qs; + +import android.annotation.Nullable; +import android.content.Context; +import android.content.res.TypedArray; +import android.database.DataSetObserver; +import android.os.Handler; +import android.util.AttributeSet; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ListAdapter; +import com.android.systemui.R; + +/** + * Similar to a ListView, but it will show only as many items as fit on screen and + * bind those instead of scrolling. + */ +public class AutoSizingList extends LinearLayout { + + private static final String TAG = "AutoSizingList"; + private final int mItemSize; + private final Handler mHandler; + + private ListAdapter mAdapter; + private int mCount; + + public AutoSizingList(Context context, @Nullable AttributeSet attrs) { + super(context, attrs); + + mHandler = new Handler(); + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.AutoSizingList); + mItemSize = a.getDimensionPixelSize(R.styleable.AutoSizingList_itemHeight, 0); + } + + public void setAdapter(ListAdapter adapter) { + if (mAdapter != null) { + mAdapter.unregisterDataSetObserver(mDataObserver); + } + mAdapter = adapter; + if (adapter != null) { + adapter.registerDataSetObserver(mDataObserver); + } + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int requestedHeight = MeasureSpec.getSize(heightMeasureSpec); + if (requestedHeight != 0) { + int count = Math.min(requestedHeight / mItemSize, getDesiredCount()); + if (mCount != count) { + postRebindChildren(); + mCount = count; + } + } + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + } + + private int getDesiredCount() { + return mAdapter != null ? mAdapter.getCount() : 0; + } + + private void postRebindChildren() { + mHandler.post(mBindChildren); + } + + private void rebindChildren() { + if (mAdapter == null) { + return; + } + for (int i = 0; i < mCount; i++) { + View v = i < getChildCount() ? getChildAt(i) : null; + View newView = mAdapter.getView(i, v, this); + if (newView != v) { + if (v != null) { + removeView(v); + } + addView(newView, i); + } + } + // Ditch extra views. + while (getChildCount() > mCount) { + removeViewAt(getChildCount() - 1); + } + } + + private final Runnable mBindChildren = new Runnable() { + @Override + public void run() { + rebindChildren(); + } + }; + + private final DataSetObserver mDataObserver = new DataSetObserver() { + @Override + public void onChanged() { + if (mCount > getDesiredCount()) { + mCount = getDesiredCount(); + } + postRebindChildren(); + } + + @Override + public void onInvalidated() { + postRebindChildren(); + } + }; +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java index 115c9d0e06fb..5a236104806f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java @@ -1,6 +1,8 @@ package com.android.systemui.qs; import android.content.Context; +import android.content.res.Configuration; +import android.content.res.Resources; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.util.AttributeSet; @@ -199,11 +201,22 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout { @Override public boolean updateResources() { - if (super.updateResources()) { - mMaxRows = mColumns != 3 ? 2 : 3; - return true; + final int rows = getRows(); + boolean changed = rows != mMaxRows; + if (changed) { + mMaxRows = rows; + requestLayout(); } - return false; + return super.updateResources() || changed; + } + + private int getRows() { + final Resources res = getContext().getResources(); + if (res.getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { + // Always have 3 rows in portrait. + return 3; + } + return Math.max(1, res.getInteger(R.integer.quick_settings_num_rows)); } public void setMaxRows(int maxRows) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java index 5d06aebdba66..0af5fa62d219 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java @@ -100,7 +100,13 @@ public class QSContainer extends FrameLayout { // Since we control our own bottom, be whatever size we want. // Otherwise the QSPanel ends up with 0 height when the window is only the // size of the status bar. - super.onMeasure(widthMeasureSpec, MeasureSpec.UNSPECIFIED); + mQSPanel.measure(widthMeasureSpec, MeasureSpec.makeMeasureSpec( + MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.UNSPECIFIED)); + int width = mQSPanel.getMeasuredWidth(); + int height = ((LayoutParams) mQSPanel.getLayoutParams()).topMargin + + mQSPanel.getMeasuredHeight(); + super.onMeasure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); // QSCustomizer is always be the height of the screen, but do this after // other measuring to avoid changing the height of the QSContainer. diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java b/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java index 25b91054af89..2dd4a0ab76eb 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSDetailItems.java @@ -28,11 +28,10 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.ImageView; -import android.widget.LinearLayout; import android.widget.TextView; - import com.android.systemui.FontSizeUtils; import com.android.systemui.R; @@ -45,16 +44,17 @@ public class QSDetailItems extends FrameLayout { private final Context mContext; private final H mHandler = new H(); + private final Adapter mAdapter = new Adapter(); private String mTag; private Callback mCallback; private boolean mItemsVisible = true; - private LinearLayout mItems; + private AutoSizingList mItemList; private View mEmpty; - private View mMinHeightSpacer; private TextView mEmptyText; private ImageView mEmptyIcon; - private int mMaxItems; + + private Item[] mItems; public QSDetailItems(Context context, AttributeSet attrs) { super(context, attrs); @@ -73,27 +73,22 @@ public class QSDetailItems extends FrameLayout { @Override protected void onFinishInflate() { super.onFinishInflate(); - mItems = (LinearLayout) findViewById(android.R.id.list); - mItems.setVisibility(GONE); + mItemList = (AutoSizingList) findViewById(android.R.id.list); + mItemList.setVisibility(GONE); + mItemList.setAdapter(mAdapter); mEmpty = findViewById(android.R.id.empty); mEmpty.setVisibility(GONE); mEmptyText = (TextView) mEmpty.findViewById(android.R.id.title); mEmptyIcon = (ImageView) mEmpty.findViewById(android.R.id.icon); - mMinHeightSpacer = findViewById(R.id.min_height_spacer); - - // By default, a detail item view has fixed size. - mMaxItems = getResources().getInteger( - R.integer.quick_settings_detail_max_item_count); - setMinHeightInItems(mMaxItems); } @Override protected void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); FontSizeUtils.updateFontSize(mEmptyText, R.dimen.qs_detail_empty_text_size); - int count = mItems.getChildCount(); + int count = mItemList.getChildCount(); for (int i = 0; i < count; i++) { - View item = mItems.getChildAt(i); + View item = mItemList.getChildAt(i); FontSizeUtils.updateFontSize(item, android.R.id.title, R.dimen.qs_detail_item_primary_text_size); FontSizeUtils.updateFontSize(item, android.R.id.summary, @@ -110,16 +105,6 @@ public class QSDetailItems extends FrameLayout { mEmptyText.setText(text); } - /** - * Set the minimum height of this detail view, in item count. - */ - public void setMinHeightInItems(int minHeightInItems) { - ViewGroup.LayoutParams lp = mMinHeightSpacer.getLayoutParams(); - lp.height = minHeightInItems * getResources().getDimensionPixelSize( - R.dimen.qs_detail_item_height); - mMinHeightSpacer.setLayoutParams(lp); - } - @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); @@ -153,65 +138,82 @@ public class QSDetailItems extends FrameLayout { } private void handleSetItems(Item[] items) { - final int itemCount = items != null ? Math.min(items.length, mMaxItems) : 0; + final int itemCount = items != null ? items.length : 0; mEmpty.setVisibility(itemCount == 0 ? VISIBLE : GONE); - mItems.setVisibility(itemCount == 0 ? GONE : VISIBLE); - for (int i = mItems.getChildCount() - 1; i >= itemCount; i--) { - mItems.removeViewAt(i); - } - for (int i = 0; i < itemCount; i++) { - bind(items[i], mItems.getChildAt(i)); - } + mItemList.setVisibility(itemCount == 0 ? GONE : VISIBLE); + mItems = items; + mAdapter.notifyDataSetChanged(); } private void handleSetItemsVisible(boolean visible) { if (mItemsVisible == visible) return; mItemsVisible = visible; - for (int i = 0; i < mItems.getChildCount(); i++) { - mItems.getChildAt(i).setVisibility(mItemsVisible ? VISIBLE : INVISIBLE); + for (int i = 0; i < mItemList.getChildCount(); i++) { + mItemList.getChildAt(i).setVisibility(mItemsVisible ? VISIBLE : INVISIBLE); } } - private void bind(final Item item, View view) { - if (view == null) { - view = LayoutInflater.from(mContext).inflate(R.layout.qs_detail_item, this, false); - mItems.addView(view); + private class Adapter extends BaseAdapter { + + @Override + public int getCount() { + return mItems != null ? mItems.length : 0; + } + + @Override + public Object getItem(int position) { + return mItems[position]; } - view.setVisibility(mItemsVisible ? VISIBLE : INVISIBLE); - final ImageView iv = (ImageView) view.findViewById(android.R.id.icon); - iv.setImageResource(item.icon); - iv.getOverlay().clear(); - if (item.overlay != null) { - item.overlay.setBounds(0, 0, item.overlay.getIntrinsicWidth(), - item.overlay.getIntrinsicHeight()); - iv.getOverlay().add(item.overlay); + + @Override + public long getItemId(int position) { + return 0; } - final TextView title = (TextView) view.findViewById(android.R.id.title); - title.setText(item.line1); - final TextView summary = (TextView) view.findViewById(android.R.id.summary); - final boolean twoLines = !TextUtils.isEmpty(item.line2); - title.setMaxLines(twoLines ? 1 : 2); - summary.setVisibility(twoLines ? VISIBLE : GONE); - summary.setText(twoLines ? item.line2 : null); - view.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - if (mCallback != null) { - mCallback.onDetailItemClick(item); - } + + @Override + public View getView(int position, View view, ViewGroup parent) { + final Item item = mItems[position]; + if (view == null) { + view = LayoutInflater.from(mContext).inflate(R.layout.qs_detail_item, parent, + false); } - }); - final ImageView disconnect = (ImageView) view.findViewById(android.R.id.icon2); - disconnect.setVisibility(item.canDisconnect ? VISIBLE : GONE); - disconnect.setOnClickListener(new OnClickListener() { - @Override - public void onClick(View v) { - if (mCallback != null) { - mCallback.onDetailItemDisconnect(item); - } + view.setVisibility(mItemsVisible ? VISIBLE : INVISIBLE); + final ImageView iv = (ImageView) view.findViewById(android.R.id.icon); + iv.setImageResource(item.icon); + iv.getOverlay().clear(); + if (item.overlay != null) { + item.overlay.setBounds(0, 0, item.overlay.getIntrinsicWidth(), + item.overlay.getIntrinsicHeight()); + iv.getOverlay().add(item.overlay); } - }); - } + final TextView title = (TextView) view.findViewById(android.R.id.title); + title.setText(item.line1); + final TextView summary = (TextView) view.findViewById(android.R.id.summary); + final boolean twoLines = !TextUtils.isEmpty(item.line2); + title.setMaxLines(twoLines ? 1 : 2); + summary.setVisibility(twoLines ? VISIBLE : GONE); + summary.setText(twoLines ? item.line2 : null); + view.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (mCallback != null) { + mCallback.onDetailItemClick(item); + } + } + }); + final ImageView disconnect = (ImageView) view.findViewById(android.R.id.icon2); + disconnect.setVisibility(item.canDisconnect ? VISIBLE : GONE); + disconnect.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (mCallback != null) { + mCallback.onDetailItemDisconnect(item); + } + } + }); + return view; + } + }; private class H extends Handler { private static final int SET_ITEMS = 1; diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java index 98a1c23aa645..57a1a4a09a10 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java @@ -37,7 +37,7 @@ public class QSTileView extends QSTileBaseView { private final int mTileSpacingPx; private int mTilePaddingTopPx; - private TextView mLabel; + protected TextView mLabel; private ImageView mPadLock; public QSTileView(Context context, QSIconView icon) { @@ -81,7 +81,7 @@ public class QSTileView extends QSTileBaseView { FontSizeUtils.updateFontSize(mLabel, R.dimen.qs_tile_text_size); } - private void createLabel() { + protected void createLabel() { final Resources res = mContext.getResources(); View view = LayoutInflater.from(mContext).inflate(R.layout.qs_tile_label, null); mLabel = (TextView) view.findViewById(R.id.tile_label); diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java index 55eda9838664..6969e25d0a61 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java +++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java @@ -24,6 +24,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout { private int mCellMargin; protected final ArrayList<TileRecord> mRecords = new ArrayList<>(); + private int mCellMarginTop; public TileLayout(Context context) { this(context, null); @@ -60,9 +61,10 @@ public class TileLayout extends ViewGroup implements QSTileLayout { final int columns = Math.max(1, res.getInteger(R.integer.quick_settings_num_columns)); mCellHeight = mContext.getResources().getDimensionPixelSize(R.dimen.qs_tile_height); mCellMargin = res.getDimensionPixelSize(R.dimen.qs_tile_margin); + mCellMarginTop = res.getDimensionPixelSize(R.dimen.qs_tile_margin_top); if (mColumns != columns) { mColumns = columns; - postInvalidate(); + requestLayout(); return true; } return false; @@ -81,7 +83,8 @@ public class TileLayout extends ViewGroup implements QSTileLayout { record.tileView.measure(exactly(mCellWidth), exactly(mCellHeight)); previousView = record.tileView.updateAccessibilityOrder(previousView); } - setMeasuredDimension(width, (mCellHeight + mCellMargin) * rows); + setMeasuredDimension(width, + (mCellHeight + mCellMargin) * rows + (mCellMarginTop - mCellMargin)); } private static int exactly(int size) { @@ -114,7 +117,7 @@ public class TileLayout extends ViewGroup implements QSTileLayout { } private int getRowTop(int row) { - return row * (mCellHeight + mCellMargin) + mCellMargin; + return row * (mCellHeight + mCellMargin) + mCellMarginTop; } private int getColumnStart(int column) { diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java b/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java new file mode 100644 index 000000000000..e512f93f2ced --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.qs.customize; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.TextView; +import com.android.systemui.R; +import com.android.systemui.qs.QSIconView; +import com.android.systemui.qs.QSTileView; +import libcore.util.Objects; + +public class CustomizeTileView extends QSTileView { + + private TextView mAppLabel; + + public CustomizeTileView(Context context, QSIconView icon) { + super(context, icon); + } + + @Override + protected void createLabel() { + super.createLabel(); + View view = LayoutInflater.from(mContext).inflate(R.layout.qs_tile_label, null); + mAppLabel = (TextView) view.findViewById(R.id.tile_label); + mAppLabel.setAlpha(.6f); + mAppLabel.setSingleLine(true); + addView(view); + } + + public void setShowAppLabel(boolean showAppLabel) { + mAppLabel.setVisibility(showAppLabel ? View.VISIBLE : View.GONE); + mLabel.setSingleLine(showAppLabel); + } + + public void setAppLabel(CharSequence label) { + if (!Objects.equal(label, mAppLabel.getText())) { + mAppLabel.setText(label); + } + } + + public TextView getAppLabel() { + return mAppLabel; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java index 4c134516f844..e8e17b1d15c3 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java @@ -41,7 +41,6 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsProto; import com.android.systemui.R; import com.android.systemui.qs.QSIconView; -import com.android.systemui.qs.QSTileView; import com.android.systemui.qs.customize.TileAdapter.Holder; import com.android.systemui.qs.customize.TileQueryHelper.TileInfo; import com.android.systemui.qs.customize.TileQueryHelper.TileStateListener; @@ -61,6 +60,10 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta private static final int TYPE_TILE = 0; private static final int TYPE_EDIT = 1; private static final int TYPE_ACCESSIBLE_DROP = 2; + private static final int TYPE_DIVIDER = 4; + + private static final long EDIT_ID = 10000; + private static final long DIVIDER_ID = 20000; private final Context mContext; @@ -68,7 +71,8 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta private final List<TileInfo> mTiles = new ArrayList<>(); private final ItemTouchHelper mItemTouchHelper; private final AccessibilityManager mAccessibilityManager; - private int mDividerIndex; + private int mEditIndex; + private int mTileDividerIndex; private boolean mNeedsFocus; private List<String> mCurrentSpecs; private List<TileInfo> mOtherTiles; @@ -87,7 +91,8 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta @Override public long getItemId(int position) { - return mTiles.get(position) != null ? mAllTiles.indexOf(mTiles.get(position)) : -1; + return mTiles.get(position) != null ? mAllTiles.indexOf(mTiles.get(position)) + : position == mEditIndex ? EDIT_ID : DIVIDER_ID; } public ItemTouchHelper getItemTouchHelper() { @@ -100,7 +105,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta public void saveSpecs(QSTileHost host) { List<String> newSpecs = new ArrayList<>(); - for (int i = 0; mTiles.get(i) != null; i++) { + for (int i = 0; i < mTiles.size() && mTiles.get(i) != null; i++) { newSpecs.add(mTiles.get(i).spec); } host.changeTiles(mCurrentSpecs, newSpecs); @@ -131,8 +136,19 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta } } mTiles.add(null); + for (int i = 0; i < mOtherTiles.size(); i++) { + final TileInfo tile = mOtherTiles.get(i); + if (tile.isSystem) { + mOtherTiles.remove(i--); + mTiles.add(tile); + } + } + if (mOtherTiles.size() != 0) { + mTileDividerIndex = mTiles.size(); + mTiles.add(null); + } mTiles.addAll(mOtherTiles); - mDividerIndex = mTiles.indexOf(null); + mEditIndex = mTiles.indexOf(null); notifyDataSetChanged(); } @@ -147,9 +163,12 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta @Override public int getItemViewType(int position) { - if (mAccessibilityMoving && position == mDividerIndex - 1) { + if (mAccessibilityMoving && position == mEditIndex - 1) { return TYPE_ACCESSIBLE_DROP; } + if (position == mTileDividerIndex) { + return TYPE_DIVIDER; + } if (mTiles.get(position) == null) { return TYPE_EDIT; } @@ -160,12 +179,15 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta public Holder onCreateViewHolder(ViewGroup parent, int viewType) { final Context context = parent.getContext(); LayoutInflater inflater = LayoutInflater.from(context); + if (viewType == TYPE_DIVIDER) { + return new Holder(inflater.inflate(R.layout.qs_customize_tile_divider, parent, false)); + } if (viewType == TYPE_EDIT) { return new Holder(inflater.inflate(R.layout.qs_customize_divider, parent, false)); } FrameLayout frame = (FrameLayout) inflater.inflate(R.layout.qs_customize_tile_frame, parent, false); - frame.addView(new QSTileView(context, new QSIconView(context))); + frame.addView(new CustomizeTileView(context, new QSIconView(context))); return new Holder(frame); } @@ -176,6 +198,9 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta @Override public void onBindViewHolder(final Holder holder, final int position) { + if (holder.getItemViewType() == TYPE_DIVIDER) { + return; + } if (holder.getItemViewType() == TYPE_EDIT) { ((TextView) holder.itemView.findViewById(android.R.id.title)).setText( mCurrentDrag != null ? R.string.drag_to_remove_tiles @@ -213,7 +238,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta TileInfo info = mTiles.get(position); - if (position > mDividerIndex) { + if (position > mEditIndex) { info.state.contentDescription = mContext.getString( R.string.accessibility_qs_edit_add_tile_label, info.state.label); } else if (mAccessibilityMoving) { @@ -224,9 +249,11 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta R.string.accessibility_qs_edit_tile_label, position + 1, info.state.label); } holder.mTileView.onStateChanged(info.state); + holder.mTileView.setAppLabel(info.appLabel); + holder.mTileView.setShowAppLabel(position > mTileDividerIndex); if (mAccessibilityManager.isTouchExplorationEnabled()) { - final boolean selectable = !mAccessibilityMoving || position < mDividerIndex; + final boolean selectable = !mAccessibilityMoving || position < mEditIndex; holder.mTileView.setClickable(selectable); holder.mTileView.setFocusable(selectable); holder.mTileView.setImportantForAccessibility(selectable @@ -239,7 +266,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta if (mAccessibilityMoving) { selectPosition(position, v); } else { - if (position < mDividerIndex) { + if (position < mEditIndex) { showAccessibilityDialog(position, v); } else { startAccessibleDrag(position); @@ -253,7 +280,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta private void selectPosition(int position, View v) { // Remove the placeholder. - mTiles.remove(mDividerIndex--); + mTiles.remove(mEditIndex--); mAccessibilityMoving = false; move(mAccessibilityFromIndex, position, v); notifyDataSetChanged(); @@ -272,7 +299,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta if (which == 0) { startAccessibleDrag(position); } else { - move(position, mDividerIndex, v); + move(position, mEditIndex, v); } } }).setNegativeButton(android.R.string.cancel, null) @@ -287,7 +314,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta mNeedsFocus = true; mAccessibilityFromIndex = position; // Add placeholder for last slot. - mTiles.add(mDividerIndex++, null); + mTiles.add(mEditIndex++, null); notifyDataSetChanged(); } @@ -296,25 +323,38 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta } private boolean move(int from, int to, View v) { - if (to > mDividerIndex) { - if (from >= mDividerIndex) { + if (to >= mEditIndex) { + if (from >= mEditIndex) { return false; } + // Sort tiles into system/non-system groups. + TileInfo tile = mTiles.get(from); + if (tile.isSystem) { + if (to > mTileDividerIndex) { + to = mTileDividerIndex; + } + } else { + if (mTileDividerIndex == mTiles.size()) { + mTiles.add(null); + } + if (to <= mTileDividerIndex) { + to = mTileDividerIndex; + } + } } CharSequence fromLabel = mTiles.get(from).state.label; move(from, to, mTiles); - mDividerIndex = mTiles.indexOf(null); - notifyItemChanged(from); - notifyItemMoved(from, to); + notifyDataSetChanged(); + updateDividerLocations(); CharSequence announcement; - if (to >= mDividerIndex) { + if (to >= mEditIndex) { MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_REMOVE_SPEC, strip(mTiles.get(to))); MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_REMOVE, from); announcement = mContext.getString(R.string.accessibility_qs_edit_tile_removed, fromLabel); - } else if (from >= mDividerIndex) { + } else if (from >= mEditIndex) { MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_ADD_SPEC, strip(mTiles.get(to))); MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_QS_EDIT_ADD, @@ -333,6 +373,25 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta return true; } + private void updateDividerLocations() { + // The first null is the edit tiles label, the second null is the tile divider. + // If there is no second null, then there are no non-system tiles. + mEditIndex = -1; + mTileDividerIndex = mTiles.size(); + for (int i = 0; i < mTiles.size(); i++) { + if (mTiles.get(i) == null) { + if (mEditIndex == -1) { + mEditIndex = i; + } else { + mTileDividerIndex = i; + } + } + } + if (mTiles.get(mTiles.size() - 1) == null) { + mTiles.remove(mTiles.size() - 1); + } + } + private String strip(TileInfo tileInfo) { String spec = tileInfo.spec; if (spec.startsWith(CustomTile.PREFIX)) { @@ -348,12 +407,12 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta } public class Holder extends ViewHolder { - private QSTileView mTileView; + private CustomizeTileView mTileView; public Holder(View itemView) { super(itemView); if (itemView instanceof FrameLayout) { - mTileView = (QSTileView) ((FrameLayout) itemView).getChildAt(0); + mTileView = (CustomizeTileView) ((FrameLayout) itemView).getChildAt(0); mTileView.setBackground(null); mTileView.getIcon().disableAnimation(); } @@ -367,6 +426,9 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta mTileView.findViewById(R.id.tile_label).animate() .setDuration(DRAG_LENGTH) .alpha(0); + mTileView.getAppLabel().animate() + .setDuration(DRAG_LENGTH) + .alpha(0); } public void stopDrag() { @@ -377,13 +439,17 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta mTileView.findViewById(R.id.tile_label).animate() .setDuration(DRAG_LENGTH) .alpha(1); + mTileView.getAppLabel().animate() + .setDuration(DRAG_LENGTH) + .alpha(.6f); } } private final SpanSizeLookup mSizeLookup = new SpanSizeLookup() { @Override public int getSpanSize(int position) { - return getItemViewType(position) == TYPE_EDIT ? 3 : 1; + final int type = getItemViewType(position); + return type == TYPE_EDIT || type == TYPE_DIVIDER ? 3 : 1; } }; @@ -401,7 +467,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta for (int i = 0; i < childCount; i++) { final View child = parent.getChildAt(i); final ViewHolder holder = parent.getChildViewHolder(child); - if (holder.getAdapterPosition() < mDividerIndex) { + if (holder.getAdapterPosition() < mEditIndex) { continue; } @@ -443,7 +509,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta mHandler.post(new Runnable() { @Override public void run() { - notifyItemChanged(mDividerIndex); + notifyItemChanged(mEditIndex); } }); } diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java index bbc885691b31..d04a2fc7e148 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java @@ -31,6 +31,7 @@ import android.service.quicksettings.TileService; import com.android.systemui.R; import com.android.systemui.qs.QSTile; import com.android.systemui.qs.QSTile.DrawableIcon; +import com.android.systemui.qs.QSTile.State; import com.android.systemui.qs.external.CustomTile; import com.android.systemui.statusbar.phone.QSTileHost; @@ -79,7 +80,7 @@ public class TileQueryHelper { mainHandler.post(new Runnable() { @Override public void run() { - addTile(spec, state); + addTile(spec, null, state, true); mListener.onTilesChanged(mTiles); } }); @@ -103,28 +104,33 @@ public class TileQueryHelper { mListener = listener; } - private void addTile(String spec, QSTile.State state) { + private void addTile(String spec, CharSequence appLabel, State state, boolean isSystem) { if (mSpecs.contains(spec)) { return; } TileInfo info = new TileInfo(); info.state = state; info.spec = spec; + info.appLabel = appLabel; + info.isSystem = isSystem; mTiles.add(info); mSpecs.add(spec); } - private void addTile(String spec, Drawable drawable, CharSequence label, Context context) { + private void addTile(String spec, Drawable drawable, CharSequence label, CharSequence appLabel, + Context context) { QSTile.State state = new QSTile.State(); state.label = label; state.contentDescription = label; state.icon = new DrawableIcon(drawable); - addTile(spec, state); + addTile(spec, appLabel, state, false); } public static class TileInfo { public String spec; + public CharSequence appLabel; public QSTile.State state; + public boolean isSystem; } private class QueryTilesTask extends AsyncTask<Void, Void, Collection<TileInfo>> { @@ -147,7 +153,8 @@ public class TileQueryHelper { icon.setTint(mContext.getColor(android.R.color.white)); } CharSequence label = info.serviceInfo.loadLabel(pm); - addTile(spec, icon, label != null ? label.toString() : "null", mContext); + final CharSequence appLabel = info.serviceInfo.applicationInfo.loadLabel(pm); + addTile(spec, icon, label != null ? label.toString() : "null", appLabel, mContext); } return tiles; } diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java index 1fef8f18cd39..63c85dbd6c37 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BluetoothTile.java @@ -216,7 +216,6 @@ public class BluetoothTile extends QSTile<QSTile.BooleanState> { mItems.setEmptyState(R.drawable.ic_qs_bluetooth_detail_empty, R.string.quick_settings_bluetooth_detail_empty_text); mItems.setCallback(this); - mItems.setMinHeightInItems(0); updateItems(); setItemsVisible(mState.value); return mItems; diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index 8060e07801bb..b1d955573d19 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -78,6 +78,9 @@ import com.android.systemui.recents.views.RecentsView; import com.android.systemui.recents.views.SystemBarScrimViews; import com.android.systemui.statusbar.BaseStatusBar; +import java.io.FileDescriptor; +import java.io.PrintWriter; + /** * The main Recents activity that is started from AlternateRecentsComponent. */ @@ -733,4 +736,20 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD }); return true; } + + @Override + public void dump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) { + super.dump(prefix, fd, writer, args); + String id = Integer.toHexString(System.identityHashCode(this)); + + writer.print(prefix); writer.print(TAG); + writer.print(" visible="); writer.print(mIsVisible ? "Y" : "N"); + writer.print(" [0x"); writer.print(id); writer.print("]"); + writer.println(); + + if (mRecentsView != null) { + mRecentsView.dump(prefix, writer); + } + EventBus.getDefault().dump(prefix, writer); + } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java index 4dae7460f30a..aba05aa38619 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java @@ -144,7 +144,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener // Task launching Rect mTaskStackBounds = new Rect(); - Rect mLastTaskViewBounds = new Rect(); TaskViewTransform mTmpTransform = new TaskViewTransform(); int mStatusBarHeight; int mNavBarHeight; @@ -169,8 +168,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } }); - protected Bitmap mThumbnailTransitionBitmapCache; - Task mThumbnailTransitionBitmapCacheKey; + protected Bitmap mThumbTransitionBitmapCache; public RecentsImpl(Context context) { mContext = context; @@ -186,7 +184,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener // Initialize the static configuration resources reloadHeaderBarLayout(); - updateHeaderBarLayout(null /* stack */); // When we start, preload the data associated with the previous recent tasks. // We can use a new plan since the caches will be the same. @@ -201,12 +198,11 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } public void onBootCompleted() { - updateHeaderBarLayout(null /* stack */); + // Do nothing } public void onConfigurationChanged() { reloadHeaderBarLayout(); - updateHeaderBarLayout(null /* stack */); } /** @@ -368,9 +364,14 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener loader.preloadTasks(sInstanceLoadPlan, topTask.id, topTaskHome.value); TaskStack stack = sInstanceLoadPlan.getTaskStack(); if (stack.getTaskCount() > 0) { - // We try and draw the thumbnail transition bitmap in parallel before - // toggle/show recents is called - preCacheThumbnailTransitionBitmapAsync(topTask, stack, mDummyStackView); + // Only preload the icon (but not the thumbnail since it may not have been taken for + // the pausing activity) + preloadIcon(topTask); + + // At this point, we don't know anything about the stack state. So only calculate + // the dimensions of the thumbnail that we need for the transition into Recents, but + // do not draw it until we construct the activity options when we start Recents + updateHeaderBarLayout(stack); } } } @@ -601,21 +602,30 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener if (stack != null) { stackLayout.getTaskStackBounds(windowRect, systemInsets.top, systemInsets.right, mTaskStackBounds); + stackLayout.reset(); stackLayout.initialize(windowRect, mTaskStackBounds, TaskStackLayoutAlgorithm.StackState.getStackStateForStack(stack)); mDummyStackView.setTasks(stack, false /* allowNotifyStackChanges */); - } - Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds(); - if (!taskViewBounds.equals(mLastTaskViewBounds)) { - mLastTaskViewBounds.set(taskViewBounds); + Rect taskViewBounds = stackLayout.getUntransformedTaskViewBounds(); int taskViewWidth = taskViewBounds.width(); synchronized (mHeaderBarLock) { - mHeaderBar.measure( - View.MeasureSpec.makeMeasureSpec(taskViewWidth, View.MeasureSpec.EXACTLY), - View.MeasureSpec.makeMeasureSpec(mTaskBarHeight, View.MeasureSpec.EXACTLY)); + if (mHeaderBar.getMeasuredWidth() != taskViewWidth || + mHeaderBar.getMeasuredHeight() != mTaskBarHeight) { + mHeaderBar.measure( + View.MeasureSpec.makeMeasureSpec(taskViewWidth, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(mTaskBarHeight, View.MeasureSpec.EXACTLY)); + } mHeaderBar.layout(0, 0, taskViewWidth, mTaskBarHeight); } + + // Update the transition bitmap to match the new header bar height + if (mThumbTransitionBitmapCache == null || + (mThumbTransitionBitmapCache.getWidth() != taskViewWidth) || + (mThumbTransitionBitmapCache.getHeight() != mTaskBarHeight)) { + mThumbTransitionBitmapCache = Bitmap.createBitmap(taskViewWidth, + mTaskBarHeight, Bitmap.Config.ARGB_8888); + } } } @@ -652,40 +662,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } /** - * Caches the header thumbnail used for a window animation asynchronously into - * {@link #mThumbnailTransitionBitmapCache}. - */ - private void preCacheThumbnailTransitionBitmapAsync(ActivityManager.RunningTaskInfo topTask, - TaskStack stack, TaskStackView stackView) { - preloadIcon(topTask); - - // Update the header bar if necessary - updateHeaderBarLayout(stack); - - // Update the destination rect - final Task toTask = new Task(); - final TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask); - ForegroundThread.getHandler().postAtFrontOfQueue(new Runnable() { - @Override - public void run() { - final Bitmap transitionBitmap = drawThumbnailTransitionBitmap(toTask, toTransform); - if (transitionBitmap != null) { - mHandler.post(new Runnable() { - @Override - public void run() { - mThumbnailTransitionBitmapCache = transitionBitmap; - mThumbnailTransitionBitmapCacheKey = toTask; - } - }); - } else { - Log.e(TAG, "Could not load thumbnail for task: " + toTask + " at transform: " + - toTransform); - } - } - }); - } - - /** * Creates the activity options for a unknown state->recents transition. */ protected ActivityOptions getUnknownTransitionActivityOptions() { @@ -724,9 +700,10 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener if (task.isFreeformTask()) { mTmpTransform = stackLayout.getStackTransformScreenCoordinates(task, stackScroller.getStackScroll(), mTmpTransform, null); + Bitmap thumbnail = drawThumbnailTransitionBitmap(task, mTmpTransform, + mThumbTransitionBitmapCache); Rect toTaskRect = new Rect(); mTmpTransform.rect.round(toTaskRect); - Bitmap thumbnail = getThumbnailBitmap(topTask, task, mTmpTransform); specs.add(new AppTransitionAnimationSpec(task.key.id, thumbnail, toTaskRect)); } } @@ -738,9 +715,10 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener // Update the destination rect Task toTask = new Task(); TaskViewTransform toTransform = getThumbnailTransitionTransform(stackView, toTask); - RectF toTaskRect = toTransform.rect; - Bitmap thumbnail = getThumbnailBitmap(topTask, toTask, toTransform); + Bitmap thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform, + mThumbTransitionBitmapCache); if (thumbnail != null) { + RectF toTaskRect = toTransform.rect; return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView, thumbnail, (int) toTaskRect.left, (int) toTaskRect.top, (int) toTaskRect.width(), (int) toTaskRect.height(), mHandler, null); @@ -750,22 +728,6 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } } - private Bitmap getThumbnailBitmap(ActivityManager.RunningTaskInfo topTask, Task toTask, - TaskViewTransform toTransform) { - Bitmap thumbnail; - if (mThumbnailTransitionBitmapCacheKey != null - && mThumbnailTransitionBitmapCacheKey.key != null - && mThumbnailTransitionBitmapCacheKey.key.equals(toTask.key)) { - thumbnail = mThumbnailTransitionBitmapCache; - mThumbnailTransitionBitmapCacheKey = null; - mThumbnailTransitionBitmapCache = null; - } else { - preloadIcon(topTask); - thumbnail = drawThumbnailTransitionBitmap(toTask, toTransform); - } - return thumbnail; - } - /** * Returns the transition rect for the given task id. */ @@ -793,26 +755,19 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener /** * Draws the header of a task used for the window animation into a bitmap. */ - private Bitmap drawThumbnailTransitionBitmap(Task toTask, TaskViewTransform toTransform) { + private Bitmap drawThumbnailTransitionBitmap(Task toTask, TaskViewTransform toTransform, + Bitmap thumbnail) { SystemServicesProxy ssp = Recents.getSystemServices(); if (toTransform != null && toTask.key != null) { - Bitmap thumbnail; synchronized (mHeaderBarLock) { - int toHeaderWidth = (int) toTransform.rect.width(); - int toHeaderHeight = (int) (mHeaderBar.getMeasuredHeight() * toTransform.scale); - if (toHeaderWidth <= 0 || toHeaderHeight <= 0) { - return null; - } boolean disabledInSafeMode = !toTask.isSystemApp && ssp.isInSafeMode(); mHeaderBar.onTaskViewSizeChanged((int) toTransform.rect.width(), (int) toTransform.rect.height()); - thumbnail = Bitmap.createBitmap(toHeaderWidth, toHeaderHeight, - Bitmap.Config.ARGB_8888); if (RecentsDebugFlags.Static.EnableTransitionThumbnailDebugMode) { thumbnail.eraseColor(0xFFff0000); } else { + thumbnail.eraseColor(0); Canvas c = new Canvas(thumbnail); - c.scale(toTransform.scale, toTransform.scale); // Workaround for b/27815919, reset the callback so that we do not trigger an // invalidate on the header bar as a result of updating the icon Drawable icon = mHeaderBar.getIconView().getDrawable(); @@ -854,6 +809,18 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener boolean hasRecentTasks = stack.getTaskCount() > 0; boolean useThumbnailTransition = (topTask != null) && !isTopTaskHome && hasRecentTasks; + // Update the launch state that we need in updateHeaderBarLayout() + launchState.launchedFromHome = !useThumbnailTransition; + launchState.launchedFromApp = useThumbnailTransition || mLaunchedWhileDocking; + launchState.launchedViaDockGesture = mLaunchedWhileDocking; + launchState.launchedViaDragGesture = mDraggingInRecents; + launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1; + launchState.launchedWithAltTab = mTriggeredFromAltTab; + + // Preload the icon (this will be a null-op if we have preloaded the icon already in + // preloadRecents()) + preloadIcon(topTask); + // Update the header bar if necessary updateHeaderBarLayout(stack); @@ -861,44 +828,27 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener TaskStackLayoutAlgorithm.VisibilityReport stackVr = mDummyStackView.computeStackVisibilityReport(); - // Update the launch state - launchState.launchedFromHome = false; - launchState.launchedFromApp = mLaunchedWhileDocking; - launchState.launchedViaDockGesture = mLaunchedWhileDocking; - launchState.launchedToTaskId = (topTask != null) ? topTask.id : -1; - launchState.launchedWithAltTab = mTriggeredFromAltTab; + // Update the remaining launch state launchState.launchedNumVisibleTasks = stackVr.numVisibleTasks; launchState.launchedNumVisibleThumbnails = stackVr.numVisibleThumbnails; - launchState.launchedViaDragGesture = mDraggingInRecents; if (!animate) { startRecentsActivity(ActivityOptions.makeCustomAnimation(mContext, -1, -1)); return; } + ActivityOptions opts; if (useThumbnailTransition) { - launchState.launchedFromApp = true; - // Try starting with a thumbnail transition - ActivityOptions opts = getThumbnailTransitionActivityOptions(topTask, mDummyStackView); - if (opts != null) { - startRecentsActivity(opts); - } else { - // Fall through below to the non-thumbnail transition - useThumbnailTransition = false; - } - } - - if (!useThumbnailTransition) { - launchState.launchedFromHome = true; - + opts = getThumbnailTransitionActivityOptions(topTask, mDummyStackView); + } else { // If there is no thumbnail transition, but is launching from home into recents, then // use a quick home transition - ActivityOptions opts = hasRecentTasks - ? getHomeTransitionActivityOptions() - : getUnknownTransitionActivityOptions(); - startRecentsActivity(opts); + opts = hasRecentTasks + ? getHomeTransitionActivityOptions() + : getUnknownTransitionActivityOptions(); } + startRecentsActivity(opts); mLastToggleTime = SystemClock.elapsedRealtime(); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java b/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java index 0d56ae98a165..38ad1c710716 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java +++ b/packages/SystemUI/src/com/android/systemui/recents/events/EventBus.java @@ -30,6 +30,7 @@ import android.util.MutableBoolean; import com.android.systemui.recents.misc.ReferenceCountedTrigger; +import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; @@ -652,19 +653,43 @@ public class EventBus extends BroadcastReceiver { /** * @return a dump of the current state of the EventBus */ - public String dump() { + public void dump(String prefix, PrintWriter writer) { + writer.println(dumpInternal(prefix)); + } + + public String dumpInternal(String prefix) { + String innerPrefix = prefix + " "; + String innerInnerPrefix = innerPrefix + " "; StringBuilder output = new StringBuilder(); + output.append(prefix); output.append("Registered class types:"); output.append("\n"); - for (Class<?> clz : mSubscriberTypeMap.keySet()) { - output.append("\t"); + ArrayList<Class<?>> subsciberTypes = new ArrayList<>(mSubscriberTypeMap.keySet()); + Collections.sort(subsciberTypes, new Comparator<Class<?>>() { + @Override + public int compare(Class<?> o1, Class<?> o2) { + return o1.getSimpleName().compareTo(o2.getSimpleName()); + } + }); + for (int i = 0; i < subsciberTypes.size(); i++) { + Class<?> clz = subsciberTypes.get(i); + output.append(innerPrefix); output.append(clz.getSimpleName()); output.append("\n"); } + output.append(prefix); output.append("Event map:"); output.append("\n"); - for (Class<?> clz : mEventTypeMap.keySet()) { - output.append("\t"); + ArrayList<Class<?>> classes = new ArrayList<>(mEventTypeMap.keySet()); + Collections.sort(classes, new Comparator<Class<?>>() { + @Override + public int compare(Class<?> o1, Class<?> o2) { + return o1.getSimpleName().compareTo(o2.getSimpleName()); + } + }); + for (int i = 0; i < classes.size(); i++) { + Class<?> clz = classes.get(i); + output.append(innerPrefix); output.append(clz.getSimpleName()); output.append(" -> "); output.append("\n"); @@ -673,7 +698,7 @@ public class EventBus extends BroadcastReceiver { Object subscriber = handler.subscriber.getReference(); if (subscriber != null) { String id = Integer.toHexString(System.identityHashCode(subscriber)); - output.append("\t\t"); + output.append(innerInnerPrefix); output.append(subscriber.getClass().getSimpleName()); output.append(" [0x" + id + ", #" + handler.priority + "]"); output.append("\n"); diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java index e28612a3cff6..69d98af5a2b2 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java @@ -243,4 +243,14 @@ public class Utilities { public static float dpToPx(Resources res, float dp) { return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, res.getDisplayMetrics()); } + + /** + * Returns a lightweight dump of a rect. + */ + public static String dumpRect(Rect r) { + if (r == null) { + return "N:0,0-0,0"; + } + return r.left + "," + r.top + "-" + r.right + "," + r.bottom; + } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java index 76ca6ca3bba9..7aeff1feca71 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java @@ -132,6 +132,8 @@ public class RecentsTaskLoadPlan { SparseIntArray affiliatedTaskCounts = new SparseIntArray(); String dismissDescFormat = mContext.getString( R.string.accessibility_recents_item_will_be_dismissed); + String appInfoDescFormat = mContext.getString( + R.string.accessibility_recents_item_open_app_info); long lastStackActiveTime = Prefs.getLong(mContext, Prefs.Key.OVERVIEW_LAST_STACK_TASK_ACTIVE_TIME, 0); if (RecentsDebugFlags.Static.EnableMockTasks) { @@ -188,8 +190,9 @@ public class RecentsTaskLoadPlan { // Load the title, icon, and color ActivityInfo info = loader.getAndUpdateActivityInfo(taskKey); String title = loader.getAndUpdateActivityTitle(taskKey, t.taskDescription); - String contentDescription = loader.getAndUpdateContentDescription(taskKey, res); - String dismissDescription = String.format(dismissDescFormat, contentDescription); + String titleDescription = loader.getAndUpdateContentDescription(taskKey, res); + String dismissDescription = String.format(dismissDescFormat, titleDescription); + String appInfoDescription = String.format(appInfoDescFormat, titleDescription); Drawable icon = isStackTask ? loader.getAndUpdateActivityIcon(taskKey, t.taskDescription, res, false) : null; @@ -201,9 +204,9 @@ public class RecentsTaskLoadPlan { // Add the task to the stack Task task = new Task(taskKey, t.affiliatedTaskId, t.affiliatedTaskColor, icon, - thumbnail, title, contentDescription, dismissDescription, activityColor, - backgroundColor, isLaunchTarget, isStackTask, isSystemApp, t.isDockable, - t.bounds, t.taskDescription); + thumbnail, title, titleDescription, dismissDescription, appInfoDescription, + activityColor, backgroundColor, isLaunchTarget, isStackTask, isSystemApp, + t.isDockable, t.bounds, t.taskDescription); allTasks.add(task); affiliatedTaskCounts.put(taskKey.id, affiliatedTaskCounts.get(taskKey.id, 0) + 1); diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java index d5d5aa0dc97f..24eeaf27f032 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java @@ -29,6 +29,7 @@ import com.android.systemui.recents.Recents; import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.misc.Utilities; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.Objects; @@ -37,6 +38,9 @@ import java.util.Objects; * A task represents the top most task in the system's task stack. */ public class Task { + + public static final String TAG = "Task"; + /* Task callbacks */ public interface TaskCallbacks { /* Notifies when a task has been bound */ @@ -100,7 +104,8 @@ public class Task { @Override public String toString() { - return "t" + id + ", s" + stackId + ", u" + userId; + return "id=" + id + " stackId=" + stackId + " user=" + userId + " lastActiveTime=" + + lastActiveTime; } private void updateHashCode() { @@ -134,10 +139,12 @@ public class Task { @ViewDebug.ExportedProperty(category="recents") public String title; @ViewDebug.ExportedProperty(category="recents") - public String contentDescription; + public String titleDescription; @ViewDebug.ExportedProperty(category="recents") public String dismissDescription; @ViewDebug.ExportedProperty(category="recents") + public String appInfoDescription; + @ViewDebug.ExportedProperty(category="recents") public int colorPrimary; @ViewDebug.ExportedProperty(category="recents") public int colorBackground; @@ -174,8 +181,8 @@ public class Task { } public Task(TaskKey key, int affiliationTaskId, int affiliationColor, Drawable icon, - Bitmap thumbnail, String title, String contentDescription, - String dismissDescription, int colorPrimary, int colorBackground, + Bitmap thumbnail, String title, String titleDescription, String dismissDescription, + String appInfoDescription, int colorPrimary, int colorBackground, boolean isLaunchTarget, boolean isStackTask, boolean isSystemApp, boolean isDockable, Rect bounds, ActivityManager.TaskDescription taskDescription) { boolean isInAffiliationGroup = (affiliationTaskId != key.id); @@ -186,8 +193,9 @@ public class Task { this.icon = icon; this.thumbnail = thumbnail; this.title = title; - this.contentDescription = contentDescription; + this.titleDescription = titleDescription; this.dismissDescription = dismissDescription; + this.appInfoDescription = appInfoDescription; this.colorPrimary = hasAffiliationGroupColor ? affiliationColor : colorPrimary; this.colorBackground = colorBackground; this.useLightOnPrimaryColor = Utilities.computeContrastBetweenColors(this.colorPrimary, @@ -211,8 +219,9 @@ public class Task { this.icon = o.icon; this.thumbnail = o.thumbnail; this.title = o.title; - this.contentDescription = o.contentDescription; + this.titleDescription = o.titleDescription; this.dismissDescription = o.dismissDescription; + this.appInfoDescription = o.appInfoDescription; this.colorPrimary = o.colorPrimary; this.colorBackground = o.colorBackground; this.useLightOnPrimaryColor = o.useLightOnPrimaryColor; @@ -302,4 +311,13 @@ public class Task { public String toString() { return "[" + key.toString() + "] " + title; } + + public void dump(String prefix, PrintWriter writer) { + writer.print(prefix); writer.print(key); + if (affiliationTaskId != key.id) { + writer.print(" "); writer.print("affTaskId=" + affiliationTaskId); + } + writer.print(" "); writer.print(title); + writer.println(); + } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java index df3f56c7c3ac..fbb59870b237 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java @@ -55,6 +55,7 @@ import com.android.systemui.recents.views.AnimationProps; import com.android.systemui.recents.views.DropTarget; import com.android.systemui.recents.views.TaskStackLayoutAlgorithm; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -208,6 +209,8 @@ class FilteredTaskList { */ public class TaskStack { + private static final String TAG = "TaskStack"; + /** Task stack callbacks */ public interface TaskStackCallbacks { /** @@ -725,7 +728,9 @@ public class TaskStack { /** Finds the task with the specified task id. */ public Task findTaskWithId(int taskId) { ArrayList<Task> tasks = computeAllTasksList(); - for (Task task : tasks) { + int taskCount = tasks.size(); + for (int i = 0; i < taskCount; i++) { + Task task = tasks.get(i); if (task.key.id == taskId) { return task; } @@ -880,7 +885,10 @@ public class TaskStack { ArraySet<ComponentName> existingComponents = new ArraySet<>(); ArraySet<ComponentName> removedComponents = new ArraySet<>(); ArrayList<Task.TaskKey> taskKeys = getTaskKeys(); - for (Task.TaskKey t : taskKeys) { + int taskKeyCount = taskKeys.size(); + for (int i = 0; i < taskKeyCount; i++) { + Task.TaskKey t = taskKeys.get(i); + // Skip if this doesn't apply to the current user if (t.userId != userId) continue; @@ -903,8 +911,10 @@ public class TaskStack { @Override public String toString() { String str = "Stack Tasks (" + mStackTaskList.size() + "):\n"; - for (Task t : mStackTaskList.getTasks()) { - str += " " + t.toString() + "\n"; + ArrayList<Task> tasks = mStackTaskList.getTasks(); + int taskCount = tasks.size(); + for (int i = 0; i < taskCount; i++) { + str += " " + tasks.get(i).toString() + "\n"; } return str; } @@ -921,4 +931,17 @@ public class TaskStack { } return map; } + + public void dump(String prefix, PrintWriter writer) { + String innerPrefix = prefix + " "; + + writer.print(prefix); writer.print(TAG); + writer.print(" numStackTasks="); writer.print(mStackTaskList.size()); + writer.println(); + ArrayList<Task> tasks = mStackTaskList.getTasks(); + int taskCount = tasks.size(); + for (int i = 0; i < taskCount; i++) { + tasks.get(i).dump(innerPrefix, writer); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java index 483f9e523c55..f9f851a76c2a 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvActivity.java @@ -53,7 +53,6 @@ import com.android.systemui.recents.model.RecentsTaskLoadPlan; import com.android.systemui.recents.model.RecentsTaskLoader; import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.TaskStack; -import com.android.systemui.recents.tv.animations.FocusAnimationHolder; import com.android.systemui.recents.tv.views.RecentsTvView; import com.android.systemui.recents.tv.views.TaskStackHorizontalViewAdapter; import com.android.systemui.statusbar.BaseStatusBar; @@ -79,7 +78,6 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener { private boolean mIgnoreAltTabRelease; private RecentsTvView mRecentsView; - private FocusAnimationHolder mRecentsFocusAnimationHolder; private View mPipView; private TaskStackHorizontalViewAdapter mTaskStackViewAdapter; private FinishRecentsRunnable mFinishLaunchHomeRunnable; @@ -133,13 +131,7 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener { new View.OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { - if (hasFocus) { - mRecentsFocusAnimationHolder.startFocusLoseAnimation(); - mPipRecentsOverlayManager.requestFocus( - mTaskStackViewAdapter.getItemCount() > 0); - } else { - mRecentsFocusAnimationHolder.startFocusGainAnimation(); - } + handlePipViewFocusChange(hasFocus); } }; @@ -288,11 +280,10 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener { mRecentsView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION); - mRecentsFocusAnimationHolder = new FocusAnimationHolder(mRecentsView); mPipView = findViewById(R.id.pip); // Place mPipView at the PIP bounds for fine tuned focus handling. - Rect pipBounds = mPipManager.getPipBounds(); + Rect pipBounds = mPipManager.getRecentsFocusedPipBounds(); LayoutParams lp = (LayoutParams) mPipView.getLayoutParams(); lp.width = pipBounds.width(); lp.height = pipBounds.height(); @@ -513,11 +504,30 @@ public class RecentsTvActivity extends Activity implements OnPreDrawListener { if (mPipManager.isPipShown()) { mPipView.setVisibility(View.VISIBLE); mPipView.setOnFocusChangeListener(mPipViewFocusChangeListener); - mPipView.requestFocus(); + if (mPipView.hasFocus()) { + // This can happen only if the activity is resumed. Ask for reset. + handlePipViewFocusChange(true); + } else { + mPipView.requestFocus(); + } } else { mPipView.setVisibility(View.GONE); mPipRecentsOverlayManager.removePipRecentsOverlayView(); - mRecentsFocusAnimationHolder.reset(); + } + } + + /** + * Handles the PIP view's focus change. + * This starts the relevant recents row animation + * and give focus to the recents overlay if needed. + */ + private void handlePipViewFocusChange(boolean hasFocus) { + mRecentsView.startRecentsRowFocusAnimation(!hasFocus); + if (hasFocus) { + // When PIP view has focus, recents overlay view will takes the focus + // as if it's the part of the Recents UI. + mPipRecentsOverlayManager.requestFocus( + mTaskStackViewAdapter.getItemCount() > 0); } } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java index c1b47dcbb4e0..fb62affd6cee 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/RecentsTvImpl.java @@ -124,7 +124,7 @@ public class RecentsTvImpl extends RecentsImpl{ */ private ActivityOptions getThumbnailTransitionActivityOptionsForTV( ActivityManager.RunningTaskInfo topTask) { - Bitmap thumbnail = mThumbnailTransitionBitmapCache; + Bitmap thumbnail = mThumbTransitionBitmapCache; Rect rect = TaskCardView.getStartingCardThumbnailRect(mContext); if (thumbnail != null) { return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mDummyStackView, diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/FocusAnimationHolder.java b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/FocusAnimationHolder.java deleted file mode 100644 index 864540c616e9..000000000000 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/FocusAnimationHolder.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.android.systemui.recents.tv.animations; - -import android.content.res.Resources; -import android.view.View; - -import com.android.systemui.Interpolators; -import com.android.systemui.R; -import com.android.systemui.recents.tv.views.TaskCardView; - -/** - * Collections of Recents row's animation depending on the PIP's focus. - */ -public class FocusAnimationHolder { - private final float DIM_ALPHA = 0.5f; - - private View mRecentsRowView; - private int mCardYDelta; - private long mDuration; - - public FocusAnimationHolder(View recentsRowView) { - mRecentsRowView = recentsRowView; - - Resources res = recentsRowView.getResources(); - mCardYDelta = res.getDimensionPixelOffset(R.dimen.recents_tv_dismiss_shift_down); - mDuration = res.getInteger(R.integer.recents_tv_pip_focus_anim_duration); - } - - public void startFocusGainAnimation() { - mRecentsRowView.animate() - .setDuration(mDuration) - .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) - .alpha(1f) - .translationY(0); - } - - public void startFocusLoseAnimation() { - mRecentsRowView.animate() - .setDuration(mDuration) - .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) - .alpha(DIM_ALPHA) - .translationY(mCardYDelta); - } - - public void reset() { - mRecentsRowView.setTransitionAlpha(1f); - mRecentsRowView.setTranslationY(0); - } -} diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/animations/RecentsRowFocusAnimationHolder.java b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/RecentsRowFocusAnimationHolder.java new file mode 100644 index 000000000000..28abc344f7d1 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/animations/RecentsRowFocusAnimationHolder.java @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.systemui.recents.tv.animations; + +import android.animation.Animator; +import android.animation.AnimatorSet; +import android.animation.ObjectAnimator; +import android.content.res.Resources; +import android.view.View; + +import com.android.systemui.Interpolators; +import com.android.systemui.R; +import com.android.systemui.recents.tv.views.TaskCardView; + +/** + * Recents row's focus animation with PIP controls. + */ +public class RecentsRowFocusAnimationHolder { + private static final float DIM_ALPHA = 0.5f; + + private View mView; + private View mTitleView; + + private AnimatorSet mFocusGainAnimatorSet; + private AnimatorSet mFocusLoseAnimatorSet; + + public RecentsRowFocusAnimationHolder(View view, View titleView) { + mView = view; + mTitleView = titleView; + + Resources res = view.getResources(); + int duration = res.getInteger(R.integer.recents_tv_pip_focus_anim_duration); + + mFocusGainAnimatorSet = new AnimatorSet(); + mFocusGainAnimatorSet.playTogether( + ObjectAnimator.ofFloat(mView, "alpha", 1f), + ObjectAnimator.ofFloat(mTitleView, "alpha", 1f)); + mFocusGainAnimatorSet.setDuration(duration); + mFocusGainAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); + + mFocusLoseAnimatorSet = new AnimatorSet(); + mFocusLoseAnimatorSet.playTogether( + ObjectAnimator.ofFloat(mView, "alpha", DIM_ALPHA), + ObjectAnimator.ofFloat(mTitleView, "alpha", 0f)); + mFocusLoseAnimatorSet.setDuration(duration); + mFocusLoseAnimatorSet.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); + } + + /** + * Returns the Recents row's focus change animation. + */ + public Animator getFocusChangeAnimator(boolean hasFocus) { + return hasFocus ? mFocusGainAnimatorSet : mFocusLoseAnimatorSet; + } + + /** + * Resets the views to the initial state immediately. + */ + public void reset() { + mView.setAlpha(1f); + mTitleView.setAlpha(1f); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java index d966614efb1b..9da8eed3996b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/RecentsTvView.java @@ -37,6 +37,7 @@ import com.android.systemui.recents.events.component.RecentsVisibilityChangedEve import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.TaskStack; +import com.android.systemui.recents.tv.animations.RecentsRowFocusAnimationHolder; import java.util.ArrayList; import java.util.List; @@ -52,6 +53,7 @@ public class RecentsTvView extends FrameLayout { private TaskStack mStack; private TaskStackHorizontalGridView mTaskStackHorizontalView; private View mEmptyView; + private RecentsRowFocusAnimationHolder mEmptyViewFocusAnimationHolder; private boolean mAwaitingFirstLayout = true; private Rect mSystemInsets = new Rect(); private RecentsTvTransitionHelper mTransitionHelper; @@ -77,6 +79,8 @@ public class RecentsTvView extends FrameLayout { LayoutInflater inflater = LayoutInflater.from(context); mEmptyView = inflater.inflate(R.layout.recents_empty, this, false); addView(mEmptyView); + mEmptyViewFocusAnimationHolder = new RecentsRowFocusAnimationHolder(mEmptyView, null); + mHandler = new Handler(); mTransitionHelper = new RecentsTvTransitionHelper(mContext, mHandler); } @@ -94,7 +98,6 @@ public class RecentsTvView extends FrameLayout { mTaskStackHorizontalView.setStack(stack); } - if (stack.getStackTaskCount() > 0) { hideEmptyView(); } else { @@ -134,33 +137,40 @@ public class RecentsTvView extends FrameLayout { public boolean launchTask(Task task, Rect taskBounds, int destinationStack) { if (mTaskStackHorizontalView != null) { // Iterate the stack views and try and find the given task. - List<TaskCardView> taskViews = mTaskStackHorizontalView.getTaskViews(); - int taskViewCount = taskViews.size(); - for (int j = 0; j < taskViewCount; j++) { - TaskCardView tv = taskViews.get(j); - if (tv.getTask() == task) { - SystemServicesProxy ssp = Recents.getSystemServices(); - ssp.startActivityFromRecents(getContext(), task.key, task.title, null); - return true; - } + if (mTaskStackHorizontalView.getChildViewForTask(task) != null) { + SystemServicesProxy ssp = Recents.getSystemServices(); + ssp.startActivityFromRecents(getContext(), task.key, task.title, null); + return true; } } return false; } /** + * Starts the focus change animation. + */ + public void startRecentsRowFocusAnimation(boolean hasFocus) { + if (mEmptyView.getVisibility() == View.VISIBLE) { + mEmptyViewFocusAnimationHolder.getFocusChangeAnimator(hasFocus).start(); + } else { + mTaskStackHorizontalView.startRecentsRowFocusAnimation(hasFocus); + } + } + + /** * Hides the task stack and shows the empty view. */ public void showEmptyView() { mEmptyView.setVisibility(View.VISIBLE); - mEmptyView.bringToFront(); + mTaskStackHorizontalView.setVisibility(View.GONE); } /** * Shows the task stack and hides the empty view. */ public void hideEmptyView() { - mEmptyView.setVisibility(View.INVISIBLE); + mEmptyView.setVisibility(View.GONE); + mTaskStackHorizontalView.setVisibility(View.VISIBLE); } /** diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java index 3343aec8891b..d60574891899 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskCardView.java @@ -24,6 +24,7 @@ import android.util.AttributeSet; import android.util.TypedValue; import android.view.Display; import android.view.KeyEvent; +import android.view.View; import android.view.WindowManager; import android.widget.ImageView; import android.widget.LinearLayout; @@ -31,6 +32,7 @@ import android.widget.TextView; import com.android.systemui.R; import com.android.systemui.recents.tv.animations.DismissAnimationsHolder; +import com.android.systemui.recents.tv.animations.RecentsRowFocusAnimationHolder; import com.android.systemui.recents.tv.animations.ViewFocusAnimator; import com.android.systemui.recents.model.Task; @@ -44,6 +46,7 @@ public class TaskCardView extends LinearLayout { private ViewFocusAnimator mViewFocusAnimator; private DismissAnimationsHolder mDismissAnimationsHolder; + private RecentsRowFocusAnimationHolder mRecentsRowFocusAnimationHolder; public TaskCardView(Context context) { this(context, null); @@ -65,6 +68,8 @@ public class TaskCardView extends LinearLayout { mTitleTextView = (TextView) findViewById(R.id.card_title_text); mBadgeView = (ImageView) findViewById(R.id.card_extra_badge); mDismissAnimationsHolder = new DismissAnimationsHolder(this); + View title = findViewById(R.id.card_info_field); + mRecentsRowFocusAnimationHolder = new RecentsRowFocusAnimationHolder(this, title); } public void init(Task task) { @@ -193,6 +198,10 @@ public class TaskCardView extends LinearLayout { mDismissAnimationsHolder.startDismissAnimation(listener); } + public RecentsRowFocusAnimationHolder getRecentsRowFocusAnimationHolder() { + return mRecentsRowFocusAnimationHolder; + } + @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java index 5eb9fda98d93..603721a56eca 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/tv/views/TaskStackHorizontalGridView.java @@ -15,7 +15,11 @@ */ package com.android.systemui.recents.tv.views; +import android.animation.Animator; +import android.animation.AnimatorSet; import android.content.Context; +import android.os.Handler; +import android.os.Message; import android.support.v17.leanback.widget.HorizontalGridView; import android.util.AttributeSet; import android.view.View; @@ -36,10 +40,19 @@ import java.util.List; * Horizontal Grid View Implementation to show the Task Stack for TV. */ public class TaskStackHorizontalGridView extends HorizontalGridView implements TaskStackCallbacks { - + private static final int ANIMATION_DELAY_MS = 50; + private static final int MSG_START_RECENT_ROW_FOCUS_ANIMATION = 100; + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + if (msg.what == MSG_START_RECENT_ROW_FOCUS_ANIMATION) { + startRecentsRowFocusAnimation(msg.arg1 == 1); + } + } + }; private TaskStack mStack; - private ArrayList<TaskCardView> mTaskViews = new ArrayList<>(); private Task mFocusedTask; + private AnimatorSet mRecentsRowFocusAnimation; public TaskStackHorizontalGridView(Context context) { this(context, null); @@ -62,10 +75,18 @@ public class TaskStackHorizontalGridView extends HorizontalGridView implements T super.onDetachedFromWindow(); EventBus.getDefault().unregister(this); } + /** * Resets this view for reuse. */ public void reset() { + for (int i = 0; i < getChildCount(); i++) { + ((TaskCardView) getChildAt(i)).getRecentsRowFocusAnimationHolder().reset(); + } + if (mRecentsRowFocusAnimation != null && mRecentsRowFocusAnimation.isStarted()) { + mRecentsRowFocusAnimation.cancel(); + } + mHandler.removeCallbacksAndMessages(null); requestLayout(); } @@ -119,10 +140,8 @@ public class TaskStackHorizontalGridView extends HorizontalGridView implements T * @return Child view for given task */ public TaskCardView getChildViewForTask(Task task) { - List<TaskCardView> taskViews = getTaskViews(); - int taskViewCount = taskViews.size(); - for (int i = 0; i < taskViewCount; i++) { - TaskCardView tv = taskViews.get(i); + for (int i = 0; i < getChildCount(); i++) { + TaskCardView tv = (TaskCardView) getChildAt(i); if (tv.getTask() == task) { return tv; } @@ -130,12 +149,36 @@ public class TaskStackHorizontalGridView extends HorizontalGridView implements T return null; } - public List<TaskCardView> getTaskViews() { - return mTaskViews; + /** + * Starts the focus change animation. + */ + public void startRecentsRowFocusAnimation(final boolean hasFocus) { + if (getChildCount() == 0) { + // Animation request may happen before view is attached. + // Post again with small dealy so animation can be run again later. + if (getAdapter().getItemCount() > 0) { + mHandler.sendMessageDelayed(mHandler.obtainMessage( + MSG_START_RECENT_ROW_FOCUS_ANIMATION, hasFocus ? 1 : 0), + ANIMATION_DELAY_MS); + } + return; + } + if (mRecentsRowFocusAnimation != null && mRecentsRowFocusAnimation.isStarted()) { + mRecentsRowFocusAnimation.cancel(); + } + Animator animator = ((TaskCardView) getChildAt(0)).getRecentsRowFocusAnimationHolder() + .getFocusChangeAnimator(hasFocus); + mRecentsRowFocusAnimation = new AnimatorSet(); + AnimatorSet.Builder builder = mRecentsRowFocusAnimation.play(animator); + for (int i = 1; i < getChildCount(); i++) { + builder.with(((TaskCardView) getChildAt(i)).getRecentsRowFocusAnimationHolder() + .getFocusChangeAnimator(hasFocus)); + } + mRecentsRowFocusAnimation.start(); } @Override - public void onStackTaskAdded(TaskStack stack, Task newTask){ + public void onStackTaskAdded(TaskStack stack, Task newTask) { getAdapter().notifyItemInserted(stack.getStackTasks().indexOf(newTask)); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java index e0d048660b96..21a43d5c3e52 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -74,6 +74,8 @@ import com.android.systemui.recents.views.RecentsTransitionHelper.AnimationSpecC import com.android.systemui.stackdivider.WindowManagerProxy; import com.android.systemui.statusbar.FlingAnimationUtils; +import java.io.FileDescriptor; +import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; @@ -83,6 +85,8 @@ import java.util.List; */ public class RecentsView extends FrameLayout { + private static final String TAG = "RecentsView"; + private static final int DOCK_AREA_OVERLAY_TRANSITION_DURATION = 135; private static final int DEFAULT_UPDATE_SCRIM_DURATION = 200; private static final float DEFAULT_SCRIM_ALPHA = 0.33f; @@ -367,8 +371,10 @@ public class RecentsView extends FrameLayout { int topBottomInsets = mSystemInsets.top + mSystemInsets.bottom; int childWidth = mEmptyView.getMeasuredWidth(); int childHeight = mEmptyView.getMeasuredHeight(); - int childLeft = left + Math.max(0, (right - left - leftRightInsets - childWidth)) / 2; - int childTop = top + Math.max(0, (bottom - top - topBottomInsets - childHeight)) / 2; + int childLeft = left + mSystemInsets.left + + Math.max(0, (right - left - leftRightInsets - childWidth)) / 2; + int childTop = top + mSystemInsets.top + + Math.max(0, (bottom - top - topBottomInsets - childHeight)) / 2; mEmptyView.layout(childLeft, childTop, childLeft + childWidth, childTop + childHeight); } @@ -756,4 +762,22 @@ public class RecentsView extends FrameLayout { top + mStackActionButton.getMeasuredHeight()); return actionButtonRect; } + + public void dump(String prefix, PrintWriter writer) { + String innerPrefix = prefix + " "; + String id = Integer.toHexString(System.identityHashCode(this)); + + writer.print(prefix); writer.print(TAG); + writer.print(" awaitingFirstLayout="); writer.print(mAwaitingFirstLayout ? "Y" : "N"); + writer.print(" insets="); writer.print(Utilities.dumpRect(mSystemInsets)); + writer.print(" [0x"); writer.print(id); writer.print("]"); + writer.println(); + + if (mStack != null) { + mStack.dump(innerPrefix, writer); + } + if (mTaskStackView != null) { + mTaskStackView.dump(innerPrefix, writer); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java index 1c433d8eb31c..fe91f421c202 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java @@ -456,7 +456,8 @@ public class TaskStackAnimationHelper { TaskStack stack = mStackView.getStack(); final float curScroll = stackScroller.getStackScroll(); - final float newScroll = stackLayout.getStackScrollForTask(newFocusedTask); + final float newScroll = stackScroller.getBoundedStackScroll( + stackLayout.getStackScrollForTask(newFocusedTask)); boolean willScrollToFront = newScroll > curScroll; boolean willScroll = Float.compare(newScroll, curScroll) != 0; diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java index 9eab0f60584f..b75a91e8c42b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java @@ -29,6 +29,7 @@ import android.view.ViewDebug; import com.android.systemui.R; import com.android.systemui.recents.Recents; +import com.android.systemui.recents.RecentsActivity; import com.android.systemui.recents.RecentsActivityLaunchState; import com.android.systemui.recents.RecentsConfiguration; import com.android.systemui.recents.RecentsDebugFlags; @@ -38,6 +39,7 @@ import com.android.systemui.recents.misc.Utilities; import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.TaskStack; +import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -108,6 +110,8 @@ class Range { */ public class TaskStackLayoutAlgorithm { + private static final String TAG = "TaskStackLayoutAlgorithm"; + // The distribution of view bounds alpha // XXX: This is a hack because you can currently set the max alpha to be > 1f public static final float OUTLINE_ALPHA_MIN_VALUE = 0f; @@ -530,8 +534,12 @@ public class TaskStackLayoutAlgorithm { ? stack.indexOfStackTask(launchTask) : mNumStackTasks - 1; if (getInitialFocusState() == STATE_FOCUSED) { + int maxBottomOffset = mStackBottomOffset + mTaskRect.height(); + float maxBottomNormX = getNormalizedXFromFocusedY(maxBottomOffset, FROM_BOTTOM); + mFocusedRange.offset(0f); mMinScrollP = 0; - mMaxScrollP = Math.max(mMinScrollP, mNumStackTasks - 1); + mMaxScrollP = Math.max(mMinScrollP, (mNumStackTasks - 1) - + Math.max(0, mFocusedRange.getAbsoluteX(maxBottomNormX))); if (launchState.launchedFromHome) { mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP); } else { @@ -555,7 +563,10 @@ public class TaskStackLayoutAlgorithm { Math.max(0, mUnfocusedRange.getAbsoluteX(maxBottomNormX))); boolean scrollToFront = launchState.launchedFromHome || launchState.launchedViaDockGesture; - if (scrollToFront) { + if (launchState.launchedWithAltTab) { + mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP); + mInitialNormX = null; + } else if (scrollToFront) { mInitialScrollP = Utilities.clamp(launchTaskIndex, mMinScrollP, mMaxScrollP); mInitialNormX = null; } else { @@ -652,8 +663,9 @@ public class TaskStackLayoutAlgorithm { * Returns the default focus state. */ public int getInitialFocusState() { + RecentsActivityLaunchState launchState = Recents.getConfiguration().getLaunchState(); RecentsDebugFlags debugFlags = Recents.getDebugFlags(); - if (debugFlags.isPagingEnabled()) { + if (debugFlags.isPagingEnabled() || launchState.launchedWithAltTab) { return STATE_FOCUSED; } else { return STATE_UNFOCUSED; @@ -675,7 +687,6 @@ public class TaskStackLayoutAlgorithm { } /** - * * Returns the current stack state. */ public StackState getStackState() { @@ -1027,6 +1038,18 @@ public class TaskStackLayoutAlgorithm { } /** + * Returns the normalized x on the focused curve given an absolute Y position (relative to the + * stack height). + */ + private float getNormalizedXFromFocusedY(float y, @AnchorSide int fromSide) { + float offset = (fromSide == FROM_TOP) + ? mStackRect.height() - y + : y; + float offsetPct = offset / mStackRect.height(); + return mFocusedCurveInterpolator.getX(offsetPct); + } + + /** * Creates a new path for the focused curve. */ private Path constructFocusedCurve() { @@ -1036,10 +1059,13 @@ public class TaskStackLayoutAlgorithm { float topPeekHeightPct = (float) mFocusedTopPeekHeight / mStackRect.height(); float bottomPeekHeightPct = (float) (mStackBottomOffset + mFocusedBottomPeekHeight) / mStackRect.height(); + float minBottomPeekHeightPct = (float) (mFocusedTopPeekHeight + mTaskRect.height() - + mMinMargin) / mStackRect.height(); Path p = new Path(); p.moveTo(0f, 1f); p.lineTo(0.5f, 1f - topPeekHeightPct); - p.lineTo(1f - (0.5f / mFocusedRange.relativeMax), bottomPeekHeightPct); + p.lineTo(1f - (0.5f / mFocusedRange.relativeMax), Math.max(1f - minBottomPeekHeightPct, + bottomPeekHeightPct)); p.lineTo(1f, 0f); return p; } @@ -1133,4 +1159,44 @@ public class TaskStackLayoutAlgorithm { mBackOfStackTransform.visible = true; mFrontOfStackTransform.visible = true; } -} + + public void dump(String prefix, PrintWriter writer) { + String innerPrefix = prefix + " "; + + writer.print(prefix); writer.print(TAG); + writer.write(" numStackTasks="); writer.write(mNumStackTasks); + writer.println(); + + writer.print(innerPrefix); + writer.print("insets="); writer.print(Utilities.dumpRect(mSystemInsets)); + writer.print(" stack="); writer.print(Utilities.dumpRect(mStackRect)); + writer.print(" task="); writer.print(Utilities.dumpRect(mTaskRect)); + writer.print(" freeform="); writer.print(Utilities.dumpRect(mFreeformRect)); + writer.print(" actionButton="); writer.print(Utilities.dumpRect(mStackActionButtonRect)); + writer.println(); + + writer.print(innerPrefix); + writer.print("minScroll="); writer.print(mMinScrollP); + writer.print(" maxScroll="); writer.print(mMaxScrollP); + writer.print(" initialScroll="); writer.print(mInitialScrollP); + writer.println(); + + writer.print(innerPrefix); + writer.print("focusState="); writer.print(mFocusState); + writer.println(); + + if (mTaskIndexOverrideMap.size() > 0) { + for (int i = mTaskIndexOverrideMap.size() - 1; i >= 0; i--) { + int taskId = mTaskIndexOverrideMap.keyAt(i); + float x = mTaskIndexMap.get(taskId); + float overrideX = mTaskIndexOverrideMap.get(taskId, 0f); + + writer.print(innerPrefix); + writer.print("taskId= "); writer.print(taskId); + writer.print(" x= "); writer.print(x); + writer.print(" overrideX= "); writer.print(overrideX); + writer.println(); + } + } + } +}
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index 5416a4897666..13c8403ab0ab 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -90,6 +90,7 @@ import com.android.systemui.recents.misc.Utilities; import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.TaskStack; +import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -102,6 +103,8 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal TaskStackLayoutAlgorithm.TaskStackLayoutAlgorithmCallbacks, ViewPool.ViewPoolConsumer<TaskView, Task> { + private static final String TAG = "TaskStackView"; + private final static String KEY_SAVED_STATE_SUPER = "saved_instance_state_super"; private final static String KEY_SAVED_STATE_LAYOUT_FOCUSED_STATE = "saved_instance_state_layout_focused_state"; @@ -2067,4 +2070,37 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal mScreenPinningEnabled = ssp.getSystemSetting(getContext(), Settings.System.LOCK_TO_APP_ENABLED) != 0; } + + public void dump(String prefix, PrintWriter writer) { + String innerPrefix = prefix + " "; + String id = Integer.toHexString(System.identityHashCode(this)); + + writer.print(prefix); writer.print(TAG); + writer.print(" hasDefRelayout="); + writer.print(mDeferredTaskViewLayoutAnimation != null ? "Y" : "N"); + writer.print(" clipDirty="); writer.print(mTaskViewsClipDirty ? "Y" : "N"); + writer.print(" awaitingFirstLayout="); writer.print(mAwaitingFirstLayout ? "Y" : "N"); + writer.print(" initialState="); writer.print(mInitialState); + writer.print(" inMeasureLayout="); writer.print(mInMeasureLayout ? "Y" : "N"); + writer.print(" enterAnimCompleted="); writer.print(mEnterAnimationComplete ? "Y" : "N"); + writer.print(" touchExplorationOn="); writer.print(mTouchExplorationEnabled ? "Y" : "N"); + writer.print(" screenPinningOn="); writer.print(mScreenPinningEnabled ? "Y" : "N"); + writer.print(" numIgnoreTasks="); writer.print(mIgnoreTasks.size()); + writer.print(" numViewPool="); writer.print(mViewPool.getViews().size()); + writer.print(" stableStackBounds="); writer.print(Utilities.dumpRect(mStableStackBounds)); + writer.print(" stackBounds="); writer.print(Utilities.dumpRect(mStackBounds)); + writer.print(" stableWindow="); writer.print(Utilities.dumpRect(mStableWindowRect)); + writer.print(" window="); writer.print(Utilities.dumpRect(mWindowRect)); + writer.print(" [0x"); writer.print(id); writer.print("]"); + writer.println(); + + if (mFocusedTask != null) { + writer.print(innerPrefix); + writer.print("Focused task: "); + mFocusedTask.dump(innerPrefix, writer); + } + + mLayoutAlgorithm.dump(innerPrefix, writer); + mStackScroller.dump(innerPrefix, writer); + } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java index 583fb88e4069..19b3c943ae65 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java @@ -30,6 +30,8 @@ import com.android.systemui.Interpolators; import com.android.systemui.R; import com.android.systemui.recents.misc.Utilities; +import java.io.PrintWriter; + /* The scrolling logic for a TaskStackView */ public class TaskStackViewScroller { @@ -246,4 +248,10 @@ public class TaskStackViewScroller { mScroller.abortAnimation(); } } + + public void dump(String prefix, PrintWriter writer) { + writer.print(prefix); writer.print(TAG); + writer.print(" stackScroll:"); writer.print(mStackScrollP); + writer.println(); + } }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java index a2f61c267f03..570ff8a07fe4 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java @@ -459,7 +459,7 @@ public class TaskViewHeader extends FrameLayout if (!mTitleView.getText().toString().equals(t.title)) { mTitleView.setText(t.title); } - mTitleView.setContentDescription(t.contentDescription); + mTitleView.setContentDescription(t.titleDescription); mTitleView.setTextColor(t.useLightOnPrimaryColor ? mTaskBarViewLightTextColor : mTaskBarViewDarkTextColor); if (!t.isDockable && ssp.hasDockedTask()) { @@ -501,6 +501,7 @@ public class TaskViewHeader extends FrameLayout // In accessibility, a single click on the focused app info button will show it if (touchExplorationEnabled) { + mIconView.setContentDescription(t.appInfoDescription); mIconView.setOnClickListener(this); } } diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java index e8cf1261a63b..d294c80bdf51 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/Divider.java @@ -34,8 +34,6 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; * Controls the docked stack divider. */ public class Divider extends SystemUI { - private static final String TAG = "Divider"; - private int mDividerWindowWidth; private DividerWindowManager mWindowManager; private DividerView mView; private DockDividerVisibilityListener mDockDividerVisibilityListener; @@ -46,8 +44,6 @@ public class Divider extends SystemUI { @Override public void start() { mWindowManager = new DividerWindowManager(mContext); - mDividerWindowWidth = mContext.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.docked_stack_divider_thickness); update(mContext.getResources().getConfiguration()); putComponent(Divider.class, this); mDockDividerVisibilityListener = new DockDividerVisibilityListener(); @@ -70,9 +66,11 @@ public class Divider extends SystemUI { mView = (DividerView) LayoutInflater.from(mContext).inflate(R.layout.docked_stack_divider, null); mView.setVisibility(mVisible ? View.VISIBLE : View.INVISIBLE); + final int size = mContext.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.docked_stack_divider_thickness); final boolean landscape = configuration.orientation == ORIENTATION_LANDSCAPE; - final int width = landscape ? mDividerWindowWidth : MATCH_PARENT; - final int height = landscape ? MATCH_PARENT : mDividerWindowWidth; + final int width = landscape ? size : MATCH_PARENT; + final int height = landscape ? MATCH_PARENT : size; mWindowManager.add(mView, width, height); mView.setWindowManager(mWindowManager); } @@ -97,6 +95,9 @@ public class Divider extends SystemUI { if (mVisible != visible) { mVisible = visible; mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); + + // Update state because animations won't finish. + mView.setMinimizedDockStack(mMinimized); } } }); diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index 7a933cd6576a..3005535535cc 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -134,6 +134,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, private ValueAnimator mCurrentAnimator; private boolean mEntranceAnimationRunning; private GestureDetector mGestureDetector; + private boolean mDockedStackMinimized; private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() { @Override @@ -239,16 +240,6 @@ public class DividerView extends FrameLayout implements OnTouchListener, protected void onAttachedToWindow() { super.onAttachedToWindow(); EventBus.getDefault().register(this); - getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { - - @Override - public void onGlobalLayout() { - getViewTreeObserver().removeOnGlobalLayoutListener(this); - mWindowManagerProxy.setTouchRegion(new Rect(mHandle.getLeft(), mHandle.getTop(), - mHandle.getLeft() + mHandle.getWidth(), - mHandle.getTop() + mHandle.getHeight())); - } - }); } @Override @@ -273,6 +264,15 @@ public class DividerView extends FrameLayout implements OnTouchListener, return super.onApplyWindowInsets(insets); } + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + if (changed) { + mWindowManagerProxy.setTouchRegion(new Rect(mHandle.getLeft(), mHandle.getTop(), + mHandle.getRight(), mHandle.getBottom())); + } + } + public void setWindowManager(DividerWindowManager windowManager) { mWindowManager = windowManager; } @@ -538,6 +538,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, : mBackground.getWidth()); mBackground.setScaleX(MINIMIZE_DOCK_SCALE); } + mDockedStackMinimized = minimized; } public void setMinimizedDockStack(boolean minimized, long animDuration) { @@ -566,6 +567,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, .setInterpolator(Interpolators.FAST_OUT_SLOW_IN) .setDuration(animDuration) .start(); + mDockedStackMinimized = minimized; } private void resetBackground() { @@ -883,7 +885,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, public final void onBusEvent(UndockingTaskEvent undockingTaskEvent) { int dockSide = mWindowManagerProxy.getDockSide(); - if (dockSide != WindowManager.DOCKED_INVALID) { + if (dockSide != WindowManager.DOCKED_INVALID && !mDockedStackMinimized) { startDragging(false /* animate */, false /* touching */); SnapTarget target = dockSideTopLeft(dockSide) ? mSnapAlgorithm.getDismissEndTarget() diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index 4ed64260dc7f..1b2393afcccf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -91,6 +91,7 @@ import com.android.internal.statusbar.IStatusBarService; import com.android.internal.statusbar.StatusBarIcon; import com.android.internal.widget.LockPatternUtils; import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.KeyguardHostView.OnDismissAction; import com.android.systemui.DejankUtils; import com.android.systemui.Interpolators; import com.android.systemui.R; @@ -100,6 +101,7 @@ import com.android.systemui.SystemUI; import com.android.systemui.assist.AssistManager; import com.android.systemui.recents.Recents; import com.android.systemui.statusbar.NotificationData.Entry; +import com.android.systemui.statusbar.NotificationGuts.OnGutsClosedListener; import com.android.systemui.statusbar.phone.NavigationBarView; import com.android.systemui.statusbar.phone.NotificationGroupManager; import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager; @@ -107,7 +109,6 @@ import com.android.systemui.statusbar.policy.HeadsUpManager; import com.android.systemui.statusbar.policy.PreviewInflater; import com.android.systemui.statusbar.policy.RemoteInputView; import com.android.systemui.statusbar.stack.NotificationStackScrollLayout; -import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.GearDisplayedListener; import com.android.systemui.statusbar.stack.StackStateAnimator; import java.util.ArrayList; @@ -115,12 +116,12 @@ import java.util.List; import java.util.Locale; import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_HIGH; -import static com.android.keyguard.KeyguardHostView.OnDismissAction; public abstract class BaseStatusBar extends SystemUI implements CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener, ExpandableNotificationRow.ExpansionLogger, NotificationData.Environment, - ExpandableNotificationRow.OnExpandClickListener, GearDisplayedListener { + ExpandableNotificationRow.OnExpandClickListener, + OnGutsClosedListener { public static final String TAG = "StatusBar"; public static final boolean DEBUG = false; public static final boolean MULTIUSER_DEBUG = false; @@ -242,7 +243,6 @@ public abstract class BaseStatusBar extends SystemUI implements // which notification is currently being longpress-examined by the user private NotificationGuts mNotificationGutsExposed; - private ExpandableNotificationRow mNotificationGearDisplayed; private KeyboardShortcuts mKeyboardShortcuts; @@ -287,9 +287,10 @@ public abstract class BaseStatusBar extends SystemUI implements private final ContentObserver mLockscreenSettingsObserver = new ContentObserver(mHandler) { @Override public void onChange(boolean selfChange) { - // We don't know which user changed LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS, - // so we just dump our cache ... + // We don't know which user changed LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS or + // LOCK_SCREEN_SHOW_NOTIFICATIONS, so we just dump our cache ... mUsersAllowingPrivateNotifications.clear(); + mUsersAllowingNotifications.clear(); // ... and refresh all the notifications updateNotifications(); } @@ -1012,6 +1013,7 @@ public abstract class BaseStatusBar extends SystemUI implements PackageManager pmUser = getPackageManagerForUser(mContext, sbn.getUser().getIdentifier()); row.setTag(sbn.getPackageName()); final NotificationGuts guts = row.getGuts(); + guts.setClosedListener(this); final String pkg = sbn.getPackageName(); String appname = pkg; Drawable pkgicon = null; @@ -1039,6 +1041,7 @@ public abstract class BaseStatusBar extends SystemUI implements settingsButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { MetricsLogger.action(mContext, MetricsEvent.ACTION_NOTE_INFO); + guts.resetFalsingCheck(); startAppNotificationSettingsActivity(pkg, appUidF); } }); @@ -1049,26 +1052,41 @@ public abstract class BaseStatusBar extends SystemUI implements row.findViewById(R.id.done).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { - guts.saveImportance(sbn); - - int[] rowLocation = new int[2]; - int[] doneLocation = new int[2]; - row.getLocationOnScreen(rowLocation); - v.getLocationOnScreen(doneLocation); - - final int centerX = v.getWidth() / 2; - final int centerY = v.getHeight() / 2; - final int x = doneLocation[0] - rowLocation[0] + centerX; - final int y = doneLocation[1] - rowLocation[1] + centerY; - dismissPopups(x, y); + // If the user has security enabled, show challenge if the setting is changed. + if (guts.hasImportanceChanged() && isLockscreenPublicMode() && + (mState == StatusBarState.KEYGUARD + || mState == StatusBarState.SHADE_LOCKED)) { + OnDismissAction dismissAction = new OnDismissAction() { + @Override + public boolean onDismiss() { + saveImportanceCloseControls(sbn, row, guts, v); + return true; + } + }; + onLockedNotificationImportanceChange(dismissAction); + } else { + saveImportanceCloseControls(sbn, row, guts, v); + } } }); - guts.bindImportance(pmUser, sbn, row, mNotificationData.getImportance(sbn.getKey())); } - protected GearDisplayedListener getGearDisplayedListener() { - return this; + private void saveImportanceCloseControls(StatusBarNotification sbn, + ExpandableNotificationRow row, NotificationGuts guts, View done) { + guts.resetFalsingCheck(); + guts.saveImportance(sbn); + + int[] rowLocation = new int[2]; + int[] doneLocation = new int[2]; + row.getLocationOnScreen(rowLocation); + done.getLocationOnScreen(doneLocation); + + final int centerX = done.getWidth() / 2; + final int centerY = done.getHeight() / 2; + final int x = doneLocation[0] - rowLocation[0] + centerX; + final int y = doneLocation[1] - rowLocation[1] + centerY; + dismissPopups(x, y); } protected SwipeHelper.LongPressListener getNotificationLongClicker() { @@ -1106,7 +1124,8 @@ public abstract class BaseStatusBar extends SystemUI implements // Post to ensure the the guts are properly laid out. guts.post(new Runnable() { public void run() { - dismissPopups(-1 /* x */, -1 /* y */, false /* resetGear */); + dismissPopups(-1 /* x */, -1 /* y */, false /* resetGear */, + false /* animate */); guts.setVisibility(View.VISIBLE); final double horz = Math.max(guts.getWidth() - x, x); final double vert = Math.max(guts.getHeight() - y, y); @@ -1124,7 +1143,8 @@ public abstract class BaseStatusBar extends SystemUI implements } }); a.start(); - guts.setExposed(true); + guts.setExposed(true /* exposed */, + mState == StatusBarState.KEYGUARD /* needsFalsingProtection */); row.closeRemoteInput(); mStackScroller.onHeightChanged(null, true /* needsAnimation */); mNotificationGutsExposed = guts; @@ -1135,56 +1155,37 @@ public abstract class BaseStatusBar extends SystemUI implements }; } - @Override - public void onGearDisplayed(ExpandableNotificationRow row) { - MetricsLogger.action(mContext, MetricsEvent.ACTION_REVEAL_GEAR, - row.getStatusBarNotification().getPackageName()); - mNotificationGearDisplayed = row; + /** + * Returns the exposed NotificationGuts or null if none are exposed. + */ + public NotificationGuts getExposedGuts() { + return mNotificationGutsExposed; } public void dismissPopups() { - dismissPopups(-1 /* x */, -1 /* y */, true /* resetGear */); + dismissPopups(-1 /* x */, -1 /* y */, true /* resetGear */, false /* animate */); } private void dismissPopups(int x, int y) { - dismissPopups(x, y, true /* resetGear */); + dismissPopups(x, y, true /* resetGear */, false /* animate */); } - public void dismissPopups(int x, int y, boolean resetGear) { + public void dismissPopups(int x, int y, boolean resetGear, boolean animate) { if (mNotificationGutsExposed != null) { - final NotificationGuts v = mNotificationGutsExposed; - mNotificationGutsExposed = null; - - if (v.getWindowToken() == null) return; - if (x == -1 || y == -1) { - x = (v.getLeft() + v.getRight()) / 2; - y = (v.getTop() + v.getHeight() / 2); - } - final double horz = Math.max(v.getWidth() - x, x); - final double vert = Math.max(v.getHeight() - y, y); - final float r = (float) Math.hypot(horz, vert); - final Animator a = ViewAnimationUtils.createCircularReveal(v, - x, y, r, 0); - a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); - a.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN); - a.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); - v.setVisibility(View.GONE); - } - }); - a.start(); - v.setExposed(false); - mStackScroller.onHeightChanged(null, true /* needsAnimation */); + mNotificationGutsExposed.closeControls(x, y, true /* notify */); } - if (resetGear && mNotificationGearDisplayed != null) { - mNotificationGearDisplayed.resetTranslation(); - mNotificationGearDisplayed = null; + if (resetGear) { + mStackScroller.resetExposedGearView(animate, true /* force */); } } @Override + public void onGutsClosed(NotificationGuts guts) { + mStackScroller.onHeightChanged(null, true /* needsAnimation */); + mNotificationGutsExposed = null; + } + + @Override public void showRecentApps(boolean triggeredFromAltTab) { int msg = MSG_SHOW_RECENT_APPS; mHandler.removeMessages(msg); @@ -1456,6 +1457,8 @@ public abstract class BaseStatusBar extends SystemUI implements } } + protected void onLockedNotificationImportanceChange(OnDismissAction dismissAction) {} + protected void onLockedRemoteInput(ExpandableNotificationRow row, View clickedView) {} @Override @@ -1843,11 +1846,12 @@ public abstract class BaseStatusBar extends SystemUI implements .getIdentifier(); if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId) && mKeyguardManager.isDeviceLocked(userId)) { - // Show work challenge, do not run pendingintent and - // remove notification - startWorkChallenge(userId, intent.getIntentSender(), - notificationKey); - return; + if (startWorkChallengeIfNecessary(userId, + intent.getIntentSender(), notificationKey)) { + // Show work challenge, do not run pendingintent and + // remove notification + return; + } } } try { @@ -1885,21 +1889,25 @@ public abstract class BaseStatusBar extends SystemUI implements }, afterKeyguardGone); } - public void startWorkChallenge(int userId, IntentSender intendSender, + public boolean startWorkChallengeIfNecessary(int userId, IntentSender intendSender, String notificationKey) { + final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, + null, userId); + if (newIntent == null) { + return false; + } final Intent callBackIntent = new Intent( WORK_CHALLENGE_UNLOCKED_NOTIFICATION_ACTION); callBackIntent.putExtra(Intent.EXTRA_INTENT, intendSender); callBackIntent.putExtra(Intent.EXTRA_INDEX, notificationKey); callBackIntent.setPackage(mContext.getPackageName()); - final Intent newIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, - null, userId); newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_CLEAR_TASK); newIntent.putExtra(Intent.EXTRA_INTENT, PendingIntent .getBroadcast(mContext, 0, callBackIntent, 0).getIntentSender()); mContext.startActivity(newIntent); + return true; } public void register(ExpandableNotificationRow row, StatusBarNotification sbn) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java index 7f87c3c687d8..2dabf5d32016 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java @@ -170,22 +170,22 @@ public class DragDownHelper implements Gefingerpoken { : RUBBERBAND_FACTOR_STATIC; float rubberband = heightDelta * rubberbandFactor; if (expandable - && (rubberband + child.getMinExpandHeight()) > child.getMaxContentHeight()) { + && (rubberband + child.getCollapsedHeight()) > child.getMaxContentHeight()) { float overshoot = - (rubberband + child.getMinExpandHeight()) - child.getMaxContentHeight(); + (rubberband + child.getCollapsedHeight()) - child.getMaxContentHeight(); overshoot *= (1 - RUBBERBAND_FACTOR_STATIC); rubberband -= overshoot; } - child.setActualHeight((int) (child.getMinExpandHeight() + rubberband)); + child.setActualHeight((int) (child.getCollapsedHeight() + rubberband)); } private void cancelExpansion(final ExpandableView child) { - if (child.getActualHeight() == child.getMinExpandHeight()) { + if (child.getActualHeight() == child.getCollapsedHeight()) { mCallback.setUserLockedChild(child, false); return; } ObjectAnimator anim = ObjectAnimator.ofInt(child, "actualHeight", - child.getActualHeight(), child.getMinExpandHeight()); + child.getActualHeight(), child.getCollapsedHeight()); anim.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); anim.setDuration(SPRING_BACK_ANIMATION_LENGTH_MS); anim.addListener(new AnimatorListenerAdapter() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index f9edeb312644..7ca7d12c590a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -470,7 +470,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { if(mExpandedWhenPinned) { return Math.max(getMaxExpandHeight(), mHeadsUpHeight); } else if (atLeastMinHeight) { - return Math.max(getMinHeight(), mHeadsUpHeight); + return Math.max(getCollapsedHeight(), mHeadsUpHeight); } else { return mHeadsUpHeight; } @@ -1040,12 +1040,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { } else if (isExpanded()) { return Math.max(getMaxExpandHeight(), mHeadsUpHeight); } else { - return Math.max(getMinHeight(), mHeadsUpHeight); + return Math.max(getCollapsedHeight(), mHeadsUpHeight); } } else if (isExpanded()) { return getMaxExpandHeight(); } else { - return getMinHeight(); + return getCollapsedHeight(); } } @@ -1301,9 +1301,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { } @Override - public int getMinExpandHeight() { + public int getCollapsedHeight() { if (mIsSummaryWithChildren && !mShowingPublic) { - return mChildrenContainer.getMinExpandHeight(); + return mChildrenContainer.getCollapsedHeight(); } return getMinHeight(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java index 91418ad312bf..6dcd61f259f3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java @@ -153,11 +153,11 @@ public abstract class ExpandableView extends FrameLayout { } /** - * @return The minimum height this child chan be expanded to. Note that this might be different - * than {@link #getMinHeight()} because some elements can't be collapsed by an expand gesture - * to it's absolute minimal height + * @return The collapsed height of this view. Note that this might be different + * than {@link #getMinHeight()} because some elements like groups may have different sizes when + * they are system expanded. */ - public int getMinExpandHeight() { + public int getCollapsedHeight() { return getHeight(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java index 2b365dc743e9..977a77d59559 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java @@ -21,6 +21,9 @@ import android.app.Dialog; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.drawable.Drawable; import android.hardware.input.InputManager; import android.os.Handler; import android.os.Looper; @@ -37,6 +40,7 @@ import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.view.WindowManager.KeyboardShortcutsReceiver; +import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; @@ -52,175 +56,191 @@ import static android.view.WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG; /** * Contains functionality for handling keyboard shortcuts. */ -public class KeyboardShortcuts { +public final class KeyboardShortcuts { private static final String TAG = KeyboardShortcuts.class.getSimpleName(); - private static final SparseArray<String> SPECIAL_CHARACTER_NAMES = new SparseArray<>(); - private static final SparseArray<String> MODIFIER_NAMES = new SparseArray<>(); + private final SparseArray<String> mSpecialCharacterNames = new SparseArray<>(); + private final SparseArray<String> mModifierNames = new SparseArray<>(); + private final SparseArray<Drawable> mSpecialCharacterDrawables = new SparseArray<>(); + private final SparseArray<Drawable> mModifierDrawables = new SparseArray<>(); - private static void loadSpecialCharacterNames(Context context) { - SPECIAL_CHARACTER_NAMES.put( + private final Handler mHandler = new Handler(Looper.getMainLooper()); + private final Context mContext; + private final OnClickListener dialogCloseListener = new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + dismissKeyboardShortcutsDialog(); + } + }; + + private Dialog mKeyboardShortcutsDialog; + private KeyCharacterMap mKeyCharacterMap; + + public KeyboardShortcuts(Context context) { + this.mContext = new ContextThemeWrapper(context, android.R.style.Theme_Material_Light); + loadResources(context); + } + + private void loadResources(Context context) { + mSpecialCharacterNames.put( KeyEvent.KEYCODE_HOME, context.getString(R.string.keyboard_key_home)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_BACK, context.getString(R.string.keyboard_key_back)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_DPAD_UP, context.getString(R.string.keyboard_key_dpad_up)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_DPAD_DOWN, context.getString(R.string.keyboard_key_dpad_down)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_DPAD_LEFT, context.getString(R.string.keyboard_key_dpad_left)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_DPAD_RIGHT, context.getString(R.string.keyboard_key_dpad_right)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_DPAD_CENTER, context.getString(R.string.keyboard_key_dpad_center)); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_PERIOD, "."); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put(KeyEvent.KEYCODE_PERIOD, "."); + mSpecialCharacterNames.put( KeyEvent.KEYCODE_TAB, context.getString(R.string.keyboard_key_tab)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_SPACE, context.getString(R.string.keyboard_key_space)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_ENTER, context.getString(R.string.keyboard_key_enter)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_DEL, context.getString(R.string.keyboard_key_backspace)); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE, context.getString(R.string.keyboard_key_media_play_pause)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_MEDIA_STOP, context.getString(R.string.keyboard_key_media_stop)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_MEDIA_NEXT, context.getString(R.string.keyboard_key_media_next)); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MEDIA_PREVIOUS, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_MEDIA_PREVIOUS, context.getString(R.string.keyboard_key_media_previous)); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MEDIA_REWIND, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_MEDIA_REWIND, context.getString(R.string.keyboard_key_media_rewind)); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD, context.getString(R.string.keyboard_key_media_fast_forward)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_PAGE_UP, context.getString(R.string.keyboard_key_page_up)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_PAGE_DOWN, context.getString(R.string.keyboard_key_page_down)); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_A, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_A, context.getString(R.string.keyboard_key_button_template, "A")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_B, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_B, context.getString(R.string.keyboard_key_button_template, "B")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_C, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_C, context.getString(R.string.keyboard_key_button_template, "C")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_X, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_X, context.getString(R.string.keyboard_key_button_template, "X")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_Y, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_Y, context.getString(R.string.keyboard_key_button_template, "Y")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_Z, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_Z, context.getString(R.string.keyboard_key_button_template, "Z")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_L1, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_L1, context.getString(R.string.keyboard_key_button_template, "L1")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_R1, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_R1, context.getString(R.string.keyboard_key_button_template, "R1")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_L2, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_L2, context.getString(R.string.keyboard_key_button_template, "L2")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_R2, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_R2, context.getString(R.string.keyboard_key_button_template, "R2")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_START, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_START, context.getString(R.string.keyboard_key_button_template, "Start")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_SELECT, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_SELECT, context.getString(R.string.keyboard_key_button_template, "Select")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BUTTON_MODE, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BUTTON_MODE, context.getString(R.string.keyboard_key_button_template, "Mode")); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_FORWARD_DEL, context.getString(R.string.keyboard_key_forward_del)); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_ESCAPE, "Esc"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_SYSRQ, "SysRq"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_BREAK, "Break"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_SCROLL_LOCK, "Scroll Lock"); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put(KeyEvent.KEYCODE_ESCAPE, "Esc"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_SYSRQ, "SysRq"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_BREAK, "Break"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_SCROLL_LOCK, "Scroll Lock"); + mSpecialCharacterNames.put( KeyEvent.KEYCODE_MOVE_HOME, context.getString(R.string.keyboard_key_move_home)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_MOVE_END, context.getString(R.string.keyboard_key_move_end)); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put( KeyEvent.KEYCODE_INSERT, context.getString(R.string.keyboard_key_insert)); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F1, "F1"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F2, "F2"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F3, "F3"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F4, "F4"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F5, "F5"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F6, "F6"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F7, "F7"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F8, "F8"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F9, "F9"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F10, "F10"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F11, "F11"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_F12, "F12"); - SPECIAL_CHARACTER_NAMES.put( + mSpecialCharacterNames.put(KeyEvent.KEYCODE_F1, "F1"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_F2, "F2"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_F3, "F3"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_F4, "F4"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_F5, "F5"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_F6, "F6"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_F7, "F7"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_F8, "F8"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_F9, "F9"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_F10, "F10"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_F11, "F11"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_F12, "F12"); + mSpecialCharacterNames.put( KeyEvent.KEYCODE_NUM_LOCK, context.getString(R.string.keyboard_key_num_lock)); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_0, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_0, context.getString(R.string.keyboard_key_numpad_template, "0")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_1, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_1, context.getString(R.string.keyboard_key_numpad_template, "1")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_2, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_2, context.getString(R.string.keyboard_key_numpad_template, "2")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_3, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_3, context.getString(R.string.keyboard_key_numpad_template, "3")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_4, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_4, context.getString(R.string.keyboard_key_numpad_template, "4")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_5, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_5, context.getString(R.string.keyboard_key_numpad_template, "5")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_6, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_6, context.getString(R.string.keyboard_key_numpad_template, "6")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_7, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_7, context.getString(R.string.keyboard_key_numpad_template, "7")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_8, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_8, context.getString(R.string.keyboard_key_numpad_template, "8")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_9, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_9, context.getString(R.string.keyboard_key_numpad_template, "9")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_DIVIDE, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_DIVIDE, context.getString(R.string.keyboard_key_numpad_template, "/")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_MULTIPLY, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_MULTIPLY, context.getString(R.string.keyboard_key_numpad_template, "*")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_SUBTRACT, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_SUBTRACT, context.getString(R.string.keyboard_key_numpad_template, "-")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_ADD, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_ADD, context.getString(R.string.keyboard_key_numpad_template, "+")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_DOT, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_DOT, context.getString(R.string.keyboard_key_numpad_template, ".")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_COMMA, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_COMMA, context.getString(R.string.keyboard_key_numpad_template, ",")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_ENTER, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_ENTER, context.getString(R.string.keyboard_key_numpad_template, context.getString(R.string.keyboard_key_enter))); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_EQUALS, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_EQUALS, context.getString(R.string.keyboard_key_numpad_template, "=")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_LEFT_PAREN, context.getString(R.string.keyboard_key_numpad_template, "(")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN, + mSpecialCharacterNames.put(KeyEvent.KEYCODE_NUMPAD_RIGHT_PAREN, context.getString(R.string.keyboard_key_numpad_template, ")")); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_ZENKAKU_HANKAKU, "半角/全角"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_EISU, "英数"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_MUHENKAN, "無変換"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_HENKAN, "変換"); - SPECIAL_CHARACTER_NAMES.put(KeyEvent.KEYCODE_KATAKANA_HIRAGANA, "かな"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_ZENKAKU_HANKAKU, "半角/全角"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_EISU, "英数"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_MUHENKAN, "無変換"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_HENKAN, "変換"); + mSpecialCharacterNames.put(KeyEvent.KEYCODE_KATAKANA_HIRAGANA, "かな"); - MODIFIER_NAMES.put(KeyEvent.META_META_ON, "Meta"); - MODIFIER_NAMES.put(KeyEvent.META_CTRL_ON, "Ctrl"); - MODIFIER_NAMES.put(KeyEvent.META_ALT_ON, "Alt"); - MODIFIER_NAMES.put(KeyEvent.META_SHIFT_ON, "Shift"); - MODIFIER_NAMES.put(KeyEvent.META_SYM_ON, "Sym"); - MODIFIER_NAMES.put(KeyEvent.META_FUNCTION_ON, "Fn"); - } + mModifierNames.put(KeyEvent.META_META_ON, "Meta"); + mModifierNames.put(KeyEvent.META_CTRL_ON, "Ctrl"); + mModifierNames.put(KeyEvent.META_ALT_ON, "Alt"); + mModifierNames.put(KeyEvent.META_SHIFT_ON, "Shift"); + mModifierNames.put(KeyEvent.META_SYM_ON, "Sym"); + mModifierNames.put(KeyEvent.META_FUNCTION_ON, "Fn"); - private final Handler mHandler = new Handler(Looper.getMainLooper()); - private final Context mContext; - private final OnClickListener dialogCloseListener = new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int id) { - dismissKeyboardShortcutsDialog(); - } - }; - - private Dialog mKeyboardShortcutsDialog; - private KeyCharacterMap mKeyCharacterMap; + mSpecialCharacterDrawables.put( + KeyEvent.KEYCODE_DEL, context.getDrawable(R.drawable.ic_ksh_key_backspace)); + mSpecialCharacterDrawables.put( + KeyEvent.KEYCODE_ENTER, context.getDrawable(R.drawable.ic_ksh_key_enter)); + mSpecialCharacterDrawables.put( + KeyEvent.KEYCODE_DPAD_UP, context.getDrawable(R.drawable.ic_ksh_key_up)); + mSpecialCharacterDrawables.put( + KeyEvent.KEYCODE_DPAD_RIGHT, context.getDrawable(R.drawable.ic_ksh_key_right)); + mSpecialCharacterDrawables.put( + KeyEvent.KEYCODE_DPAD_DOWN, context.getDrawable(R.drawable.ic_ksh_key_down)); + mSpecialCharacterDrawables.put( + KeyEvent.KEYCODE_DPAD_LEFT, context.getDrawable(R.drawable.ic_ksh_key_left)); - public KeyboardShortcuts(Context context) { - this.mContext = new ContextThemeWrapper(context, android.R.style.Theme_Material_Light); - if (SPECIAL_CHARACTER_NAMES.size() == 0) { - loadSpecialCharacterNames(context); - } + mModifierDrawables.put( + KeyEvent.META_META_ON, context.getDrawable(R.drawable.ic_ksh_key_meta)); } public void toggleKeyboardShortcuts(int deviceId) { @@ -343,6 +363,8 @@ public class KeyboardShortcuts { List<KeyboardShortcutGroup> keyboardShortcutGroups) { LayoutInflater inflater = LayoutInflater.from(mContext); final int keyboardShortcutGroupsSize = keyboardShortcutGroups.size(); + // Needed to be able to scale the image items to the same height as the text items. + final int shortcutTextItemHeight = getShortcutTextItemHeight(inflater); for (int i = 0; i < keyboardShortcutGroupsSize; i++) { KeyboardShortcutGroup group = keyboardShortcutGroups.get(i); TextView categoryTitle = (TextView) inflater.inflate( @@ -364,7 +386,7 @@ public class KeyboardShortcuts { Log.w(TAG, "Keyboard Shortcut contains key not on device, skipping."); continue; } - List<String> shortcutKeys = getHumanReadableShortcutKeys(info); + List<StringOrDrawable> shortcutKeys = getHumanReadableShortcutKeys(info); if (shortcutKeys == null) { // Ignore shortcuts we can't display keys for. Log.w(TAG, "Keyboard Shortcut contains unsupported keys, skipping."); @@ -380,11 +402,26 @@ public class KeyboardShortcuts { .findViewById(R.id.keyboard_shortcuts_item_container); final int shortcutKeysSize = shortcutKeys.size(); for (int k = 0; k < shortcutKeysSize; k++) { - String shortcutKey = shortcutKeys.get(k); - TextView shortcutKeyView = (TextView) inflater.inflate( - R.layout.keyboard_shortcuts_key_view, shortcutItemsContainer, false); - shortcutKeyView.setText(shortcutKey); - shortcutItemsContainer.addView(shortcutKeyView); + StringOrDrawable shortcutRepresentation = shortcutKeys.get(k); + if (shortcutRepresentation.drawable != null) { + ImageView shortcutKeyIconView = (ImageView) inflater.inflate( + R.layout.keyboard_shortcuts_key_icon_view, shortcutItemsContainer, + false); + Bitmap bitmap = Bitmap.createBitmap(shortcutTextItemHeight, + shortcutTextItemHeight, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + shortcutRepresentation.drawable.setBounds(0, 0, canvas.getWidth(), + canvas.getHeight()); + shortcutRepresentation.drawable.draw(canvas); + shortcutKeyIconView.setImageBitmap(bitmap); + shortcutItemsContainer.addView(shortcutKeyIconView); + } else if (shortcutRepresentation.string != null) { + TextView shortcutKeyTextView = (TextView) inflater.inflate( + R.layout.keyboard_shortcuts_key_view, shortcutItemsContainer, + false); + shortcutKeyTextView.setText(shortcutRepresentation.string); + shortcutItemsContainer.addView(shortcutKeyTextView); + } } shortcutContainer.addView(shortcutView); } @@ -398,16 +435,29 @@ public class KeyboardShortcuts { } } - private List<String> getHumanReadableShortcutKeys(KeyboardShortcutInfo info) { - List<String> shortcutKeys = getHumanReadableModifiers(info); + private int getShortcutTextItemHeight(LayoutInflater inflater) { + TextView shortcutKeyTextView = (TextView) inflater.inflate( + R.layout.keyboard_shortcuts_key_view, null, false); + shortcutKeyTextView.measure( + View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); + return shortcutKeyTextView.getMeasuredHeight() + - shortcutKeyTextView.getPaddingTop() + - shortcutKeyTextView.getPaddingBottom(); + } + + private List<StringOrDrawable> getHumanReadableShortcutKeys(KeyboardShortcutInfo info) { + List<StringOrDrawable> shortcutKeys = getHumanReadableModifiers(info); if (shortcutKeys == null) { return null; } - String displayLabelString; + String displayLabelString = null; + Drawable displayLabelDrawable = null; if (info.getBaseCharacter() > Character.MIN_VALUE) { displayLabelString = String.valueOf(info.getBaseCharacter()); - } else if (SPECIAL_CHARACTER_NAMES.get(info.getKeycode()) != null) { - displayLabelString = SPECIAL_CHARACTER_NAMES.get(info.getKeycode()); + } else if (mSpecialCharacterDrawables.get(info.getKeycode()) != null) { + displayLabelDrawable = mSpecialCharacterDrawables.get(info.getKeycode()); + } else if (mSpecialCharacterNames.get(info.getKeycode()) != null) { + displayLabelString = mSpecialCharacterNames.get(info.getKeycode()); } else { // Special case for shortcuts with no base key or keycode. if (info.getKeycode() == KeyEvent.KEYCODE_UNKNOWN) { @@ -422,20 +472,31 @@ public class KeyboardShortcuts { return null; } } - shortcutKeys.add(displayLabelString.toUpperCase()); + + if (displayLabelDrawable != null) { + shortcutKeys.add(new StringOrDrawable(displayLabelDrawable)); + } else if (displayLabelString != null) { + shortcutKeys.add(new StringOrDrawable(displayLabelString.toUpperCase())); + } return shortcutKeys; } - private List<String> getHumanReadableModifiers(KeyboardShortcutInfo info) { - final List<String> shortcutKeys = new ArrayList<>(); + private List<StringOrDrawable> getHumanReadableModifiers(KeyboardShortcutInfo info) { + final List<StringOrDrawable> shortcutKeys = new ArrayList<>(); int modifiers = info.getModifiers(); if (modifiers == 0) { return shortcutKeys; } - for(int i = 0; i < MODIFIER_NAMES.size(); ++i) { - final int supportedModifier = MODIFIER_NAMES.keyAt(i); + for(int i = 0; i < mModifierNames.size(); ++i) { + final int supportedModifier = mModifierNames.keyAt(i); if ((modifiers & supportedModifier) != 0) { - shortcutKeys.add(MODIFIER_NAMES.get(supportedModifier).toUpperCase()); + if (mModifierDrawables.get(supportedModifier) != null) { + shortcutKeys.add(new StringOrDrawable( + mModifierDrawables.get(supportedModifier))); + } else { + shortcutKeys.add(new StringOrDrawable( + mModifierNames.get(supportedModifier).toUpperCase())); + } modifiers &= ~supportedModifier; } } @@ -445,4 +506,17 @@ public class KeyboardShortcuts { } return shortcutKeys; } + + private static final class StringOrDrawable { + public String string; + public Drawable drawable; + + public StringOrDrawable(String string) { + this.string = string; + } + + public StringOrDrawable(Drawable drawable) { + this.drawable = drawable; + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java index f4fb0b925b07..5b005237e5d4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java @@ -604,7 +604,7 @@ public class NotificationContentView extends FrameLayout { } int expandedVisualType = getVisualTypeForHeight(height); int collapsedVisualType = getVisualTypeForHeight( - mContainingNotification.getMinExpandHeight()); + mContainingNotification.getCollapsedHeight()); return mTransformationStartVisibleType == collapsedVisualType ? expandedVisualType : collapsedVisualType; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java index 45a24a0b3822..3c464d5a1819 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationGuts.java @@ -16,28 +16,35 @@ package com.android.systemui.statusbar; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.app.INotificationManager; import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.Canvas; import android.graphics.drawable.Drawable; +import android.os.Handler; import android.os.RemoteException; import android.os.ServiceManager; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.util.AttributeSet; import android.view.View; +import android.view.ViewAnimationUtils; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.RadioButton; +import android.widget.RadioGroup; import android.widget.SeekBar; import android.widget.TextView; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.MetricsProto.MetricsEvent; import com.android.settingslib.Utils; +import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.statusbar.stack.StackStateAnimator; import com.android.systemui.tuner.TunerService; /** @@ -46,6 +53,8 @@ import com.android.systemui.tuner.TunerService; public class NotificationGuts extends LinearLayout implements TunerService.Tunable { public static final String SHOW_SLIDER = "show_importance_slider"; + private static final long CLOSE_GUTS_DELAY = 8000; + private Drawable mBackground; private int mClipTopAmount; private int mActualHeight; @@ -59,10 +68,35 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab private RadioButton mSilent; private RadioButton mReset; + private Handler mHandler; + private Runnable mFalsingCheck; + private boolean mNeedsFalsingProtection; + private OnGutsClosedListener mListener; + + public interface OnGutsClosedListener { + public void onGutsClosed(NotificationGuts guts); + } + public NotificationGuts(Context context, AttributeSet attrs) { super(context, attrs); setWillNotDraw(false); TunerService.get(mContext).addTunable(this, SHOW_SLIDER); + mHandler = new Handler(); + mFalsingCheck = new Runnable() { + @Override + public void run() { + if (mNeedsFalsingProtection && mExposed) { + closeControls(-1 /* x */, -1 /* y */, true /* notify */); + } + } + }; + } + + public void resetFalsingCheck() { + mHandler.removeCallbacks(mFalsingCheck); + if (mNeedsFalsingProtection && mExposed) { + mHandler.postDelayed(mFalsingCheck, CLOSE_GUTS_DELAY); + } } @Override @@ -130,30 +164,23 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab importanceSlider.setVisibility(View.VISIBLE); importanceButtons.setVisibility(View.GONE); } else { - int userImportance = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED; + mStartingImportance = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED; try { - userImportance = + mStartingImportance = mINotificationManager.getImportance(sbn.getPackageName(), sbn.getUid()); } catch (RemoteException e) {} - bindToggles(importanceButtons, userImportance, systemApp); + bindToggles(importanceButtons, mStartingImportance, systemApp); importanceButtons.setVisibility(View.VISIBLE); importanceSlider.setVisibility(View.GONE); } } + public boolean hasImportanceChanged() { + return mStartingImportance != getSelectedImportance(); + } + void saveImportance(final StatusBarNotification sbn) { - int progress; - if (mSeekBar!= null && mSeekBar.isShown()) { - progress = mSeekBar.getProgress(); - } else { - if (mBlock.isChecked()) { - progress = NotificationListenerService.Ranking.IMPORTANCE_NONE; - } else if (mSilent.isChecked()) { - progress = NotificationListenerService.Ranking.IMPORTANCE_LOW; - } else { - progress = NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED; - } - } + int progress = getSelectedImportance(); MetricsLogger.action(mContext, MetricsEvent.ACTION_SAVE_IMPORTANCE, progress - mStartingImportance); try { @@ -163,8 +190,29 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab } } + private int getSelectedImportance() { + if (mSeekBar!= null && mSeekBar.isShown()) { + return mSeekBar.getProgress(); + } else { + if (mBlock.isChecked()) { + return NotificationListenerService.Ranking.IMPORTANCE_NONE; + } else if (mSilent.isChecked()) { + return NotificationListenerService.Ranking.IMPORTANCE_LOW; + } else { + return NotificationListenerService.Ranking.IMPORTANCE_UNSPECIFIED; + } + } + } + private void bindToggles(final View importanceButtons, final int importance, final boolean systemApp) { + ((RadioGroup) importanceButtons).setOnCheckedChangeListener( + new RadioGroup.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(RadioGroup group, int checkedId) { + resetFalsingCheck(); + } + }); mBlock = (RadioButton) importanceButtons.findViewById(R.id.block_importance); mSilent = (RadioButton) importanceButtons.findViewById(R.id.silent_importance); mReset = (RadioButton) importanceButtons.findViewById(R.id.reset_importance); @@ -198,6 +246,7 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab mSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + resetFalsingCheck(); if (progress < minProgress) { seekBar.setProgress(minProgress); progress = minProgress; @@ -210,7 +259,7 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab @Override public void onStartTrackingTouch(SeekBar seekBar) { - // no-op + resetFalsingCheck(); } @Override @@ -256,6 +305,38 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab mSeekBar.setProgress(mStartingImportance); } + public void closeControls(int x, int y, boolean notify) { + if (getWindowToken() == null) { + if (notify && mListener != null) { + mListener.onGutsClosed(this); + } + return; + } + if (x == -1 || y == -1) { + x = (getLeft() + getRight()) / 2; + y = (getTop() + getHeight() / 2); + } + final double horz = Math.max(getWidth() - x, x); + final double vert = Math.max(getHeight() - y, y); + final float r = (float) Math.hypot(horz, vert); + final Animator a = ViewAnimationUtils.createCircularReveal(this, + x, y, r, 0); + a.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD); + a.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN); + a.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + super.onAnimationEnd(animation); + setVisibility(View.GONE); + } + }); + a.start(); + setExposed(false, mNeedsFalsingProtection); + if (notify && mListener != null) { + mListener.onGutsClosed(this); + } + } + public void setActualHeight(int actualHeight) { mActualHeight = actualHeight; invalidate(); @@ -277,8 +358,18 @@ public class NotificationGuts extends LinearLayout implements TunerService.Tunab return false; } - public void setExposed(boolean exposed) { + public void setClosedListener(OnGutsClosedListener listener) { + mListener = listener; + } + + public void setExposed(boolean exposed, boolean needsFalsingProtection) { mExposed = exposed; + mNeedsFalsingProtection = needsFalsingProtection; + if (mExposed && mNeedsFalsingProtection) { + resetFalsingCheck(); + } else { + mHandler.removeCallbacks(mFalsingCheck); + } } public boolean areGutsExposed() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java index c70aad2d4198..06d79a7f9124 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java @@ -131,11 +131,8 @@ public class NotificationHeaderUtil { mComparators.add(HeaderProcessor.forTextView(mRow, com.android.internal.R.id.app_name_text)); mComparators.add(HeaderProcessor.forTextView(mRow, - com.android.internal.R.id.header_sub_text)); - mComparators.add(HeaderProcessor.forTextView(mRow, - com.android.internal.R.id.header_content_info)); - mDividers.add(com.android.internal.R.id.sub_text_divider); - mDividers.add(com.android.internal.R.id.content_info_divider); + com.android.internal.R.id.header_text)); + mDividers.add(com.android.internal.R.id.header_text_divider); mDividers.add(com.android.internal.R.id.time_divider); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java index a3e78c165b2f..a5ebbbab36b3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java @@ -41,7 +41,7 @@ public class NotificationSettingsIconRow extends FrameLayout implements View.OnC /** * Called when a notification is slid back over the gear. */ - public void onSettingsIconRowReset(NotificationSettingsIconRow row); + public void onSettingsIconRowReset(ExpandableNotificationRow row); } private ExpandableNotificationRow mParent; @@ -92,9 +92,9 @@ public class NotificationSettingsIconRow extends FrameLayout implements View.OnC mAnimating = false; mSnapping = false; mDismissing = false; - setIconLocation(true /* on left */); + setIconLocation(true /* on left */, true /* force */); if (mListener != null) { - mListener.onSettingsIconRowReset(this); + mListener.onSettingsIconRowReset(mParent); } } @@ -104,6 +104,7 @@ public class NotificationSettingsIconRow extends FrameLayout implements View.OnC public void setNotificationRowParent(ExpandableNotificationRow parent) { mParent = parent; + setIconLocation(mOnLeft, true /* force */); } public void setAppName(String appName) { @@ -183,7 +184,7 @@ public class NotificationSettingsIconRow extends FrameLayout implements View.OnC if (isIconLocationChange(transX)) { setGearAlpha(0f); } - setIconLocation(transX > 0 /* fromLeft */); + setIconLocation(transX > 0 /* fromLeft */, false /* force */); mFadeAnimator = ValueAnimator.ofFloat(mGearIcon.getAlpha(), 1); mFadeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override @@ -220,12 +221,20 @@ public class NotificationSettingsIconRow extends FrameLayout implements View.OnC mFadeAnimator.start(); } - public void setIconLocation(boolean onLeft) { - if (onLeft == mOnLeft || mSnapping) { - // Same side? Do nothing. + @Override + public void onRtlPropertiesChanged(int layoutDirection) { + setIconLocation(mOnLeft, true /* force */); + } + + public void setIconLocation(boolean onLeft, boolean force) { + if ((!force && onLeft == mOnLeft) || mSnapping || mParent == null) { + // Do nothing return; } - setTranslationX(onLeft ? 0 : (mParent.getWidth() - mHorizSpaceForGear)); + final boolean isRtl = mParent.isLayoutRtl(); + final float left = isRtl ? -(mParent.getWidth() - mHorizSpaceForGear) : 0; + final float right = isRtl ? 0 : (mParent.getWidth() - mHorizSpaceForGear); + setTranslationX(onLeft ? left : right); mOnLeft = onLeft; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileController.java index 63ee0c02ba63..41eed565506d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ManagedProfileController.java @@ -113,7 +113,8 @@ public class ManagedProfileController { filter.addAction(Intent.ACTION_USER_SWITCHED); filter.addAction(Intent.ACTION_MANAGED_PROFILE_ADDED); filter.addAction(Intent.ACTION_MANAGED_PROFILE_REMOVED); - filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED); + filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); + filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, filter, null, null); } else { mContext.unregisterReceiver(mReceiver); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java index 260c9697c293..ec45d604b829 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java @@ -182,7 +182,7 @@ public class NavigationBarInflaterView extends FrameLayout implements TunerServi private void inflateButtons(String[] buttons, ViewGroup parent, boolean landscape) { for (int i = 0; i < buttons.length; i++) { - inflateButton(buttons[i], parent, landscape); + inflateButton(buttons[i], parent, landscape, i); } } @@ -195,7 +195,8 @@ public class NavigationBarInflaterView extends FrameLayout implements TunerServi } @Nullable - protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape) { + protected View inflateButton(String buttonSpec, ViewGroup parent, boolean landscape, + int indexInParent) { LayoutInflater inflater = landscape ? mLandscapeInflater : mLayoutInflater; float size = extractSize(buttonSpec); String button = extractButton(buttonSpec); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java index 56a7dbed52cb..68593484a862 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java @@ -76,6 +76,8 @@ public class NavigationBarView extends LinearLayout { private Drawable mHomeDefaultIcon, mHomeCarModeIcon; private Drawable mRecentIcon; private Drawable mDockedIcon; + private Drawable mImeIcon; + private Drawable mMenuIcon; private NavigationBarGestureHelper mGestureHelper; private DeadZone mDeadZone; @@ -270,7 +272,8 @@ public class NavigationBarView extends LinearLayout { } private void updateIcons(Context ctx, Configuration oldConfig, Configuration newConfig) { - if (oldConfig.orientation != newConfig.orientation) { + if (oldConfig.orientation != newConfig.orientation + || oldConfig.densityDpi != newConfig.densityDpi) { mDockedIcon = ctx.getDrawable(R.drawable.ic_sysbar_docked); } if (oldConfig.densityDpi != newConfig.densityDpi) { @@ -280,8 +283,10 @@ public class NavigationBarView extends LinearLayout { mBackAltLandIcon = mBackAltIcon; mHomeDefaultIcon = ctx.getDrawable(R.drawable.ic_sysbar_home); - mRecentIcon = ctx.getDrawable(R.drawable.ic_sysbar_recent); + mMenuIcon = ctx.getDrawable(R.drawable.ic_sysbar_menu); + mImeIcon = ctx.getDrawable(R.drawable.ic_ime_switcher_default); + updateCarModeIcons(ctx); } } @@ -348,9 +353,11 @@ public class NavigationBarView extends LinearLayout { final boolean showImeButton = ((hints & StatusBarManager.NAVIGATION_HINT_IME_SHOWN) != 0); getImeSwitchButton().setVisibility(showImeButton ? View.VISIBLE : View.INVISIBLE); + getImeSwitchButton().setImageDrawable(mImeIcon); // Update menu button in case the IME state has changed. setMenuVisibility(mShowMenu, true); + getMenuButton().setImageDrawable(mMenuIcon); setDisabledFlags(mDisabledFlags, true); } @@ -595,14 +602,12 @@ public class NavigationBarView extends LinearLayout { super.onConfigurationChanged(newConfig); boolean uiCarModeChanged = updateCarMode(newConfig); updateTaskSwitchHelper(); - if (uiCarModeChanged) { - // uiMode changed either from carmode or to carmode. - // replace the nav bar button icons based on which mode - // we are switching to. - setNavigationIconHints(mNavigationIconHints, true); - } updateIcons(getContext(), mConfiguration, newConfig); updateRecentsIcon(); + if (uiCarModeChanged || mConfiguration.densityDpi != newConfig.densityDpi) { + // If car mode or density changes, we need to reset the icons. + setNavigationIconHints(mNavigationIconHints, true); + } mConfiguration.updateFrom(newConfig); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index c563eb606663..bf58592c7ca9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -755,7 +755,6 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById( R.id.notification_stack_scroller); mStackScroller.setLongPressListener(getNotificationLongClicker()); - mStackScroller.setGearDisplayedListener(getGearDisplayedListener()); mStackScroller.setPhoneStatusBar(this); mStackScroller.setGroupManager(mGroupManager); mStackScroller.setHeadsUpManager(mHeadsUpManager); @@ -3304,10 +3303,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, protected void loadDimens() { final Resources res = mContext.getResources(); + int oldBarHeight = mNaturalBarHeight; mNaturalBarHeight = res.getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); - - mMaxAllowedKeyguardNotifications = res.getInteger(R.integer.keyguard_max_notification_count); + if (mStatusBarWindowManager != null && mNaturalBarHeight != oldBarHeight) { + mStatusBarWindowManager.setBarHeight(mNaturalBarHeight); + } + mMaxAllowedKeyguardNotifications = res.getInteger( + R.integer.keyguard_max_notification_count); if (DEBUG) Log.v(TAG, "updateResources"); } @@ -4194,6 +4197,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } @Override + public void onLockedNotificationImportanceChange(OnDismissAction dismissAction) { + mLeaveOpenOnKeyguardHide = true; + dismissKeyguardThenExecute(dismissAction, true /* afterKeyguardGone */); + } + + @Override protected void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) { mLeaveOpenOnKeyguardHide = true; showBouncer(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index c883cc9284db..0ac2e7c4b8cd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -137,7 +137,8 @@ public class PhoneStatusBarPolicy implements Callback, RotationLockController.Ro filter.addAction(AudioManager.ACTION_HEADSET_PLUG); filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); filter.addAction(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED); - filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED); + filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); + filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); mContext.registerReceiver(mIntentReceiver, filter, null, mHandler); // listen for user / profile change. @@ -507,7 +508,8 @@ public class PhoneStatusBarPolicy implements Callback, RotationLockController.Ro updateSimState(intent); } else if (action.equals(TelecomManager.ACTION_CURRENT_TTY_MODE_CHANGED)) { updateTTY(intent); - } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED)) { + } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABLE) || + action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) { updateQuietState(); updateManagedProfile(); } else if (action.equals(AudioManager.ACTION_HEADSET_PLUG)) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java index f3aba4f81ce0..e8170fb5dc26 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QuickStatusBarHeader.java @@ -309,7 +309,7 @@ public class QuickStatusBarHeader extends BaseStatusBarHeader implements public void setupHost(final QSTileHost host) { mHost = host; - host.setHeaderView(this); + host.setHeaderView(mExpandIndicator); mHeaderQsPanel.setQSPanelAndHeader(mQsPanel, this); mHeaderQsPanel.setHost(host, null /* No customization in header */); setUserInfoController(host.getUserInfoController()); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java index b271380e496c..888e19c50f38 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java @@ -323,6 +323,11 @@ public class StatusBarWindowManager implements RemoteInputController.Callback { apply(mCurrentState); } + public void setBarHeight(int barHeight) { + mBarHeight = barHeight; + apply(mCurrentState); + } + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("StatusBarWindowManager state:"); pw.println(mCurrentState); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 6a2ecf4e6b0b..ebfa0183f8b3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -226,6 +226,10 @@ public class StatusBarWindowView extends FrameLayout { return false; } } + if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { + mStackScrollLayout.closeControlsIfOutsideTouch(ev); + } + return super.dispatchTouchEvent(ev); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index ab44b6a277ee..ea0bdf29c25c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -23,6 +23,7 @@ import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; @@ -52,6 +53,7 @@ import com.android.settingslib.RestrictedLockUtils; import com.android.systemui.BitmapHelper; import com.android.systemui.GuestResumeSessionReceiver; import com.android.systemui.R; +import com.android.systemui.SystemUISecondaryUserService; import com.android.systemui.qs.QSTile; import com.android.systemui.qs.tiles.UserDetailView; import com.android.systemui.statusbar.phone.ActivityStarter; @@ -101,6 +103,8 @@ public class UserSwitcherController { private boolean mSimpleUserSwitcher; private boolean mAddUsersWhenLocked; private boolean mPauseRefreshUsers; + private int mSecondaryUser = UserHandle.USER_NULL; + private Intent mSecondaryUserServiceIntent; private SparseBooleanArray mForcePictureLoadForUserId = new SparseBooleanArray(2); public UserSwitcherController(Context context, KeyguardMonitor keyguardMonitor, @@ -121,6 +125,8 @@ public class UserSwitcherController { mContext.registerReceiverAsUser(mReceiver, UserHandle.SYSTEM, filter, null /* permission */, null /* scheduler */); + mSecondaryUserServiceIntent = new Intent(context, SystemUISecondaryUserService.class); + filter = new IntentFilter(); filter.addAction(ACTION_REMOVE_GUEST); filter.addAction(ACTION_LOGOUT_USER); @@ -477,6 +483,20 @@ public class UserSwitcherController { } notifyAdapters(); + // Disconnect from the old secondary user's service + if (mSecondaryUser != UserHandle.USER_NULL) { + context.stopServiceAsUser(mSecondaryUserServiceIntent, + UserHandle.of(mSecondaryUser)); + mSecondaryUser = UserHandle.USER_NULL; + } + // Connect to the new secondary user's service (purely to ensure that a persistent + // SystemUI application is created for that user) + if (userInfo != null && !userInfo.isPrimary()) { + context.startServiceAsUser(mSecondaryUserServiceIntent, + UserHandle.of(userInfo.id)); + mSecondaryUser = userInfo.id; + } + if (UserManager.isSplitSystemUser() && userInfo != null && !userInfo.isGuest() && userInfo.id != UserHandle.USER_SYSTEM) { showLogoutNotification(currentId); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java index dc567fc20113..ee483e5a40e2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java @@ -592,7 +592,7 @@ public class NotificationChildrenContainer extends ViewGroup { public float getGroupExpandFraction() { int visibleChildrenExpandedHeight = getVisibleChildrenExpandHeight(); - int minExpandHeight = getMinExpandHeight(); + int minExpandHeight = getCollapsedHeight(); float factor = (mActualHeight - minExpandHeight) / (float) (visibleChildrenExpandedHeight - minExpandHeight); return Math.max(0.0f, Math.min(1.0f, factor)); @@ -618,11 +618,14 @@ public class NotificationChildrenContainer extends ViewGroup { } public int getMinHeight() { - return getIntrinsicHeight(NUMBER_OF_CHILDREN_WHEN_COLLAPSED); + return getMinHeight(NUMBER_OF_CHILDREN_WHEN_COLLAPSED); } - public int getMinExpandHeight() { - int maxAllowedVisibleChildren = getMaxAllowedVisibleChildren(true /* forceCollapsed */); + public int getCollapsedHeight() { + return getMinHeight(getMaxAllowedVisibleChildren(true /* forceCollapsed */)); + } + + private int getMinHeight(int maxAllowedVisibleChildren) { int minExpandHeight = mNotificationHeaderHeight; int visibleChildren = 0; boolean firstChild = true; @@ -637,7 +640,7 @@ public class NotificationChildrenContainer extends ViewGroup { firstChild = false; } ExpandableNotificationRow child = mChildren.get(i); - minExpandHeight += child.getMinHeight(); + minExpandHeight += child.getSingleLineView().getHeight(); visibleChildren++; } minExpandHeight += mCollapsedBottompadding; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index b5030e66e9c5..fa37e2257a61 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -60,6 +60,7 @@ import com.android.systemui.statusbar.DismissView; import com.android.systemui.statusbar.EmptyShadeView; import com.android.systemui.statusbar.ExpandableNotificationRow; import com.android.systemui.statusbar.ExpandableView; +import com.android.systemui.statusbar.NotificationGuts; import com.android.systemui.statusbar.NotificationOverflowContainer; import com.android.systemui.statusbar.NotificationSettingsIconRow; import com.android.systemui.statusbar.NotificationSettingsIconRow.SettingsIconRowListener; @@ -220,7 +221,6 @@ public class NotificationStackScrollLayout extends ViewGroup */ private int mMaxScrollAfterExpand; private SwipeHelper.LongPressListener mLongPressListener; - private GearDisplayedListener mGearDisplayedListener; private NotificationSettingsIconRow mCurrIconRow; private View mTranslatingParentView; @@ -374,8 +374,12 @@ public class NotificationStackScrollLayout extends ViewGroup } @Override - public void onSettingsIconRowReset(NotificationSettingsIconRow row) { - mSwipeHelper.setSnappedToGear(false); + public void onSettingsIconRowReset(ExpandableNotificationRow row) { + if (mTranslatingParentView != null && row == mTranslatingParentView) { + mSwipeHelper.setSnappedToGear(false); + mGearExposedView = null; + mTranslatingParentView = null; + } } @Override @@ -669,10 +673,6 @@ public class NotificationStackScrollLayout extends ViewGroup mLongPressListener = listener; } - public void setGearDisplayedListener(GearDisplayedListener listener) { - mGearDisplayedListener = listener; - } - public void setQsContainer(ViewGroup qsContainer) { mQsContainer = qsContainer; } @@ -737,17 +737,9 @@ public class NotificationStackScrollLayout extends ViewGroup // We start the swipe and snap back in the same frame, we don't want any animation mDragAnimPendingChildren.remove(animView); } - - if (mCurrIconRow != null) { - if (targetLeft == 0) { - mCurrIconRow.resetState(); - mCurrIconRow = null; - if (mGearExposedView != null && mGearExposedView == mTranslatingParentView) { - mGearExposedView = null; - } - } else { - mSwipeHelper.setSnappedToGear(true); - } + if (mCurrIconRow != null && targetLeft == 0) { + mCurrIconRow.resetState(); + mCurrIconRow = null; } } @@ -926,7 +918,7 @@ public class NotificationStackScrollLayout extends ViewGroup int positionInLinearLayout = getPositionInLinearLayout(v); int targetScroll = positionInLinearLayout + expandableView.getActualHeight() + - mBottomInset - getHeight() + getTopPadding(); + getImeInset() - getHeight() + getTopPadding(); if (mOwnScrollY < targetScroll) { mScroller.startScroll(mScrollX, mOwnScrollY, 0, targetScroll - mOwnScrollY); mDontReportNextOverScroll = true; @@ -936,8 +928,7 @@ public class NotificationStackScrollLayout extends ViewGroup @Override public WindowInsets onApplyWindowInsets(WindowInsets insets) { - mBottomInset = Math.max(0, insets.getSystemWindowInsetBottom() - - (getRootView().getHeight() - getHeight())); + mBottomInset = insets.getSystemWindowInsetBottom(); int range = getScrollRange(); if (mOwnScrollY > range) { @@ -995,7 +986,8 @@ public class NotificationStackScrollLayout extends ViewGroup } public void dismissViewAnimated(View child, Runnable endRunnable, int delay, long duration) { - mSwipeHelper.dismissChild(child, 0, endRunnable, delay, true, duration); + mSwipeHelper.dismissChild(child, 0, endRunnable, delay, true, duration, + true /* isDismissAll */); } public void snapViewIfNeeded(View child) { @@ -1506,23 +1498,17 @@ public class NotificationStackScrollLayout extends ViewGroup } private int getScrollRange() { - int scrollRange = 0; - ExpandableView firstChild = (ExpandableView) getFirstChildNotGone(); - if (firstChild != null) { - int contentHeight = getContentHeight(); - scrollRange = Math.max(0, contentHeight - mMaxLayoutHeight + mBottomStackPeekSize - + mBottomStackSlowDownHeight); - if (scrollRange > 0) { - int firstChildMaxExpandHeight = getMaxExpandHeight(firstChild); - // We want to at least be able collapse the first item and not ending in a weird - // end state. - scrollRange = Math.max(scrollRange, firstChildMaxExpandHeight - - firstChild.getMinHeight()); - } - } - int imeOverlap = Math.max(0, - getContentHeight() - (getHeight() - mBottomInset)); - return scrollRange + imeOverlap; + int contentHeight = getContentHeight(); + int scrollRange = Math.max(0, contentHeight - mMaxLayoutHeight + mBottomStackPeekSize + + mBottomStackSlowDownHeight); + int imeInset = getImeInset(); + scrollRange += Math.min(imeInset, Math.max(0, + getContentHeight() - (getHeight() - imeInset))); + return scrollRange; + } + + private int getImeInset() { + return Math.max(0, mBottomInset - (getRootView().getHeight() - getHeight())); } /** @@ -1947,7 +1933,7 @@ public class NotificationStackScrollLayout extends ViewGroup public int getPeekHeight() { final ExpandableView firstChild = getFirstChildNotGone(); - final int firstChildMinHeight = firstChild != null ? (int) firstChild.getMinHeight() + final int firstChildMinHeight = firstChild != null ? firstChild.getCollapsedHeight() : mCollapsedSize; return mIntrinsicPadding + firstChildMinHeight + mBottomStackPeekSize + mBottomStackSlowDownHeight; @@ -3209,9 +3195,6 @@ public class NotificationStackScrollLayout extends ViewGroup disableClipOptimization(); } handleDismissAllClipping(); - if (mCurrIconRow != null && mCurrIconRow.isVisible()) { - mCurrIconRow.getNotificationParent().animateTranslateNotification(0 /* left target */); - } } private void handleDismissAllClipping() { @@ -3470,16 +3453,11 @@ public class NotificationStackScrollLayout extends ViewGroup public void flingTopOverscroll(float velocity, boolean open); } - /** - * A listener that is notified when the gear is shown behind a notification. - */ - public interface GearDisplayedListener { - void onGearDisplayed(ExpandableNotificationRow row); - } - private class NotificationSwipeHelper extends SwipeHelper { - private static final long GEAR_SHOW_DELAY = 60; + private static final long SHOW_GEAR_DELAY = 60; + private static final long COVER_GEAR_DELAY = 4000; private CheckForDrag mCheckForDrag; + private Runnable mFalsingCheck; private Handler mHandler; private boolean mGearSnappedTo; private boolean mGearSnappedOnLeft; @@ -3487,6 +3465,12 @@ public class NotificationStackScrollLayout extends ViewGroup public NotificationSwipeHelper(int swipeDirection, Callback callback, Context context) { super(swipeDirection, callback, context); mHandler = new Handler(); + mFalsingCheck = new Runnable() { + @Override + public void run() { + resetExposedGearView(true /* animate */, true /* force */); + } + }; } @Override @@ -3501,9 +3485,10 @@ public class NotificationStackScrollLayout extends ViewGroup } mCheckForDrag = null; mCurrIconRow = null; + mHandler.removeCallbacks(mFalsingCheck); // Slide back any notifications that might be showing a gear - resetExposedGearView(); + resetExposedGearView(true /* animate */, false /* force */); if (currView instanceof ExpandableNotificationRow) { // Set the listener for the current row's gear @@ -3514,6 +3499,8 @@ public class NotificationStackScrollLayout extends ViewGroup @Override public void onMoveUpdate(View view, float translation, float delta) { + mHandler.removeCallbacks(mFalsingCheck); + if (mCurrIconRow != null) { mCurrIconRow.setSnapping(false); // If we're moving, we're not snapping. @@ -3532,7 +3519,8 @@ public class NotificationStackScrollLayout extends ViewGroup } else { // Check scheduled, reset alpha and update location; check will fade it in mCurrIconRow.setGearAlpha(0f); - mCurrIconRow.setIconLocation(translation > 0 /* onLeft */); + mCurrIconRow.setIconLocation(translation > 0 /* onLeft */, + false /* force */); } } } @@ -3547,10 +3535,10 @@ public class NotificationStackScrollLayout extends ViewGroup } @Override - public void dismissChild(final View view, float velocity) { - super.dismissChild(view, velocity); - cancelCheckForDrag(); - setSnappedToGear(false); + public void dismissChild(final View view, float velocity, + boolean useAccelerateInterpolator) { + super.dismissChild(view, velocity, useAccelerateInterpolator); + handleGearCoveredOrDismissed(); } @Override @@ -3558,11 +3546,17 @@ public class NotificationStackScrollLayout extends ViewGroup super.snapChild(animView, targetLeft, velocity); onDragCancelled(animView); if (targetLeft == 0) { - cancelCheckForDrag(); - setSnappedToGear(false); + handleGearCoveredOrDismissed(); } } + private void handleGearCoveredOrDismissed() { + cancelCheckForDrag(); + setSnappedToGear(false); + if (mGearExposedView != null && mGearExposedView == mTranslatingParentView) { + mGearExposedView = null; + } + } @Override public boolean handleUpEvent(MotionEvent ev, View animView, float velocity, @@ -3584,7 +3578,8 @@ public class NotificationStackScrollLayout extends ViewGroup snapChild(animView, 0 /* leftTarget */, velocity); } else if (isDismissGesture(ev)) { // Gesture is a dismiss that's not towards the gear - dismissChild(animView, swipedFastEnough() ? velocity : 0f); + dismissChild(animView, velocity, + !swipedFastEnough() /* useAccelerateInterpolator */); } else { // Didn't move enough to dismiss or cover, snap to the gear snapToGear(animView, velocity); @@ -3609,7 +3604,8 @@ public class NotificationStackScrollLayout extends ViewGroup private void dismissOrSnapBack(View animView, float velocity, MotionEvent ev) { if (isDismissGesture(ev)) { - dismissChild(animView, swipedFastEnough() ? velocity : 0f); + dismissChild(animView, velocity, + !swipedFastEnough() /* useAccelerateInterpolator */); } else { snapChild(animView, 0 /* leftTarget */, velocity); } @@ -3620,19 +3616,29 @@ public class NotificationStackScrollLayout extends ViewGroup final float target = mCurrIconRow.isIconOnLeft() ? snapBackThreshold : -snapBackThreshold; mGearExposedView = mTranslatingParentView; - if (mGearDisplayedListener != null - && (animView instanceof ExpandableNotificationRow)) { - mGearDisplayedListener.onGearDisplayed((ExpandableNotificationRow) animView); + if (animView instanceof ExpandableNotificationRow) { + MetricsLogger.action(mContext, MetricsEvent.ACTION_REVEAL_GEAR, + ((ExpandableNotificationRow) animView).getStatusBarNotification() + .getPackageName()); } if (mCurrIconRow != null) { mCurrIconRow.setSnapping(true); setSnappedToGear(true); } onDragCancelled(animView); + + // If we're on the lockscreen we want to false this. + if (mPhoneStatusBar.getBarState() == StatusBarState.KEYGUARD) { + mHandler.removeCallbacks(mFalsingCheck); + mHandler.postDelayed(mFalsingCheck, COVER_GEAR_DELAY); + } super.snapChild(animView, target, velocity); } private boolean swipedEnoughToShowGear(View animView) { + if (mTranslatingParentView == null) { + return false; + } final float snapBackThreshold = getSpaceForGear(animView); final float translation = getTranslation(animView); final boolean fromLeft = translation > 0; @@ -3648,10 +3654,7 @@ public class NotificationStackScrollLayout extends ViewGroup @Override public Animator getViewTranslationAnimator(View v, float target, AnimatorUpdateListener listener) { - if (mDismissAllInProgress) { - // When dismissing all, we translate the entire view instead. - return super.getViewTranslationAnimator(v, target, listener); - } else if (v instanceof ExpandableNotificationRow) { + if (v instanceof ExpandableNotificationRow) { return ((ExpandableNotificationRow) v).getTranslateViewAnimator(target, listener); } else { return super.getViewTranslationAnimator(v, target, listener); @@ -3660,21 +3663,42 @@ public class NotificationStackScrollLayout extends ViewGroup @Override public void setTranslation(View v, float translate) { - if (mDismissAllInProgress) { - // When dismissing all, we translate the entire view instead. - super.setTranslation(v, translate); - } else { - ((ExpandableView) v).setTranslation(translate); - } + ((ExpandableView) v).setTranslation(translate); } @Override public float getTranslation(View v) { - if (mDismissAllInProgress) { - // When dismissing all, we translate the entire view instead. - return super.getTranslation(v); - } else { - return ((ExpandableView) v).getTranslation(); + return ((ExpandableView) v).getTranslation(); + } + + public void closeControlsIfOutsideTouch(MotionEvent ev) { + NotificationGuts guts = mPhoneStatusBar.getExposedGuts(); + View view = null; + int height = 0; + if (guts != null) { + // Checking guts + view = guts; + height = guts.getActualHeight(); + } else if (mCurrIconRow != null && mCurrIconRow.isVisible() + && mTranslatingParentView != null) { + // Checking gear + view = mTranslatingParentView; + height = ((ExpandableView) mTranslatingParentView).getActualHeight(); + } + if (view != null) { + final int rx = (int) ev.getRawX(); + final int ry = (int) ev.getRawY(); + + getLocationOnScreen(mTempInt2); + int[] location = new int[2]; + view.getLocationOnScreen(location); + final int x = location[0] - mTempInt2[0]; + final int y = location[1] - mTempInt2[1]; + Rect rect = new Rect(x, y, x + view.getWidth(), y + height); + if (!rect.contains((int) rx, (int) ry)) { + // Touch was outside visible guts / gear notification, close what's visible + mPhoneStatusBar.dismissPopups(-1, -1, true /* resetGear */, true /* animate */); + } } } @@ -3711,7 +3735,7 @@ public class NotificationStackScrollLayout extends ViewGroup private void checkForDrag() { if (mCheckForDrag == null || !mHandler.hasCallbacks(mCheckForDrag)) { mCheckForDrag = new CheckForDrag(); - mHandler.postDelayed(mCheckForDrag, GEAR_SHOW_DELAY); + mHandler.postDelayed(mCheckForDrag, SHOW_GEAR_DELAY); } } @@ -3725,6 +3749,9 @@ public class NotificationStackScrollLayout extends ViewGroup private final class CheckForDrag implements Runnable { @Override public void run() { + if (mTranslatingParentView == null) { + return; + } final float translation = getTranslation(mTranslatingParentView); final float absTransX = Math.abs(translation); final float bounceBackToGearWidth = getSpaceForGear(mTranslatingParentView); @@ -3740,20 +3767,24 @@ public class NotificationStackScrollLayout extends ViewGroup } } - private void resetExposedGearView() { - if (mGearExposedView == null || mGearExposedView == mTranslatingParentView) { + public void resetExposedGearView(boolean animate, boolean force) { + if (mGearExposedView == null + || (!force && mGearExposedView == mTranslatingParentView)) { // If no gear is showing or it's showing for this view we do nothing. return; } - final View prevGearExposedView = mGearExposedView; + if (animate) { + Animator anim = getViewTranslationAnimator(prevGearExposedView, + 0 /* leftTarget */, null /* updateListener */); + if (anim != null) { + anim.start(); + } + } else if (mGearExposedView instanceof ExpandableNotificationRow) { + ((ExpandableNotificationRow) mGearExposedView).resetTranslation(); + } mGearExposedView = null; mGearSnappedTo = false; - Animator anim = getViewTranslationAnimator(prevGearExposedView, - 0 /* leftTarget */, null /* updateListener */); - if (anim != null) { - anim.start(); - } } } @@ -3769,6 +3800,14 @@ public class NotificationStackScrollLayout extends ViewGroup } } + public void resetExposedGearView(boolean animate, boolean force) { + mSwipeHelper.resetExposedGearView(animate, force); + } + + public void closeControlsIfOutsideTouch(MotionEvent ev) { + mSwipeHelper.closeControlsIfOutsideTouch(ev); + } + static class AnimationEvent { static AnimationFilter[] FILTERS = new AnimationFilter[] { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java index 4c94fe93cbdc..c7333c2721b4 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java @@ -368,7 +368,7 @@ public class StackScrollAlgorithm { childViewState.location = StackViewState.LOCATION_UNKNOWN; paddingAfterChild = getPaddingAfterChild(algorithmState, child); int childHeight = getMaxAllowedChildHeight(child); - int minHeight = child.getMinHeight(); + int collapsedHeight = child.getCollapsedHeight(); childViewState.yTranslation = currentYPosition; if (i == 0) { updateFirstChildHeight(child, childViewState, childHeight, ambientState); @@ -384,7 +384,7 @@ public class StackScrollAlgorithm { // According to the regular scroll view we are fully translated out of the // bottom of the screen so we are fully in the bottom stack updateStateForChildFullyInBottomStack(algorithmState, - bottomStackStart, childViewState, minHeight, ambientState, child); + bottomStackStart, childViewState, collapsedHeight, ambientState, child); } else { // According to the regular scroll view we are currently translating out of / // into the bottom of the screen @@ -475,17 +475,17 @@ public class StackScrollAlgorithm { float newTranslation = Math.max(ambientState.getTopPadding() + ambientState.getStackTranslation(), childState.yTranslation); childState.height = (int) Math.max(childState.height - (newTranslation - - childState.yTranslation), row.getMinHeight()); + - childState.yTranslation), row.getCollapsedHeight()); childState.yTranslation = newTranslation; } private void clampHunToMaxTranslation(AmbientState ambientState, ExpandableNotificationRow row, StackViewState childState) { float newTranslation; - float bottomPosition = ambientState.getMaxHeadsUpTranslation() - row.getMinHeight(); + float bottomPosition = ambientState.getMaxHeadsUpTranslation() - row.getCollapsedHeight(); newTranslation = Math.min(childState.yTranslation, bottomPosition); childState.height = (int) Math.max(childState.height - - (childState.yTranslation - newTranslation), row.getMinHeight()); + - (childState.yTranslation - newTranslation), row.getCollapsedHeight()); childState.yTranslation = newTranslation; } @@ -534,10 +534,10 @@ public class StackScrollAlgorithm { float offset = mBottomStackIndentationFunctor.getValue(algorithmState.partialInBottom); algorithmState.itemsInBottomStack += algorithmState.partialInBottom; int newHeight = childHeight; - if (childHeight > child.getMinHeight()) { + if (childHeight > child.getCollapsedHeight()) { newHeight = (int) Math.max(Math.min(transitioningPositionStart + offset - getPaddingAfterChild(algorithmState, child) - currentYPosition, childHeight), - child.getMinHeight()); + child.getCollapsedHeight()); childViewState.height = newHeight; } childViewState.yTranslation = transitioningPositionStart + offset - newHeight @@ -547,7 +547,7 @@ public class StackScrollAlgorithm { private void updateStateForChildFullyInBottomStack(StackScrollAlgorithmState algorithmState, float transitioningPositionStart, StackViewState childViewState, - int minHeight, AmbientState ambientState, ExpandableView child) { + int collapsedHeight, AmbientState ambientState, ExpandableView child) { float currentYPosition; algorithmState.itemsInBottomStack += 1.0f; if (algorithmState.itemsInBottomStack < MAX_ITEMS_IN_BOTTOM_STACK) { @@ -568,16 +568,14 @@ public class StackScrollAlgorithm { childViewState.location = StackViewState.LOCATION_BOTTOM_STACK_HIDDEN; currentYPosition = ambientState.getInnerHeight(); } - childViewState.height = minHeight; - childViewState.yTranslation = currentYPosition - minHeight; + childViewState.height = collapsedHeight; + childViewState.yTranslation = currentYPosition - collapsedHeight; } /** * Update the height of the first child i.e clamp it to the bottom stack * - * - * @param child the child to update * @param childViewState the viewstate of the child * @param childHeight the height of the child @@ -591,7 +589,7 @@ public class StackScrollAlgorithm { mBottomStackSlowDownLength + ambientState.getScrollY(); // Collapse and expand the first child while the shade is being expanded childViewState.height = (int) Math.max(Math.min(bottomPeekStart, (float) childHeight), - child.getMinHeight()); + child.getCollapsedHeight()); } /** diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java index b5c1f5739e65..fe5409041d12 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java @@ -265,11 +265,7 @@ public class PipManager { */ private void showPipOverlay() { if (DEBUG) Log.d(TAG, "showPipOverlay()"); - Intent intent = new Intent(mContext, PipOverlayActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - final ActivityOptions options = ActivityOptions.makeBasic(); - options.setLaunchStackId(PINNED_STACK_ID); - mContext.startActivity(intent, options.toBundle()); + PipOverlayActivity.showPipOverlay(mContext); } /** @@ -635,7 +631,7 @@ public class PipManager { void onPipActivityClosed(); /** Invoked when the PIP menu gets shown. */ void onShowPipMenu(); - /** Invoked when the PIPed activity is returned back to the fullscreen. */ + /** Invoked when the PIPed activity is about to return back to the fullscreen. */ void onMoveToFullscreen(); /** Invoked when we are above to start resizing the Pip. */ void onPipResizeAboutToStart(); diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java index c54e73a7cda6..854e09d9d1a6 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipMenuActivity.java @@ -30,6 +30,7 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { private final PipManager mPipManager = PipManager.getInstance(); private PipControlsView mPipControlsView; + private boolean mRestorePipSizeWhenClose; @Override protected void onCreate(Bundle bundle) { @@ -38,12 +39,21 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { mPipManager.addListener(this); mPipControlsView = (PipControlsView) findViewById(R.id.pip_controls); + mRestorePipSizeWhenClose = true; + } + + private void restorePipAndFinish() { + if (mRestorePipSizeWhenClose) { + // When PIP menu activity is closed, restore to the default position. + mPipManager.resizePinnedStack(PipManager.STATE_PIP_OVERLAY); + } + finish(); } @Override public void onPause() { super.onPause(); - finish(); + restorePipAndFinish(); } @Override @@ -55,6 +65,11 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { } @Override + public void onBackPressed() { + restorePipAndFinish(); + } + + @Override public void onPipEntered() { } @Override @@ -67,6 +82,9 @@ public class PipMenuActivity extends Activity implements PipManager.Listener { @Override public void onMoveToFullscreen() { + // Moving PIP to fullscreen is implemented by resizing PINNED_STACK with null bounds. + // This conflicts with restoring PIP position, so disable it. + mRestorePipSizeWhenClose = false; finish(); } diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java index 5472ad6718dd..e205ff5749b0 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipOverlayActivity.java @@ -35,6 +35,14 @@ import static android.app.ActivityManager.StackId.PINNED_STACK_ID; public class PipOverlayActivity extends Activity implements PipManager.Listener { private static final long SHOW_GUIDE_OVERLAY_VIEW_DURATION_MS = 4000; + /** + * A flag to ensure the single instance of PipOverlayActivity to prevent it from restarting. + * Note that {@link PipManager} moves the PIPed activity to fullscreen if the activity is + * restarted. It's because the activity may be started by the Launcher or an intent again, + * but we don't want do so for the PipOverlayActivity. + */ + private static boolean sActivityCreated; + private final PipManager mPipManager = PipManager.getInstance(); private final Handler mHandler = new Handler(); private View mGuideOverlayView; @@ -46,9 +54,23 @@ public class PipOverlayActivity extends Activity implements PipManager.Listener } }; + /** + * Shows PIP overlay UI only if it's not there. + */ + static void showPipOverlay(Context context) { + if (!sActivityCreated) { + Intent intent = new Intent(context, PipOverlayActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + final ActivityOptions options = ActivityOptions.makeBasic(); + options.setLaunchStackId(PINNED_STACK_ID); + context.startActivity(intent, options.toBundle()); + } + } + @Override protected void onCreate(Bundle bundle) { super.onCreate(bundle); + sActivityCreated = true; setContentView(R.layout.tv_pip_overlay); mGuideOverlayView = findViewById(R.id.guide_overlay); mPipManager.addListener(this); @@ -71,6 +93,7 @@ public class PipOverlayActivity extends Activity implements PipManager.Listener @Override protected void onDestroy() { super.onDestroy(); + sActivityCreated = false; mHandler.removeCallbacksAndMessages(null); mPipManager.removeListener(this); mPipManager.resumePipResizing( diff --git a/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java index b90b7279a5b5..47cd8e5a9b44 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipRecentsOverlayManager.java @@ -131,9 +131,9 @@ public class PipRecentsOverlayManager { * Called when the PIP view in {@link com.android.systemui.recents.tv.RecentsTvActivity} * is focused. * This should be called only by {@link com.android.systemui.recents.tv.RecentsTvActivity}. - * @param hasRecentsFocusable {@code true} if Recents can have focus. (i.e. Has a recent task) + * @param allowRecentsFocusable {@code true} if Recents can have focus. (i.e. Has a recent task) */ - public void requestFocus(boolean hasRecentsFocusable) { + public void requestFocus(boolean allowRecentsFocusable) { if (!mIsRecentsShown || mIsPipFocusedInRecent) { return; } @@ -143,7 +143,7 @@ public class PipRecentsOverlayManager { mWindowManager.updateViewLayout(mOverlayView, mPipRecentsControlsViewFocusedLayoutParams); mPipControlsView.requestFocus(); mPipControlsView.startFocusGainAnimation(); - mRecentsView.setVisibility(hasRecentsFocusable ? View.VISIBLE : View.GONE); + mRecentsView.setVisibility(allowRecentsFocusable ? View.VISIBLE : View.GONE); } /** diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java index 6a8165942cc0..a30f50775f77 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileLifecycleManagerTests.java @@ -198,7 +198,7 @@ public class TileLifecycleManagerTests extends AndroidTestCase { } private void waitForCallback(String callback) { - for (int i = 0; i < 25; i++) { + for (int i = 0; i < 50; i++) { if (mCallbacks.contains(callback)) { mCallbacks.remove(callback); return; @@ -229,7 +229,7 @@ public class TileLifecycleManagerTests extends AndroidTestCase { } }); try { - lock.wait(5000); + lock.wait(10000); } catch (InterruptedException e) { } } diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java index 9beaba301072..2650e5a868d2 100644 --- a/rs/java/android/renderscript/RenderScript.java +++ b/rs/java/android/renderscript/RenderScript.java @@ -1031,7 +1031,6 @@ public class RenderScript { - long mDev; long mContext; private boolean mDestroyed = false; @@ -1426,8 +1425,8 @@ public class RenderScript { RenderScript rs = new RenderScript(ctx); - rs.mDev = rs.nDeviceCreate(); - rs.mContext = rs.nContextCreate(rs.mDev, flags, sdkVersion, ct.mID); + long device = rs.nDeviceCreate(); + rs.mContext = rs.nContextCreate(device, flags, sdkVersion, ct.mID); rs.mContextType = ct; rs.mContextFlags = flags; rs.mContextSdkVersion = sdkVersion; @@ -1635,9 +1634,6 @@ public class RenderScript { } nContextDestroy(); - - nDeviceDestroy(mDev); - mDev = 0; } } diff --git a/rs/java/android/renderscript/RenderScriptGL.java b/rs/java/android/renderscript/RenderScriptGL.java index 6178994cfbe3..be1f899bd08b 100644 --- a/rs/java/android/renderscript/RenderScriptGL.java +++ b/rs/java/android/renderscript/RenderScriptGL.java @@ -177,9 +177,9 @@ public class RenderScriptGL extends RenderScript { mWidth = 0; mHeight = 0; - mDev = nDeviceCreate(); + long device = nDeviceCreate(); int dpi = ctx.getResources().getDisplayMetrics().densityDpi; - mContext = nContextCreateGL(mDev, 0, sdkVersion, + mContext = nContextCreateGL(device, 0, sdkVersion, mSurfaceConfig.mColorMin, mSurfaceConfig.mColorPref, mSurfaceConfig.mAlphaMin, mSurfaceConfig.mAlphaPref, mSurfaceConfig.mDepthMin, mSurfaceConfig.mDepthPref, diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index 4b96e7a31ccf..27417332f7d1 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -1262,7 +1262,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { Service service = componentNameToServiceMap.get(componentName); // Ignore non-encryption-aware services until user is unlocked - if (!isUnlocked && !installedService.isEncryptionAware()) { + if (!isUnlocked && !installedService.isDirectBootAware()) { Slog.d(LOG_TAG, "Ignoring non-encryption-aware service " + componentName); continue; } @@ -1784,10 +1784,15 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { userState.mEnabledServices.contains(userState.mServiceChangingSoftKeyboardMode); if (!serviceChangingSoftKeyboardModeIsEnabled) { - Settings.Secure.putIntForUser(mContext.getContentResolver(), - Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, - 0, - userState.mUserId); + final long identity = Binder.clearCallingIdentity(); + try { + Settings.Secure.putIntForUser(mContext.getContentResolver(), + Settings.Secure.ACCESSIBILITY_SOFT_KEYBOARD_MODE, + 0, + userState.mUserId); + } finally { + Binder.restoreCallingIdentity(identity); + } userState.mSoftKeyboardShowMode = 0; userState.mServiceChangingSoftKeyboardMode = null; } @@ -2146,7 +2151,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { MagnificationController getMagnificationController() { synchronized (mLock) { if (mMagnificationController == null) { - mMagnificationController = new MagnificationController(mContext, this); + mMagnificationController = new MagnificationController(mContext, this, mLock); mMagnificationController.register(); mMagnificationController.setUserId(mCurrentUserId); } @@ -3491,6 +3496,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { reportedWindow.setLayer(window.layer); reportedWindow.setFocused(window.focused); reportedWindow.setBoundsInScreen(window.boundsInScreen); + reportedWindow.setTitle(window.title); + reportedWindow.setAnchorId(window.accessibilityIdOfAnchor); final int parentId = findWindowIdLocked(window.parentToken); if (parentId >= 0) { diff --git a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java index e15b785ba718..b2196bf946e2 100644 --- a/services/accessibility/java/com/android/server/accessibility/MagnificationController.java +++ b/services/accessibility/java/com/android/server/accessibility/MagnificationController.java @@ -72,7 +72,7 @@ class MagnificationController { */ private static final float MIN_PERSISTED_SCALE = 2.0f; - private final Object mLock = new Object(); + private final Object mLock; /** * The current magnification spec. If an animation is running, this @@ -97,12 +97,13 @@ class MagnificationController { private int mUserId; - public MagnificationController(Context context, AccessibilityManagerService ams) { + public MagnificationController(Context context, AccessibilityManagerService ams, Object lock) { mAms = ams; mContentResolver = context.getContentResolver(); mScreenStateObserver = new ScreenStateObserver(context, this); mWindowStateObserver = new WindowStateObserver(context, this); mSpecAnimationBridge = new SpecAnimationBridge(context); + mLock = lock; } /** diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java index 89b145e2f4c0..f93fb1b0f975 100644 --- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java +++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java @@ -164,7 +164,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku onUserStopped(userId); } else if (Intent.ACTION_USER_SWITCHED.equals(action)) { reloadWidgetsMaskedStateForGroup(userId); - } else if (Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED.equals(action)) { + } else if (Intent.ACTION_MANAGED_PROFILE_AVAILABLE.equals(action) + || Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE.equals(action)) { synchronized (mLock) { reloadWidgetsMaskedState(userId); } @@ -288,7 +289,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku userFilter, null, null); IntentFilter offModeFilter = new IntentFilter(); - offModeFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED); + offModeFilter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); + offModeFilter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); mContext.registerReceiverAsUser(mBroadcastReceiver, UserHandle.ALL, offModeFilter, null, null); @@ -594,27 +596,28 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } final boolean showBadge; final Intent onClickIntent; - if (provider.maskedBySuspendedPackage) { - final long identity = Binder.clearCallingIdentity(); - try { + final long identity = Binder.clearCallingIdentity(); + try { + if (provider.maskedBySuspendedPackage) { UserInfo userInfo = mUserManager.getUserInfo(providerUserId); showBadge = userInfo.isManagedProfile(); onClickIntent = mDevicePolicyManagerInternal.createPackageSuspendedDialogIntent( providerPackage, providerUserId); - } finally { - Binder.restoreCallingIdentity(identity); - } - } else if (provider.maskedByQuietProfile) { - showBadge = true; - onClickIntent = UnlaunchableAppActivity.createInQuietModeDialogIntent( - providerUserId); - } else /* provider.maskedByLockedProfile */ { - showBadge = true; - onClickIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null, - providerUserId); - if (onClickIntent != null) { - onClickIntent.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + } else if (provider.maskedByQuietProfile) { + showBadge = true; + onClickIntent = UnlaunchableAppActivity.createInQuietModeDialogIntent( + providerUserId); + } else /* provider.maskedByLockedProfile */ { + showBadge = true; + onClickIntent = mKeyguardManager.createConfirmDeviceCredentialIntent(null, null, + providerUserId); + if (onClickIntent != null) { + onClickIntent.setFlags(FLAG_ACTIVITY_NEW_TASK + | FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + } } + } finally { + Binder.restoreCallingIdentity(identity); } for (int j = 0; j < widgetCount; j++) { @@ -742,8 +745,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } @Override - public int[] startListening(IAppWidgetHost callbacks, String callingPackage, - int hostId, List<RemoteViews> updatedViews) { + public ParceledListSlice<RemoteViews> startListening(IAppWidgetHost callbacks, + String callingPackage, int hostId, int[] appWidgetIds, int[] updatedIds) { final int userId = UserHandle.getCallingUserId(); if (DEBUG) { @@ -760,21 +763,21 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku // sure the caller can only access hosts it owns. HostId id = new HostId(Binder.getCallingUid(), hostId, callingPackage); Host host = lookupOrAddHostLocked(id); - host.callbacks = callbacks; - updatedViews.clear(); - - ArrayList<Widget> instances = host.widgets; - int N = instances.size(); - int[] updatedIds = new int[N]; + int N = appWidgetIds.length; + ArrayList<RemoteViews> outViews = new ArrayList<>(N); + RemoteViews rv; + int added = 0; for (int i = 0; i < N; i++) { - Widget widget = instances.get(i); - updatedIds[i] = widget.appWidgetId; - updatedViews.add(cloneIfLocalBinder(widget.getEffectiveViewsLocked())); + rv = host.getPendingViewsForId(appWidgetIds[i]); + if (rv != null) { + updatedIds[added] = appWidgetIds[i]; + outViews.add(rv); + added++; + } } - - return updatedIds; + return new ParceledListSlice<>(outViews); } } @@ -1882,6 +1885,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } private void scheduleNotifyUpdateAppWidgetLocked(Widget widget, RemoteViews updateViews) { + long requestTime = SystemClock.uptimeMillis(); + if (widget != null) { + widget.lastUpdateTime = requestTime; + } if (widget == null || widget.provider == null || widget.provider.zombie || widget.host.callbacks == null || widget.host.zombie) { return; @@ -1891,6 +1898,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku args.arg1 = widget.host; args.arg2 = widget.host.callbacks; args.arg3 = updateViews; + args.arg4 = requestTime; args.argi1 = widget.appWidgetId; mCallbackHandler.obtainMessage( @@ -1899,9 +1907,10 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku } private void handleNotifyUpdateAppWidget(Host host, IAppWidgetHost callbacks, - int appWidgetId, RemoteViews views) { + int appWidgetId, RemoteViews views, long requestTime) { try { callbacks.updateAppWidget(appWidgetId, views); + host.lastWidgetUpdateTime = requestTime; } catch (RemoteException re) { synchronized (mLock) { Slog.e(TAG, "Widget host dead: " + host.id, re); @@ -3398,10 +3407,11 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku Host host = (Host) args.arg1; IAppWidgetHost callbacks = (IAppWidgetHost) args.arg2; RemoteViews views = (RemoteViews) args.arg3; + long requestTime = (Long) args.arg4; final int appWidgetId = args.argi1; args.recycle(); - handleNotifyUpdateAppWidget(host, callbacks, appWidgetId, views); + handleNotifyUpdateAppWidget(host, callbacks, appWidgetId, views, requestTime); } break; case MSG_NOTIFY_PROVIDER_CHANGED: { @@ -3769,6 +3779,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku boolean zombie; // if we're in safe mode, don't prune this just because nobody references it int tag = TAG_UNDEFINED; // for use while saving state (the index) + long lastWidgetUpdateTime; // last time we were successfully able to send an update. public int getUserId() { return UserHandle.getUserId(id.uid); @@ -3790,6 +3801,23 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku return false; } + /** + * Returns the RemoveViews for the provided widget id if an update is pending + * for that widget. + */ + public RemoteViews getPendingViewsForId(int appWidgetId) { + long updateTime = lastWidgetUpdateTime; + int N = widgets.size(); + for (int i = 0; i < N; i++) { + Widget widget = widgets.get(i); + if (widget.appWidgetId == appWidgetId + && widget.lastUpdateTime > updateTime) { + return cloneIfLocalBinder(widget.getEffectiveViewsLocked()); + } + } + return null; + } + @Override public String toString() { return "Host{" + id + (zombie ? " Z" : "") + '}'; @@ -3860,6 +3888,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku RemoteViews maskedViews; Bundle options; Host host; + long lastUpdateTime; @Override public String toString() { diff --git a/services/core/java/com/android/server/AnyMotionDetector.java b/services/core/java/com/android/server/AnyMotionDetector.java index a0b5c154c13f..e98b4aa6e267 100644 --- a/services/core/java/com/android/server/AnyMotionDetector.java +++ b/services/core/java/com/android/server/AnyMotionDetector.java @@ -108,63 +108,71 @@ public class AnyMotionDetector { public AnyMotionDetector(PowerManager pm, Handler handler, SensorManager sm, DeviceIdleCallback callback, float thresholdAngle) { if (DEBUG) Slog.d(TAG, "AnyMotionDetector instantiated."); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); - mWakeLock.setReferenceCounted(false); - mHandler = handler; - mSensorManager = sm; - mAccelSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); - mMeasurementInProgress = false; - mState = STATE_INACTIVE; - mCallback = callback; - mThresholdAngle = thresholdAngle; - mRunningStats = new RunningSignalStats(); - mNumSufficientSamples = (int) Math.ceil( - ((double)ORIENTATION_MEASUREMENT_DURATION_MILLIS / SAMPLING_INTERVAL_MILLIS)); - if (DEBUG) Slog.d(TAG, "mNumSufficientSamples = " + mNumSufficientSamples); + synchronized (mLock) { + mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); + mWakeLock.setReferenceCounted(false); + mHandler = handler; + mSensorManager = sm; + mAccelSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + mMeasurementInProgress = false; + mState = STATE_INACTIVE; + mCallback = callback; + mThresholdAngle = thresholdAngle; + mRunningStats = new RunningSignalStats(); + mNumSufficientSamples = (int) Math.ceil( + ((double)ORIENTATION_MEASUREMENT_DURATION_MILLIS / SAMPLING_INTERVAL_MILLIS)); + if (DEBUG) Slog.d(TAG, "mNumSufficientSamples = " + mNumSufficientSamples); + } } /* * Acquire accel data until we determine AnyMotion status. */ public void checkForAnyMotion() { - if (DEBUG) Slog.d(TAG, "checkForAnyMotion(). mState = " + mState); + if (DEBUG) { + Slog.d(TAG, "checkForAnyMotion(). mState = " + mState); + } if (mState != STATE_ACTIVE) { - mState = STATE_ACTIVE; - if (DEBUG) Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_ACTIVE."); - mCurrentGravityVector = null; - mPreviousGravityVector = null; - startOrientationMeasurement(); + synchronized (mLock) { + mState = STATE_ACTIVE; + if (DEBUG) { + Slog.d(TAG, "Moved from STATE_INACTIVE to STATE_ACTIVE."); + } + mCurrentGravityVector = null; + mPreviousGravityVector = null; + mWakeLock.acquire(); + startOrientationMeasurementLocked(); + } } } public void stop() { if (mState == STATE_ACTIVE) { - mState = STATE_INACTIVE; - if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE."); - if (mMeasurementInProgress) { - mMeasurementInProgress = false; - mSensorManager.unregisterListener(mListener); + synchronized (mLock) { + mState = STATE_INACTIVE; + if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE."); + if (mMeasurementInProgress) { + mMeasurementInProgress = false; + mSensorManager.unregisterListener(mListener); + } + mHandler.removeCallbacks(mMeasurementTimeout); + mHandler.removeCallbacks(mSensorRestart); + mCurrentGravityVector = null; + mPreviousGravityVector = null; + mWakeLock.release(); } - mHandler.removeCallbacks(mMeasurementTimeout); - mHandler.removeCallbacks(mSensorRestart); - mWakeLock.release(); - mCurrentGravityVector = null; - mPreviousGravityVector = null; } } - private void startOrientationMeasurement() { - if (DEBUG) Slog.d(TAG, "startOrientationMeasurement: mMeasurementInProgress=" + + private void startOrientationMeasurementLocked() { + if (DEBUG) Slog.d(TAG, "startOrientationMeasurementLocked: mMeasurementInProgress=" + mMeasurementInProgress + ", (mAccelSensor != null)=" + (mAccelSensor != null)); - if (!mMeasurementInProgress && mAccelSensor != null) { if (mSensorManager.registerListener(mListener, mAccelSensor, SAMPLING_INTERVAL_MILLIS * 1000)) { - mWakeLock.acquire(); mMeasurementInProgress = true; mRunningStats.reset(); } - Message msg = Message.obtain(mHandler, mMeasurementTimeout); msg.setAsynchronous(true); mHandler.sendMessageDelayed(msg, ACCELEROMETER_DATA_TIMEOUT_MILLIS); @@ -178,7 +186,6 @@ public class AnyMotionDetector { if (mMeasurementInProgress) { mSensorManager.unregisterListener(mListener); mHandler.removeCallbacks(mMeasurementTimeout); - mWakeLock.release(); long detectionEndTime = SystemClock.elapsedRealtime(); mMeasurementInProgress = false; mPreviousGravityVector = mCurrentGravityVector; @@ -196,8 +203,10 @@ public class AnyMotionDetector { status = getStationaryStatus(); if (DEBUG) Slog.d(TAG, "getStationaryStatus() returned " + status); if (status != RESULT_UNKNOWN) { - if (DEBUG) Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE. status = " + - status); + mWakeLock.release(); + if (DEBUG) { + Slog.d(TAG, "Moved from STATE_ACTIVE to STATE_INACTIVE. status = " + status); + } mState = STATE_INACTIVE; } else { /* @@ -275,7 +284,7 @@ public class AnyMotionDetector { @Override public void run() { synchronized (mLock) { - startOrientationMeasurement(); + startOrientationMeasurementLocked(); } } }; @@ -442,4 +451,4 @@ public class AnyMotionDetector { return msg; } } -}
\ No newline at end of file +} diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index c38a89e30807..0a2153e9f31b 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -979,6 +979,7 @@ public class AppOpsService extends IAppOpsService.Stub { usageRestrictions.put(usage, r); } } + notifyWatchersOfChange(code); } @Override @@ -1046,7 +1047,9 @@ public class AppOpsService extends IAppOpsService.Stub { op.duration = 0; final int switchCode = AppOpsManager.opToSwitch(code); UidState uidState = ops.uidState; - if (uidState.opModes != null) { + // If there is a non-default per UID policy (we set UID op mode only if + // non-default) it takes over, otherwise use the per package policy. + if (uidState.opModes != null && uidState.opModes.indexOfKey(switchCode) >= 0) { final int uidMode = uidState.opModes.get(switchCode); if (uidMode != AppOpsManager.MODE_ALLOWED) { if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code " @@ -1055,13 +1058,15 @@ public class AppOpsService extends IAppOpsService.Stub { op.rejectTime = System.currentTimeMillis(); return uidMode; } - } - final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; - if (switchOp.mode != AppOpsManager.MODE_ALLOWED) { - if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code " - + switchCode + " (" + code + ") uid " + uid + " package " + packageName); - op.rejectTime = System.currentTimeMillis(); - return switchOp.mode; + } else { + final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op; + if (switchOp.mode != AppOpsManager.MODE_ALLOWED) { + if (DEBUG) Log.d(TAG, "noteOperation: reject #" + op.mode + " for code " + + switchCode + " (" + code + ") uid " + uid + " package " + + packageName); + op.rejectTime = System.currentTimeMillis(); + return switchOp.mode; + } } if (DEBUG) Log.d(TAG, "noteOperation: allowing code " + code + " uid " + uid + " package " + packageName); @@ -2280,6 +2285,10 @@ public class AppOpsService extends IAppOpsService.Stub { pruneUserRestrictionsForToken(token, userHandle); } + notifyWatchersOfChange(code); + } + + private void notifyWatchersOfChange(int code) { final ArrayList<Callback> clonedCallbacks; synchronized (this) { ArrayList<Callback> callbacks = mOpModeWatchers.get(code); diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 95d3cc3bbcf0..82a36b4958a6 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -371,8 +371,6 @@ public class ConnectivityService extends IConnectivityManager.Stub private int mNetTransitionWakeLockTimeout; private final PowerManager.WakeLock mPendingIntentWakeLock; - private InetAddress mDefaultDns; - // used in DBG mode to track inet condition reports private static final int INET_CONDITION_LOG_MAX_SIZE = 15; private ArrayList mInetLog; @@ -645,19 +643,6 @@ public class ConnectivityService extends IConnectivityManager.Stub } } - // read our default dns server ip - String dns = Settings.Global.getString(context.getContentResolver(), - Settings.Global.DEFAULT_DNS_SERVER); - if (dns == null || dns.length() == 0) { - dns = context.getResources().getString( - com.android.internal.R.string.config_default_dns_server); - } - try { - mDefaultDns = NetworkUtils.numericToInetAddress(dns); - } catch (IllegalArgumentException e) { - loge("Error setting defaultDns using " + dns); - } - mReleasePendingIntentDelayMs = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.CONNECTIVITY_RELEASE_PENDING_INTENT_DELAY_MS, 5_000); @@ -4149,14 +4134,8 @@ public class ConnectivityService extends IConnectivityManager.Stub // } updateTcpBufferSizes(networkAgent); - // TODO: deprecate and remove mDefaultDns when we can do so safely. See http://b/18327075 - // In L, we used it only when the network had Internet access but provided no DNS servers. - // For now, just disable it, and if disabling it doesn't break things, remove it. - // final boolean useDefaultDns = networkAgent.networkCapabilities.hasCapability( - // NET_CAPABILITY_INTERNET); - final boolean useDefaultDns = false; - final boolean flushDns = updateRoutes(newLp, oldLp, netId); - updateDnses(newLp, oldLp, netId, flushDns, useDefaultDns); + updateRoutes(newLp, oldLp, netId); + updateDnses(newLp, oldLp, netId); updateClat(newLp, oldLp, networkAgent); if (isDefaultNetwork(networkAgent)) { @@ -4259,37 +4238,24 @@ public class ConnectivityService extends IConnectivityManager.Stub return !routeDiff.added.isEmpty() || !routeDiff.removed.isEmpty(); } - private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId, - boolean flush, boolean useDefaultDns) { - if (oldLp == null || (newLp.isIdenticalDnses(oldLp) == false)) { - Collection<InetAddress> dnses = newLp.getDnsServers(); - if (dnses.size() == 0 && mDefaultDns != null && useDefaultDns) { - dnses = new ArrayList(); - dnses.add(mDefaultDns); - if (DBG) { - loge("no dns provided for netId " + netId + ", so using defaults"); - } - } - if (DBG) log("Setting Dns servers for network " + netId + " to " + dnses); - try { - mNetd.setDnsServersForNetwork(netId, NetworkUtils.makeStrings(dnses), - newLp.getDomains()); - } catch (Exception e) { - loge("Exception in setDnsServersForNetwork: " + e); - } - final NetworkAgentInfo defaultNai = getDefaultNetwork(); - if (defaultNai != null && defaultNai.network.netId == netId) { - setDefaultDnsSystemProperties(dnses); - } - flushVmDnsCache(); - } else if (flush) { - try { - mNetd.flushNetworkDnsCache(netId); - } catch (Exception e) { - loge("Exception in flushNetworkDnsCache: " + e); - } - flushVmDnsCache(); + private void updateDnses(LinkProperties newLp, LinkProperties oldLp, int netId) { + if (oldLp != null && newLp.isIdenticalDnses(oldLp)) { + return; // no updating necessary + } + + Collection<InetAddress> dnses = newLp.getDnsServers(); + if (DBG) log("Setting Dns servers for network " + netId + " to " + dnses); + try { + mNetd.setDnsServersForNetwork( + netId, NetworkUtils.makeStrings(dnses), newLp.getDomains()); + } catch (Exception e) { + loge("Exception in setDnsServersForNetwork: " + e); + } + final NetworkAgentInfo defaultNai = getDefaultNetwork(); + if (defaultNai != null && defaultNai.network.netId == netId) { + setDefaultDnsSystemProperties(dnses); } + flushVmDnsCache(); } private void setDefaultDnsSystemProperties(Collection<InetAddress> dnses) { diff --git a/services/core/java/com/android/server/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index 423f9456ee7f..ccb4647d8591 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -198,6 +198,7 @@ public class DeviceIdleController extends SystemService private long mNextIdleDelay; private long mNextLightIdleDelay; private long mNextLightAlarmTime; + private long mNextSensingTimeoutAlarmTime; private long mCurIdleBudget; private long mMaintenanceStartTime; @@ -339,6 +340,18 @@ public class DeviceIdleController extends SystemService } }; + private final AlarmManager.OnAlarmListener mSensingTimeoutAlarmListener + = new AlarmManager.OnAlarmListener() { + @Override + public void onAlarm() { + if (mState == STATE_SENSING) { + synchronized (DeviceIdleController.this) { + becomeInactiveIfAppropriateLocked(); + } + } + } + }; + private final AlarmManager.OnAlarmListener mDeepAlarmListener = new AlarmManager.OnAlarmListener() { @Override @@ -924,6 +937,11 @@ public class DeviceIdleController extends SystemService @Override public void onAnyMotionResult(int result) { if (DEBUG) Slog.d(TAG, "onAnyMotionResult(" + result + ")"); + if (result != AnyMotionDetector.RESULT_UNKNOWN) { + synchronized (this) { + cancelSensingTimeoutAlarmLocked(); + } + } if (result == AnyMotionDetector.RESULT_MOVED) { if (DEBUG) Slog.d(TAG, "RESULT_MOVED received."); synchronized (this) { @@ -1746,6 +1764,7 @@ public class DeviceIdleController extends SystemService mNextIdleDelay = 0; mNextLightIdleDelay = 0; cancelAlarmLocked(); + cancelSensingTimeoutAlarmLocked(); cancelLocatingLocked(); stopMonitoringMotionLocked(); mAnyMotionDetector.stop(); @@ -1866,15 +1885,16 @@ public class DeviceIdleController extends SystemService mState = STATE_SENSING; if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE_PENDING to STATE_SENSING."); EventLogTags.writeDeviceIdle(mState, reason); - scheduleAlarmLocked(mConstants.SENSING_TIMEOUT, false); + scheduleSensingTimeoutAlarmLocked(mConstants.SENSING_TIMEOUT); cancelLocatingLocked(); - mAnyMotionDetector.checkForAnyMotion(); mNotMoving = false; mLocated = false; mLastGenericLocation = null; mLastGpsLocation = null; + mAnyMotionDetector.checkForAnyMotion(); break; case STATE_SENSING: + cancelSensingTimeoutAlarmLocked(); mState = STATE_LOCATING; if (DEBUG) Slog.d(TAG, "Moved from STATE_SENSING to STATE_LOCATING."); EventLogTags.writeDeviceIdle(mState, reason); @@ -2161,6 +2181,13 @@ public class DeviceIdleController extends SystemService } } + void cancelSensingTimeoutAlarmLocked() { + if (mNextSensingTimeoutAlarmTime != 0) { + mNextSensingTimeoutAlarmTime = 0; + mAlarmManager.cancel(mSensingTimeoutAlarmListener); + } + } + void scheduleAlarmLocked(long delay, boolean idleUntil) { if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")"); if (mMotionSensor == null) { @@ -2194,6 +2221,13 @@ public class DeviceIdleController extends SystemService mNextLightAlarmTime, "DeviceIdleController.light", mLightAlarmListener, mHandler); } + void scheduleSensingTimeoutAlarmLocked(long delay) { + if (DEBUG) Slog.d(TAG, "scheduleSensingAlarmLocked(" + delay + ")"); + mNextSensingTimeoutAlarmTime = SystemClock.elapsedRealtime() + delay; + mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, mNextSensingTimeoutAlarmTime, + "DeviceIdleController.sensing", mSensingTimeoutAlarmListener, mHandler); + } + private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps, ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) { outAppIds.clear(); diff --git a/services/core/java/com/android/server/DisplayThread.java b/services/core/java/com/android/server/DisplayThread.java index aa0a80508d0f..9ef02598c1d3 100644 --- a/services/core/java/com/android/server/DisplayThread.java +++ b/services/core/java/com/android/server/DisplayThread.java @@ -17,6 +17,7 @@ package com.android.server; import android.os.Handler; +import android.os.Trace; /** * Shared singleton foreground thread for the system. This is a thread for @@ -36,6 +37,7 @@ public final class DisplayThread extends ServiceThread { if (sInstance == null) { sInstance = new DisplayThread(); sInstance.start(); + sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_ACTIVITY_MANAGER); sHandler = new Handler(sInstance.getLooper()); } } diff --git a/services/core/java/com/android/server/FgThread.java b/services/core/java/com/android/server/FgThread.java index 03765db35bae..5f85cbac21d5 100644 --- a/services/core/java/com/android/server/FgThread.java +++ b/services/core/java/com/android/server/FgThread.java @@ -17,6 +17,7 @@ package com.android.server; import android.os.Handler; +import android.os.Trace; /** * Shared singleton foreground thread for the system. This is a thread for regular @@ -38,6 +39,7 @@ public final class FgThread extends ServiceThread { if (sInstance == null) { sInstance = new FgThread(); sInstance.start(); + sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_ACTIVITY_MANAGER); sHandler = new Handler(sInstance.getLooper()); } } diff --git a/services/core/java/com/android/server/GestureLauncherService.java b/services/core/java/com/android/server/GestureLauncherService.java index d6575e84352d..aa986489e1c2 100644 --- a/services/core/java/com/android/server/GestureLauncherService.java +++ b/services/core/java/com/android/server/GestureLauncherService.java @@ -34,6 +34,7 @@ import android.os.PowerManager.WakeLock; import android.os.SystemClock; import android.os.SystemProperties; import android.provider.Settings; +import android.util.MutableBoolean; import android.util.Slog; import android.view.KeyEvent; @@ -251,7 +252,8 @@ public class GestureLauncherService extends SystemService { return isCameraLaunchEnabled(resources) || isCameraDoubleTapPowerEnabled(resources); } - public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive) { + public boolean interceptPowerKeyDown(KeyEvent event, boolean interactive, + MutableBoolean outLaunched) { boolean launched = false; boolean intercept = false; long doubleTapInterval; @@ -276,6 +278,7 @@ public class GestureLauncherService extends SystemService { } } MetricsLogger.histogram(mContext, "power_double_tap_interval", (int) doubleTapInterval); + outLaunched.value = launched; return intercept && launched; } diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index b8cbf16e9f6f..ac7872a94bf8 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -15,6 +15,8 @@ package com.android.server; +import static java.lang.annotation.RetentionPolicy.SOURCE; + import com.android.internal.content.PackageMonitor; import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController; import com.android.internal.inputmethod.InputMethodSubtypeSwitchingController.ImeSubtypeListItem; @@ -37,6 +39,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; @@ -125,6 +128,7 @@ import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.RadioButton; import android.widget.Switch; import android.widget.TextView; +import android.widget.Toast; import java.io.File; import java.io.FileDescriptor; @@ -132,6 +136,7 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.PrintWriter; +import java.lang.annotation.Retention; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collections; @@ -177,6 +182,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private static final int NOT_A_SUBTYPE_ID = InputMethodUtils.NOT_A_SUBTYPE_ID; private static final String TAG_TRY_SUPPRESSING_IME_SWITCHER = "TrySuppressingImeSwitcher"; + @Retention(SOURCE) + @IntDef({HardKeyboardBehavior.WIRELESS_AFFORDANCE, HardKeyboardBehavior.WIRED_AFFORDANCE}) + private @interface HardKeyboardBehavior { + int WIRELESS_AFFORDANCE = 0; + int WIRED_AFFORDANCE = 1; + } final Context mContext; final Resources mRes; @@ -452,6 +463,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private AlertDialog.Builder mDialogBuilder; private AlertDialog mSwitchingDialog; private View mSwitchingDialogTitleView; + private Toast mSubtypeSwitchedByShortCutToast; private InputMethodInfo[] mIms; private int[] mSubtypeIds; private LocaleList mLastSystemLocales; @@ -460,6 +472,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private final MyPackageMonitor mMyPackageMonitor = new MyPackageMonitor(); private final IPackageManager mIPackageManager; private final String mSlotIme; + @HardKeyboardBehavior + private final int mHardKeyboardBehavior; class SettingsObserver extends ContentObserver { int mUserId; @@ -852,6 +866,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub mHasFeature = context.getPackageManager().hasSystemFeature( PackageManager.FEATURE_INPUT_METHODS); mSlotIme = mContext.getString(com.android.internal.R.string.status_bar_ime); + mHardKeyboardBehavior = mContext.getResources().getInteger( + com.android.internal.R.integer.config_externalHardKeyboardBehavior); Bundle extras = new Bundle(); extras.putBoolean(Notification.EXTRA_ALLOW_DURING_SETUP, true); @@ -1710,11 +1726,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (isScreenLocked()) return false; if ((visibility & InputMethodService.IME_ACTIVE) == 0) return false; if (mWindowManagerInternal.isHardKeyboardAvailable()) { - // When physical keyboard is attached, we show the ime switcher (or notification if - // NavBar is not available) because SHOW_IME_WITH_HARD_KEYBOARD settings currently - // exists in the IME switcher dialog. Might be OK to remove this condition once - // SHOW_IME_WITH_HARD_KEYBOARD settings finds a good place to live. - return true; + if (mHardKeyboardBehavior == HardKeyboardBehavior.WIRELESS_AFFORDANCE) { + // When physical keyboard is attached, we show the ime switcher (or notification if + // NavBar is not available) because SHOW_IME_WITH_HARD_KEYBOARD settings currently + // exists in the IME switcher dialog. Might be OK to remove this condition once + // SHOW_IME_WITH_HARD_KEYBOARD settings finds a good place to live. + return true; + } } else if ((visibility & InputMethodService.IME_VISIBLE) == 0) { return false; } @@ -2952,6 +2970,27 @@ public class InputMethodManagerService extends IInputMethodManager.Stub return; } setInputMethodLocked(nextSubtype.mImi.getId(), nextSubtype.mSubtypeId); + if (mSubtypeSwitchedByShortCutToast != null) { + mSubtypeSwitchedByShortCutToast.cancel(); + mSubtypeSwitchedByShortCutToast = null; + } + if ((mImeWindowVis & InputMethodService.IME_VISIBLE) != 0) { + // IME window is shown. The user should be able to visually understand that the + // subtype is changed in most of cases. To avoid UI overlap, we do not show a toast + // in this case. + return; + } + final InputMethodInfo newInputMethodInfo = mMethodMap.get(mCurMethodId); + if (newInputMethodInfo == null) { + return; + } + final CharSequence toastText = InputMethodUtils.getImeAndSubtypeDisplayName(mContext, + newInputMethodInfo, mCurrentSubtype); + if (!TextUtils.isEmpty(toastText)) { + mSubtypeSwitchedByShortCutToast = Toast.makeText(mContext, toastText.toString(), + Toast.LENGTH_SHORT); + mSubtypeSwitchedByShortCutToast.show(); + } } } @@ -3823,6 +3862,22 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } + private static String imeWindowStatusToString(final int imeWindowVis) { + final StringBuilder sb = new StringBuilder(); + boolean first = true; + if ((imeWindowVis & InputMethodService.IME_ACTIVE) != 0) { + sb.append("Active"); + first = false; + } + if ((imeWindowVis & InputMethodService.IME_VISIBLE) != 0) { + if (!first) { + sb.append("|"); + } + sb.append("Visible"); + } + return sb.toString(); + } + @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) @@ -3870,6 +3925,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub method = mCurMethod; p.println(" mCurMethod=" + mCurMethod); p.println(" mEnabledSession=" + mEnabledSession); + p.println(" mImeWindowVis=" + imeWindowStatusToString(mImeWindowVis)); p.println(" mShowRequested=" + mShowRequested + " mShowExplicitlyRequested=" + mShowExplicitlyRequested + " mShowForced=" + mShowForced diff --git a/services/core/java/com/android/server/IoThread.java b/services/core/java/com/android/server/IoThread.java index 0f29857db345..ad4c19485f26 100644 --- a/services/core/java/com/android/server/IoThread.java +++ b/services/core/java/com/android/server/IoThread.java @@ -17,6 +17,7 @@ package com.android.server; import android.os.Handler; +import android.os.Trace; /** * Shared singleton I/O thread for the system. This is a thread for non-background @@ -35,6 +36,7 @@ public final class IoThread extends ServiceThread { if (sInstance == null) { sInstance = new IoThread(); sInstance.start(); + sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_ACTIVITY_MANAGER); sHandler = new Handler(sInstance.getLooper()); } } diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java index ed16af51c7eb..4ac75cabca3b 100644 --- a/services/core/java/com/android/server/LockSettingsService.java +++ b/services/core/java/com/android/server/LockSettingsService.java @@ -56,6 +56,9 @@ import android.provider.Settings; import android.provider.Settings.Secure; import android.provider.Settings.SettingNotFoundException; import android.security.KeyStore; +import android.security.keystore.AndroidKeyStoreProvider; +import android.security.keystore.KeyProperties; +import android.security.keystore.KeyProtection; import android.service.gatekeeper.GateKeeperResponse; import android.service.gatekeeper.IGateKeeperService; import android.text.TextUtils; @@ -68,15 +71,33 @@ import com.android.internal.widget.LockPatternUtils; import com.android.internal.widget.VerifyCredentialResponse; import com.android.server.LockSettingsStorage.CredentialHash; +import libcore.util.HexEncoding; + +import java.io.ByteArrayOutputStream; +import java.io.FileNotFoundException; +import java.io.IOException; import java.nio.charset.StandardCharsets; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.KeyStoreException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; - +import java.security.SecureRandom; +import java.security.UnrecoverableKeyException; +import java.security.cert.CertificateException; import java.util.Arrays; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; +import javax.crypto.spec.GCMParameterSpec; + /** * Keeps the lock pattern/password data and related settings for each user. * Used by LockPatternUtils. Needs to be a service because Settings app also needs @@ -90,6 +111,12 @@ public class LockSettingsService extends ILockSettings.Stub { private static final int FBE_ENCRYPTED_NOTIFICATION = 0; private static final boolean DEBUG = false; + private static final String PROFILE_KEY_NAME_ENCRYPT = "profile_key_name_encrypt_"; + private static final String PROFILE_KEY_NAME_DECRYPT = "profile_key_name_decrypt_"; + private static final int PROFILE_KEY_IV_SIZE = 12; + private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge"; + private final Object mSeparateChallengeLock = new Object(); + private final Context mContext; private final LockSettingsStorage mStorage; private final LockSettingsStrongAuth mStrongAuth; @@ -125,6 +152,7 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public void onStart() { + AndroidKeyStoreProvider.install(); mLockSettingsService = new LockSettingsService(getContext()); publishBinderService("lock_settings", mLockSettingsService); } @@ -149,6 +177,46 @@ public class LockSettingsService extends ILockSettings.Stub { } } + /** + * Tie managed profile to primary profile if it is in unified mode and not tied before. + * + * @param managedUserId Managed profile user Id + * @param managedUserPassword Managed profile original password (when it has separated lock). + * NULL when it does not have a separated lock before. + */ + public void tieManagedProfileLockIfNecessary(int managedUserId, String managedUserPassword) { + if (DEBUG) Slog.v(TAG, "Check child profile lock for user: " + managedUserId); + // Only for managed profile + if (!UserManager.get(mContext).getUserInfo(managedUserId).isManagedProfile()) { + return; + } + // Do not tie managed profile when work challenge is enabled + if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) { + return; + } + // Do not tie managed profile to parent when it's done already + if (mStorage.hasChildProfileLock(managedUserId)) { + return; + } + // Do not tie it to parent when parent does not have a screen lock + final int parentId = mUserManager.getProfileParent(managedUserId).id; + if (!mStorage.hasPassword(parentId) && !mStorage.hasPattern(parentId)) { + if (DEBUG) Slog.v(TAG, "Parent does not have a screen lock"); + return; + } + if (DEBUG) Slog.v(TAG, "Tie managed profile to parent now!"); + byte[] randomLockSeed = new byte[] {}; + try { + randomLockSeed = SecureRandom.getInstance("SHA1PRNG").generateSeed(40); + String newPassword = String.valueOf(HexEncoding.encode(randomLockSeed)); + setLockPasswordInternal(newPassword, managedUserPassword, managedUserId); + tieProfileLockToParent(managedUserId, newPassword); + } catch (NoSuchAlgorithmException | RemoteException e) { + Slog.e(TAG, "Fail to tie managed profile", e); + // Nothing client can do to fix this issue, so we do not throw exception out + } + } + public LockSettingsService(Context context) { mContext = context; mStrongAuth = new LockSettingsStrongAuth(context); @@ -254,7 +322,7 @@ public class LockSettingsService extends ILockSettings.Stub { com.android.internal.R.color.system_notification_accent_color)) .setContentTitle(title) .setContentText(message) - .setContentInfo(detail) + .setSubText(detail) .setVisibility(Notification.VISIBILITY_PUBLIC) .setContentIntent(intent) .build(); @@ -271,6 +339,7 @@ public class LockSettingsService extends ILockSettings.Stub { } public void onUnlockUser(int userId) { + tieManagedProfileLockIfNecessary(userId, null); hideEncryptionNotification(new UserHandle(userId)); // Now we have unlocked the parent user we should show notifications @@ -294,8 +363,7 @@ public class LockSettingsService extends ILockSettings.Stub { // Notify keystore that a new user was added. final int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); final KeyStore ks = KeyStore.getInstance(); - final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); - final UserInfo parentInfo = um.getProfileParent(userHandle); + final UserInfo parentInfo = mUserManager.getProfileParent(userHandle); final int parentHandle = parentInfo != null ? parentInfo.id : -1; ks.onUserAdded(userHandle, parentHandle); } else if (Intent.ACTION_USER_STARTING.equals(intent.getAction())) { @@ -343,9 +411,8 @@ public class LockSettingsService extends ILockSettings.Stub { // These Settings changed after multi-user was enabled, hence need to be moved per user. if (getString("migrated_user_specific", null, 0) == null) { - final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); final ContentResolver cr = mContext.getContentResolver(); - List<UserInfo> users = um.getUsers(); + List<UserInfo> users = mUserManager.getUsers(); for (int user = 0; user < users.size(); user++) { // Migrate owner info final int userId = users.get(user).id; @@ -380,8 +447,7 @@ public class LockSettingsService extends ILockSettings.Stub { // Migrates biometric weak such that the fallback mechanism becomes the primary. if (getString("migrated_biometric_weak", null, 0) == null) { - final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); - List<UserInfo> users = um.getUsers(); + List<UserInfo> users = mUserManager.getUsers(); for (int i = 0; i < users.size(); i++) { int userId = users.get(i).id; long type = getLong(LockPatternUtils.PASSWORD_TYPE_KEY, @@ -407,9 +473,7 @@ public class LockSettingsService extends ILockSettings.Stub { // user was present on the system, so if we're upgrading to M and there is more than one // user we disable the flag to remain consistent. if (getString("migrated_lockscreen_disabled", null, 0) == null) { - final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); - - final List<UserInfo> users = um.getUsers(); + final List<UserInfo> users = mUserManager.getUsers(); final int userCount = users.size(); int switchableUsers = 0; for (int i = 0; i < userCount; i++) { @@ -469,6 +533,27 @@ public class LockSettingsService extends ILockSettings.Stub { } @Override + public boolean getSeparateProfileChallengeEnabled(int userId) throws RemoteException { + synchronized (mSeparateChallengeLock) { + return getBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, false, userId); + } + } + + @Override + public void setSeparateProfileChallengeEnabled(int userId, boolean enabled, + String managedUserPassword) throws RemoteException { + synchronized (mSeparateChallengeLock) { + setBoolean(SEPARATE_PROFILE_CHALLENGE_KEY, enabled, userId); + if (enabled) { + mStorage.removeChildProfileLock(userId); + removeKeystoreProfileKey(userId); + } else { + tieManagedProfileLockIfNecessary(userId, managedUserPassword); + } + } + } + + @Override public void setBoolean(String key, boolean value, int userId) throws RemoteException { checkWritePermission(userId); setStringUnchecked(key, userId, value ? "1" : "0"); @@ -536,61 +621,65 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public boolean havePassword(int userId) throws RemoteException { // Do we need a permissions check here? - return mStorage.hasPassword(userId); } @Override public boolean havePattern(int userId) throws RemoteException { // Do we need a permissions check here? - return mStorage.hasPattern(userId); } private void setKeystorePassword(String password, int userHandle) { - final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); final KeyStore ks = KeyStore.getInstance(); - - if (um.getUserInfo(userHandle).isManagedProfile()) { - if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) { - ks.onUserPasswordChanged(userHandle, password); - } else { - throw new RuntimeException("Can't set keystore password on a profile that " - + "doesn't have a profile challenge."); - } - } else { - final List<UserInfo> profiles = um.getProfiles(userHandle); - for (UserInfo pi : profiles) { - // Change password on the given user and all its profiles that don't have - // their own profile challenge enabled. - if (pi.id == userHandle || (pi.isManagedProfile() - && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id))) { - ks.onUserPasswordChanged(pi.id, password); - } - } - } + ks.onUserPasswordChanged(userHandle, password); } private void unlockKeystore(String password, int userHandle) { - final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); + if (DEBUG) Slog.v(TAG, "Unlock keystore for user: " + userHandle); final KeyStore ks = KeyStore.getInstance(); + ks.unlock(userHandle, password); + } + + private String getDecryptedPasswordForTiedProfile(int userId) + throws KeyStoreException, UnrecoverableKeyException, + NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, + InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, + CertificateException, IOException { + if (DEBUG) Slog.v(TAG, "Unlock keystore for child profile"); + byte[] storedData = mStorage.readChildProfileLock(userId); + if (storedData == null) { + throw new FileNotFoundException("Child profile lock file not found"); + } + byte[] iv = Arrays.copyOfRange(storedData, 0, PROFILE_KEY_IV_SIZE); + byte[] encryptedPassword = Arrays.copyOfRange(storedData, PROFILE_KEY_IV_SIZE, + storedData.length); + byte[] decryptionResult; + java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore"); + keyStore.load(null); + SecretKey decryptionKey = (SecretKey) keyStore.getKey( + PROFILE_KEY_NAME_DECRYPT + userId, null); + + Cipher cipher = Cipher.getInstance(KeyProperties.KEY_ALGORITHM_AES + "/" + + KeyProperties.BLOCK_MODE_GCM + "/" + KeyProperties.ENCRYPTION_PADDING_NONE); + + cipher.init(Cipher.DECRYPT_MODE, decryptionKey, new GCMParameterSpec(128, iv)); + decryptionResult = cipher.doFinal(encryptedPassword); + return new String(decryptionResult, StandardCharsets.UTF_8); + } - if (um.getUserInfo(userHandle).isManagedProfile()) { - if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userHandle)) { - ks.unlock(userHandle, password); + private void unlockChildProfile(int profileHandle) throws RemoteException { + try { + doVerifyPassword(getDecryptedPasswordForTiedProfile(profileHandle), false, + 0 /* no challenge */, profileHandle); + } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException + | NoSuchAlgorithmException | NoSuchPaddingException + | InvalidAlgorithmParameterException | IllegalBlockSizeException + | BadPaddingException | CertificateException | IOException e) { + if (e instanceof FileNotFoundException) { + Slog.i(TAG, "Child profile key not found"); } else { - throw new RuntimeException("Can't unlock a profile explicitly if it " - + "doesn't have a profile challenge."); - } - } else { - final List<UserInfo> profiles = um.getProfiles(userHandle); - for (UserInfo pi : profiles) { - // Unlock the given user and all its profiles that don't have - // their own profile challenge enabled. - if (pi.id == userHandle || (pi.isManagedProfile() - && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id))) { - ks.unlock(pi.id, password); - } + Slog.e(TAG, "Failed to decrypt child profile key", e); } } } @@ -627,6 +716,21 @@ public class LockSettingsService extends ILockSettings.Stub { } catch (InterruptedException e) { Thread.currentThread().interrupt(); } + try { + if (!mUserManager.getUserInfo(userId).isManagedProfile()) { + final List<UserInfo> profiles = mUserManager.getProfiles(userId); + for (UserInfo pi : profiles) { + // Unlock managed profile with unified lock + if (pi.isManagedProfile() + && !mLockPatternUtils.isSeparateProfileChallengeEnabled(pi.id) + && mStorage.hasChildProfileLock(pi.id)) { + unlockChildProfile(pi.id); + } + } + } + } catch (RemoteException e) { + Log.d(TAG, "Failed to unlock child profile", e); + } } private byte[] getCurrentHandle(int userId) { @@ -661,10 +765,57 @@ public class LockSettingsService extends ILockSettings.Stub { return currentHandle; } + private void onUserLockChanged(int userId) throws RemoteException { + if (mUserManager.getUserInfo(userId).isManagedProfile()) { + return; + } + final boolean isSecure = mStorage.hasPassword(userId) || mStorage.hasPattern(userId); + final List<UserInfo> profiles = mUserManager.getProfiles(userId); + final int size = profiles.size(); + for (int i = 0; i < size; i++) { + final UserInfo profile = profiles.get(i); + if (profile.isManagedProfile()) { + final int managedUserId = profile.id; + if (mLockPatternUtils.isSeparateProfileChallengeEnabled(managedUserId)) { + continue; + } + if (isSecure) { + tieManagedProfileLockIfNecessary(managedUserId, null); + } else { + getGateKeeperService().clearSecureUserId(managedUserId); + mStorage.writePatternHash(null, managedUserId); + setKeystorePassword(null, managedUserId); + clearUserKeyProtection(managedUserId); + mStorage.removeChildProfileLock(managedUserId); + removeKeystoreProfileKey(managedUserId); + } + } + } + } + + private boolean isManagedProfileWithUnifiedLock(int userId) { + return mUserManager.getUserInfo(userId).isManagedProfile() + && !mLockPatternUtils.isSeparateProfileChallengeEnabled(userId); + } + + private boolean isManagedProfileWithSeparatedLock(int userId) { + return mUserManager.getUserInfo(userId).isManagedProfile() + && mLockPatternUtils.isSeparateProfileChallengeEnabled(userId); + } + // This method should be called by LockPatternUtil only, all internal methods in this class + // should call setLockPatternInternal. @Override public void setLockPattern(String pattern, String savedCredential, int userId) throws RemoteException { + synchronized (mSeparateChallengeLock) { + setLockPatternInternal(pattern, savedCredential, userId); + setSeparateProfileChallengeEnabled(userId, true, null); + } + } + + public void setLockPatternInternal(String pattern, String savedCredential, int userId) + throws RemoteException { byte[] currentHandle = getCurrentHandle(userId); if (pattern == null) { @@ -672,55 +823,157 @@ public class LockSettingsService extends ILockSettings.Stub { mStorage.writePatternHash(null, userId); setKeystorePassword(null, userId); clearUserKeyProtection(userId); + onUserLockChanged(userId); return; } - if (currentHandle == null) { - if (savedCredential != null) { - Slog.w(TAG, "Saved credential provided, but none stored"); + if (isManagedProfileWithUnifiedLock(userId)) { + // get credential from keystore when managed profile has unified lock + try { + savedCredential = getDecryptedPasswordForTiedProfile(userId); + } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException + | NoSuchAlgorithmException | NoSuchPaddingException + | InvalidAlgorithmParameterException | IllegalBlockSizeException + | BadPaddingException | CertificateException | IOException e) { + if (e instanceof FileNotFoundException) { + Slog.i(TAG, "Child profile key not found"); + } else { + Slog.e(TAG, "Failed to decrypt child profile key", e); + } + } + } else { + if (currentHandle == null) { + if (savedCredential != null) { + Slog.w(TAG, "Saved credential provided, but none stored"); + } + savedCredential = null; } - savedCredential = null; } byte[] enrolledHandle = enrollCredential(currentHandle, savedCredential, pattern, userId); if (enrolledHandle != null) { mStorage.writePatternHash(enrolledHandle, userId); setUserKeyProtection(userId, pattern, verifyPattern(pattern, 0, userId)); + onUserLockChanged(userId); } else { throw new RemoteException("Failed to enroll pattern"); } } - + // This method should be called by LockPatternUtil only, all internal methods in this class + // should call setLockPasswordInternal. @Override public void setLockPassword(String password, String savedCredential, int userId) throws RemoteException { - byte[] currentHandle = getCurrentHandle(userId); + synchronized (mSeparateChallengeLock) { + setLockPasswordInternal(password, savedCredential, userId); + setSeparateProfileChallengeEnabled(userId, true, null); + } + } + public void setLockPasswordInternal(String password, String savedCredential, int userId) + throws RemoteException { + byte[] currentHandle = getCurrentHandle(userId); if (password == null) { getGateKeeperService().clearSecureUserId(userId); mStorage.writePasswordHash(null, userId); setKeystorePassword(null, userId); clearUserKeyProtection(userId); + onUserLockChanged(userId); return; } - if (currentHandle == null) { - if (savedCredential != null) { - Slog.w(TAG, "Saved credential provided, but none stored"); + if (isManagedProfileWithUnifiedLock(userId)) { + // get credential from keystore when managed profile has unified lock + try { + savedCredential = getDecryptedPasswordForTiedProfile(userId); + } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException + | NoSuchAlgorithmException | NoSuchPaddingException + | InvalidAlgorithmParameterException | IllegalBlockSizeException + | BadPaddingException | CertificateException | IOException e) { + if (e instanceof FileNotFoundException) { + Slog.i(TAG, "Child profile key not found"); + } else { + Slog.e(TAG, "Failed to decrypt child profile key", e); + } + } + } else { + if (currentHandle == null) { + if (savedCredential != null) { + Slog.w(TAG, "Saved credential provided, but none stored"); + } + savedCredential = null; } - savedCredential = null; } byte[] enrolledHandle = enrollCredential(currentHandle, savedCredential, password, userId); if (enrolledHandle != null) { mStorage.writePasswordHash(enrolledHandle, userId); setUserKeyProtection(userId, password, verifyPassword(password, 0, userId)); + onUserLockChanged(userId); } else { throw new RemoteException("Failed to enroll password"); } } + private void tieProfileLockToParent(int userId, String password) { + if (DEBUG) Slog.v(TAG, "tieProfileLockToParent for user: " + userId); + byte[] randomLockSeed = password.getBytes(StandardCharsets.UTF_8); + byte[] encryptionResult; + byte[] iv; + try { + KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES); + keyGenerator.init(new SecureRandom()); + SecretKey secretKey = keyGenerator.generateKey(); + + java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore"); + keyStore.load(null); + keyStore.setEntry( + PROFILE_KEY_NAME_ENCRYPT + userId, + new java.security.KeyStore.SecretKeyEntry(secretKey), + new KeyProtection.Builder(KeyProperties.PURPOSE_ENCRYPT) + .setBlockModes(KeyProperties.BLOCK_MODE_GCM) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) + .build()); + keyStore.setEntry( + PROFILE_KEY_NAME_DECRYPT + userId, + new java.security.KeyStore.SecretKeyEntry(secretKey), + new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT) + .setBlockModes(KeyProperties.BLOCK_MODE_GCM) + .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) + .setUserAuthenticationRequired(true) + .setUserAuthenticationValidityDurationSeconds(30) + .build()); + + // Key imported, obtain a reference to it. + SecretKey keyStoreEncryptionKey = (SecretKey) keyStore.getKey( + PROFILE_KEY_NAME_ENCRYPT + userId, null); + // The original key can now be discarded. + + Cipher cipher = Cipher.getInstance( + KeyProperties.KEY_ALGORITHM_AES + "/" + KeyProperties.BLOCK_MODE_GCM + "/" + + KeyProperties.ENCRYPTION_PADDING_NONE); + cipher.init(Cipher.ENCRYPT_MODE, keyStoreEncryptionKey); + encryptionResult = cipher.doFinal(randomLockSeed); + iv = cipher.getIV(); + } catch (CertificateException | UnrecoverableKeyException + | IOException | BadPaddingException | IllegalBlockSizeException | KeyStoreException + | NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException e) { + throw new RuntimeException("Failed to encrypt key", e); + } + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + try { + if (iv.length != PROFILE_KEY_IV_SIZE) { + throw new RuntimeException("Invalid iv length: " + iv.length); + } + outputStream.write(iv); + outputStream.write(encryptionResult); + } catch (IOException e) { + throw new RuntimeException("Failed to concatenate byte arrays", e); + } + mStorage.writeChildProfileLock(userId, outputStream.toByteArray()); + } + private byte[] enrollCredential(byte[] enrolledHandle, String enrolledCredential, String toEnroll, int userId) throws RemoteException { @@ -820,7 +1073,7 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public void setCredential(String pattern, String oldPattern, int userId) throws RemoteException { - setLockPattern(pattern, oldPattern, userId); + setLockPatternInternal(pattern, oldPattern, userId); } @Override @@ -838,7 +1091,7 @@ public class LockSettingsService extends ILockSettings.Stub { if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK && shouldReEnrollBaseZero) { - setLockPattern(pattern, patternToVerify, userId); + setLockPatternInternal(pattern, patternToVerify, userId); } return response; @@ -857,6 +1110,37 @@ public class LockSettingsService extends ILockSettings.Stub { return doVerifyPassword(password, true, challenge, userId); } + @Override + public VerifyCredentialResponse verifyTiedProfileChallenge(String password, boolean isPattern, + long challenge, int userId) throws RemoteException { + checkPasswordReadPermission(userId); + if (!isManagedProfileWithUnifiedLock(userId)) { + throw new RemoteException("User id must be managed profile with unified lock"); + } + final int parentProfileId = mUserManager.getProfileParent(userId).id; + // Unlock parent by using parent's challenge + final VerifyCredentialResponse parentResponse = isPattern + ? doVerifyPattern(password, true, challenge, parentProfileId) + : doVerifyPassword(password, true, challenge, parentProfileId); + if (parentResponse.getResponseCode() != VerifyCredentialResponse.RESPONSE_OK) { + // Failed, just return parent's response + return parentResponse; + } + + try { + // Unlock work profile, and work profile with unified lock must use password only + return doVerifyPassword(getDecryptedPasswordForTiedProfile(userId), true, + challenge, + userId); + } catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException + | NoSuchAlgorithmException | NoSuchPaddingException + | InvalidAlgorithmParameterException | IllegalBlockSizeException + | BadPaddingException | CertificateException | IOException e) { + Slog.e(TAG, "Failed to decrypt child profile key", e); + throw new RemoteException("Unable to get tied profile token"); + } + } + private VerifyCredentialResponse doVerifyPassword(String password, boolean hasChallenge, long challenge, int userId) throws RemoteException { checkPasswordReadPermission(userId); @@ -866,7 +1150,7 @@ public class LockSettingsService extends ILockSettings.Stub { @Override public void setCredential(String password, String oldPassword, int userId) throws RemoteException { - setLockPassword(password, oldPassword, userId); + setLockPasswordInternal(password, oldPassword, userId); } @Override @@ -947,8 +1231,7 @@ public class LockSettingsService extends ILockSettings.Stub { " with token length " + response.getPayload().length); unlockUser(userId, response.getPayload(), secretFromCredential(credential)); - UserInfo info = UserManager.get(mContext).getUserInfo(userId); - if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) { + if (isManagedProfileWithSeparatedLock(userId)) { TrustManager trustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE); trustManager.setDeviceLockedForUser(userId, false); @@ -1027,6 +1310,23 @@ public class LockSettingsService extends ILockSettings.Stub { } catch (RemoteException ex) { Slog.w(TAG, "unable to clear GK secure user id"); } + if (mUserManager.getUserInfo(userId).isManagedProfile()) { + removeKeystoreProfileKey(userId); + } + } + + private void removeKeystoreProfileKey(int targetUserId) { + if (DEBUG) Slog.v(TAG, "Remove keystore profile key for user: " + targetUserId); + try { + java.security.KeyStore keyStore = java.security.KeyStore.getInstance("AndroidKeyStore"); + keyStore.load(null); + keyStore.deleteEntry(PROFILE_KEY_NAME_ENCRYPT + targetUserId); + keyStore.deleteEntry(PROFILE_KEY_NAME_DECRYPT + targetUserId); + } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException + | IOException e) { + // We have tried our best to remove all keys + Slog.e(TAG, "Unable to remove keystore profile key for user:" + targetUserId, e); + } } @Override diff --git a/services/core/java/com/android/server/LockSettingsStorage.java b/services/core/java/com/android/server/LockSettingsStorage.java index 816c791d47fa..d136f1af7654 100644 --- a/services/core/java/com/android/server/LockSettingsStorage.java +++ b/services/core/java/com/android/server/LockSettingsStorage.java @@ -17,7 +17,6 @@ package com.android.server; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.widget.LockPatternUtils; import android.content.ContentValues; import android.content.Context; @@ -30,6 +29,7 @@ import android.os.UserManager; import android.util.ArrayMap; import android.util.Log; import android.util.Slog; +import android.util.SparseArray; import java.io.File; import java.io.IOException; @@ -44,6 +44,7 @@ class LockSettingsStorage { private static final String TAG = "LockSettingsStorage"; private static final String TABLE = "locksettings"; + private static final boolean DEBUG = false; private static final String COLUMN_KEY = "name"; private static final String COLUMN_USERID = "user"; @@ -62,6 +63,7 @@ class LockSettingsStorage { private static final String LEGACY_LOCK_PATTERN_FILE = "gesture.key"; private static final String LOCK_PASSWORD_FILE = "gatekeeper.password.key"; private static final String LEGACY_LOCK_PASSWORD_FILE = "password.key"; + private static final String CHILD_PROFILE_LOCK_FILE = "gatekeeper.profile.key"; private static final Object DEFAULT = new Object(); @@ -70,8 +72,7 @@ class LockSettingsStorage { private final Cache mCache = new Cache(); private final Object mFileWriteLock = new Object(); - private int mStoredCredentialType; - private LockPatternUtils mLockPatternUtils; + private SparseArray<Integer> mStoredCredentialType; class CredentialHash { static final int TYPE_NONE = -1; @@ -101,7 +102,7 @@ class LockSettingsStorage { public LockSettingsStorage(Context context, Callback callback) { mContext = context; mOpenHelper = new DatabaseHelper(context, callback); - mLockPatternUtils = new LockPatternUtils(context); + mStoredCredentialType = new SparseArray<Integer>(); } public void writeKeyValue(String key, String value, int userId) { @@ -182,32 +183,34 @@ class LockSettingsStorage { } public int getStoredCredentialType(int userId) { - if (mStoredCredentialType != 0) { - return mStoredCredentialType; + final Integer cachedStoredCredentialType = mStoredCredentialType.get(userId); + if (cachedStoredCredentialType != null) { + return cachedStoredCredentialType.intValue(); } + int storedCredentialType; CredentialHash pattern = readPatternHash(userId); if (pattern == null) { if (readPasswordHash(userId) != null) { - mStoredCredentialType = CredentialHash.TYPE_PASSWORD; + storedCredentialType = CredentialHash.TYPE_PASSWORD; } else { - mStoredCredentialType = CredentialHash.TYPE_NONE; + storedCredentialType = CredentialHash.TYPE_NONE; } } else { CredentialHash password = readPasswordHash(userId); if (password != null) { // Both will never be GateKeeper if (password.version == CredentialHash.VERSION_GATEKEEPER) { - mStoredCredentialType = CredentialHash.TYPE_PASSWORD; + storedCredentialType = CredentialHash.TYPE_PASSWORD; } else { - mStoredCredentialType = CredentialHash.TYPE_PATTERN; + storedCredentialType = CredentialHash.TYPE_PATTERN; } } else { - mStoredCredentialType = CredentialHash.TYPE_PATTERN; + storedCredentialType = CredentialHash.TYPE_PATTERN; } } - - return mStoredCredentialType; + mStoredCredentialType.put(userId, storedCredentialType); + return storedCredentialType; } @@ -244,6 +247,27 @@ class LockSettingsStorage { return null; } + public void removeChildProfileLock(int userId) { + if (DEBUG) + Slog.e(TAG, "Remove child profile lock for user: " + userId); + try { + deleteFile(getChildProfileLockFile(userId)); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void writeChildProfileLock(int userId, byte[] lock) { + writeFile(getChildProfileLockFile(userId), lock); + } + + public byte[] readChildProfileLock(int userId) { + return readFile(getChildProfileLockFile(userId)); + } + + public boolean hasChildProfileLock(int userId) { + return hasFile(getChildProfileLockFile(userId)); + } public boolean hasPassword(int userId) { return hasFile(getLockPasswordFilename(userId)) || @@ -321,16 +345,19 @@ class LockSettingsStorage { } private void deleteFile(String name) { - File f = new File(name); - if (f != null) { - f.delete(); + if (DEBUG) Slog.e(TAG, "Delete file " + name); + synchronized (mFileWriteLock) { + File file = new File(name); + if (file.exists()) { + file.delete(); + mCache.putFile(name, null); + } } } public void writePatternHash(byte[] hash, int userId) { - mStoredCredentialType = hash == null - ? CredentialHash.TYPE_NONE - : CredentialHash.TYPE_PATTERN; + mStoredCredentialType.put(userId, hash == null ? CredentialHash.TYPE_NONE + : CredentialHash.TYPE_PATTERN); writeFile(getLockPatternFilename(userId), hash); clearPasswordHash(userId); } @@ -340,9 +367,8 @@ class LockSettingsStorage { } public void writePasswordHash(byte[] hash, int userId) { - mStoredCredentialType = hash == null - ? CredentialHash.TYPE_NONE - : CredentialHash.TYPE_PASSWORD; + mStoredCredentialType.put(userId, hash == null ? CredentialHash.TYPE_NONE + : CredentialHash.TYPE_PASSWORD); writeFile(getLockPasswordFilename(userId), hash); clearPatternHash(userId); } @@ -375,8 +401,11 @@ class LockSettingsStorage { return getLockCredentialFilePathForUser(userId, BASE_ZERO_LOCK_PATTERN_FILE); } + private String getChildProfileLockFile(int userId) { + return getLockCredentialFilePathForUser(userId, CHILD_PROFILE_LOCK_FILE); + } + private String getLockCredentialFilePathForUser(int userId, String basename) { - userId = getUserParentOrSelfId(userId); String dataSystemDirectory = android.os.Environment.getDataDirectory().getAbsolutePath() + SYSTEM_DIRECTORY; @@ -388,23 +417,6 @@ class LockSettingsStorage { } } - private int getUserParentOrSelfId(int userId) { - // Device supports per user encryption, so lock is applied to the given user. - if (mLockPatternUtils.isSeparateProfileChallengeEnabled(userId)) { - return userId; - } - // Device uses Block Based Encryption, and the parent user's lock is used for the whole - // device. - if (userId != 0) { - final UserManager um = (UserManager) mContext.getSystemService(USER_SERVICE); - final UserInfo pi = um.getProfileParent(userId); - if (pi != null) { - return pi.id; - } - } - return userId; - } - public void removeUser(int userId) { SQLiteDatabase db = mOpenHelper.getWritableDatabase(); @@ -427,6 +439,9 @@ class LockSettingsStorage { mCache.putFile(name, null); } } + } else { + // Manged profile + removeChildProfileLock(userId); } try { diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java index c6d536ddf671..bf4df94e92e2 100644 --- a/services/core/java/com/android/server/NetworkManagementService.java +++ b/services/core/java/com/android/server/NetworkManagementService.java @@ -1937,16 +1937,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub } @Override - public void flushNetworkDnsCache(int netId) { - mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG); - try { - mConnector.execute("resolver", "flushnet", netId); - } catch (NativeDaemonConnectorException e) { - throw e.rethrowAsParcelableException(); - } - } - - @Override public void setFirewallEnabled(boolean enabled) { enforceSystemUid(); try { diff --git a/services/core/java/com/android/server/NetworkScoreService.java b/services/core/java/com/android/server/NetworkScoreService.java index 879bb6f72895..2a78f908649b 100644 --- a/services/core/java/com/android/server/NetworkScoreService.java +++ b/services/core/java/com/android/server/NetworkScoreService.java @@ -18,10 +18,12 @@ package com.android.server; import android.Manifest.permission; import android.content.BroadcastReceiver; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.ServiceConnection; import android.content.pm.PackageManager; import android.net.INetworkScoreCache; import android.net.INetworkScoreService; @@ -30,6 +32,7 @@ import android.net.NetworkScorerAppManager; import android.net.NetworkScorerAppManager.NetworkScorerAppData; import android.net.ScoredNetwork; import android.os.Binder; +import android.os.IBinder; import android.os.PatternMatcher; import android.os.RemoteException; import android.os.UserHandle; @@ -55,17 +58,17 @@ import java.util.Set; */ public class NetworkScoreService extends INetworkScoreService.Stub { private static final String TAG = "NetworkScoreService"; + private static final boolean DBG = false; private final Context mContext; - private final Map<Integer, INetworkScoreCache> mScoreCaches; - /** Lock used to update mReceiver when scorer package changes occur. */ - private Object mReceiverLock = new Object[0]; + private final Object mReceiverLock = new Object[0]; /** Clears scores when the active scorer package is no longer valid. */ @GuardedBy("mReceiverLock") private ScorerChangedReceiver mReceiver; + private ScoringServiceConnection mServiceConnection; private class ScorerChangedReceiver extends BroadcastReceiver { final String mRegisteredPackage; @@ -77,14 +80,23 @@ public class NetworkScoreService extends INetworkScoreService.Stub { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); - if ((Intent.ACTION_PACKAGE_CHANGED.equals(action) || - Intent.ACTION_PACKAGE_REPLACED.equals(action) || - Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(action)) && - NetworkScorerAppManager.getActiveScorer(mContext) == null) { - // Package change has invalidated a scorer. - Log.i(TAG, "Package " + mRegisteredPackage + - " is no longer valid, disabling scoring"); - setScorerInternal(null); + if (Intent.ACTION_PACKAGE_CHANGED.equals(action) + || Intent.ACTION_PACKAGE_REPLACED.equals(action) + || Intent.ACTION_PACKAGE_FULLY_REMOVED.equals(action)) { + NetworkScorerAppData activeScorer = + NetworkScorerAppManager.getActiveScorer(mContext); + if (activeScorer == null) { + // Package change has invalidated a scorer. + Log.i(TAG, "Package " + mRegisteredPackage + + " is no longer valid, disabling scoring."); + setScorerInternal(null); + } else if (activeScorer.mScoringServiceClassName == null) { + // The scoring service is not available, make sure it's unbound. + unbindFromScoringServiceIfNeeded(); + } else { + // The scoring service may have changed or been added. + bindToScoringServiceIfNeeded(activeScorer); + } } } } @@ -96,6 +108,7 @@ public class NetworkScoreService extends INetworkScoreService.Stub { /** Called when the system is ready to run third-party code but before it actually does so. */ void systemReady() { + if (DBG) Log.d(TAG, "systemReady"); ContentResolver cr = mContext.getContentResolver(); if (Settings.Global.getInt(cr, Settings.Global.NETWORK_SCORING_PROVISIONED, 0) == 0) { // On first run, we try to initialize the scorer to the one configured at build time. @@ -111,7 +124,14 @@ public class NetworkScoreService extends INetworkScoreService.Stub { registerPackageReceiverIfNeeded(); } + /** Called when the system is ready for us to start third-party code. */ + void systemRunning() { + if (DBG) Log.d(TAG, "systemRunning"); + bindToScoringServiceIfNeeded(); + } + private void registerPackageReceiverIfNeeded() { + if (DBG) Log.d(TAG, "registerPackageReceiverIfNeeded"); NetworkScorerAppData scorer = NetworkScorerAppManager.getActiveScorer(mContext); synchronized (mReceiverLock) { // Unregister the receiver if the current scorer has changed since last registration. @@ -142,6 +162,41 @@ public class NetworkScoreService extends INetworkScoreService.Stub { } } + private void bindToScoringServiceIfNeeded() { + if (DBG) Log.d(TAG, "bindToScoringServiceIfNeeded"); + NetworkScorerAppData scorerData = NetworkScorerAppManager.getActiveScorer(mContext); + bindToScoringServiceIfNeeded(scorerData); + } + + private void bindToScoringServiceIfNeeded(NetworkScorerAppData scorerData) { + if (DBG) Log.d(TAG, "bindToScoringServiceIfNeeded(" + scorerData + ")"); + if (scorerData != null && scorerData.mScoringServiceClassName != null) { + ComponentName componentName = + new ComponentName(scorerData.mPackageName, scorerData.mScoringServiceClassName); + // If we're connected to a different component then drop it. + if (mServiceConnection != null + && !mServiceConnection.mComponentName.equals(componentName)) { + unbindFromScoringServiceIfNeeded(); + } + + // If we're not connected at all then create a new connection. + if (mServiceConnection == null) { + mServiceConnection = new ScoringServiceConnection(componentName); + } + + // Make sure the connection is connected (idempotent) + mServiceConnection.connect(mContext); + } + } + + private void unbindFromScoringServiceIfNeeded() { + if (DBG) Log.d(TAG, "unbindFromScoringServiceIfNeeded"); + if (mServiceConnection != null) { + mServiceConnection.disconnect(mContext); + } + mServiceConnection = null; + } + @Override public boolean updateScores(ScoredNetwork[] networks) { if (!NetworkScorerAppManager.isCallerActiveScorer(mContext, getCallingUid())) { @@ -228,8 +283,10 @@ public class NetworkScoreService extends INetworkScoreService.Stub { /** Set the active scorer. Callers are responsible for checking permissions as appropriate. */ private boolean setScorerInternal(String packageName) { + if (DBG) Log.d(TAG, "setScorerInternal(" + packageName + ")"); long token = Binder.clearCallingIdentity(); try { + unbindFromScoringServiceIfNeeded(); // Preemptively clear scores even though the set operation could fail. We do this for // safety as scores should never be compared across apps; in practice, Settings should // only be allowing valid apps to be set as scorers, so failure here should be rare. @@ -237,8 +294,13 @@ public class NetworkScoreService extends INetworkScoreService.Stub { // Get the scorer that is about to be replaced, if any, so we can notify it directly. NetworkScorerAppData prevScorer = NetworkScorerAppManager.getActiveScorer(mContext); boolean result = NetworkScorerAppManager.setActiveScorer(mContext, packageName); + // Unconditionally attempt to bind to the current scorer. If setActiveScorer() failed + // then we'll attempt to restore the previous binding (if any), otherwise an attempt + // will be made to bind to the new scorer. + bindToScoringServiceIfNeeded(); if (result) { // new scorer successfully set registerPackageReceiverIfNeeded(); + Intent intent = new Intent(NetworkScoreManager.ACTION_SCORER_CHANGED); if (prevScorer != null) { // Directly notify the old scorer. intent.setPackage(prevScorer.mPackageName); @@ -295,7 +357,6 @@ public class NetworkScoreService extends INetworkScoreService.Stub { return; } writer.println("Current scorer: " + currentScorer.mPackageName); - writer.flush(); for (INetworkScoreCache scoreCache : getScoreCaches()) { try { @@ -307,6 +368,12 @@ public class NetworkScoreService extends INetworkScoreService.Stub { } } } + if (mServiceConnection != null) { + mServiceConnection.dump(fd, writer, args); + } else { + writer.println("ScoringServiceConnection: null"); + } + writer.flush(); } /** @@ -320,4 +387,50 @@ public class NetworkScoreService extends INetworkScoreService.Stub { return new HashSet<>(mScoreCaches.values()); } } + + private static class ScoringServiceConnection implements ServiceConnection { + private final ComponentName mComponentName; + private boolean mBound = false; + + ScoringServiceConnection(ComponentName componentName) { + mComponentName = componentName; + } + + void connect(Context context) { + disconnect(context); + Intent service = new Intent(); + service.setComponent(mComponentName); + mBound = context.bindServiceAsUser(service, this, + Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE, + UserHandle.SYSTEM); + if (!mBound) { + Log.w(TAG, "Bind call failed for " + service); + } + } + + void disconnect(Context context) { + try { + if (mBound) { + mBound = false; + context.unbindService(this); + } + } catch (RuntimeException e) { + Log.e(TAG, "Unbind failed.", e); + } + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + if (DBG) Log.d(TAG, "ScoringServiceConnection: " + name.flattenToString()); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + if (DBG) Log.d(TAG, "ScoringServiceConnection, disconnected: " + name.flattenToString()); + } + + public void dump(FileDescriptor fd, PrintWriter writer, String[] args) { + writer.println("ScoringServiceConnection: " + mComponentName + ", bound: " + mBound); + } + } } diff --git a/services/core/java/com/android/server/UiThread.java b/services/core/java/com/android/server/UiThread.java index 0beb77fb4b92..c06afc2505ee 100644 --- a/services/core/java/com/android/server/UiThread.java +++ b/services/core/java/com/android/server/UiThread.java @@ -17,6 +17,7 @@ package com.android.server; import android.os.Handler; +import android.os.Trace; /** * Shared singleton thread for showing UI. This is a foreground thread, and in @@ -35,6 +36,7 @@ public final class UiThread extends ServiceThread { if (sInstance == null) { sInstance = new UiThread(); sInstance.start(); + sInstance.getLooper().setTraceTag(Trace.TRACE_TAG_ACTIVITY_MANAGER); sHandler = new Handler(sInstance.getLooper()); } } diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index d741c4948280..5d1cb8a08280 100755 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -343,6 +343,25 @@ public final class ActiveServices { return null; } + if (!r.startRequested) { + final long token = Binder.clearCallingIdentity(); + try { + // Before going further -- if this app is not allowed to run in the + // background, then at this point we aren't going to let it period. + final int allowed = mAm.checkAllowBackgroundLocked( + r.appInfo.uid, r.packageName, callingPid, true); + if (allowed != ActivityManager.APP_START_MODE_NORMAL) { + Slog.w(TAG, "Background start not allowed: service " + + service + " to " + r.name.flattenToShortString() + + " from pid=" + callingPid + " uid=" + callingUid + + " pkg=" + callingPackage); + return null; + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked( callingUid, r.packageName, service, service.getFlags(), null, r.userId); @@ -1274,23 +1293,6 @@ public final class ActiveServices { } r = smap.mServicesByName.get(name); if (r == null && createIfNeeded) { - final long token = Binder.clearCallingIdentity(); - try { - // Before going further -- if this app is not allowed to run in the - // background, then at this point we aren't going to let it period. - final int allowed = mAm.checkAllowBackgroundLocked( - sInfo.applicationInfo.uid, sInfo.packageName, callingPid, true); - if (allowed != ActivityManager.APP_START_MODE_NORMAL) { - Slog.w(TAG, "Background execution not allowed: service " - + service + " to " + name.flattenToShortString() - + " from pid=" + callingPid + " uid=" + callingUid - + " pkg=" + callingPackage); - return null; - } - } finally { - Binder.restoreCallingIdentity(token); - } - Intent.FilterComparison filter = new Intent.FilterComparison(service.cloneFilter()); ServiceRestarter res = new ServiceRestarter(); diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 82332208a3cd..4852788af3d1 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -1105,19 +1105,19 @@ public final class ActivityManagerService extends ActivityManagerNative ComponentName mTopComponent; String mTopAction = Intent.ACTION_MAIN; String mTopData; - boolean mProcessesReady = false; - boolean mSystemReady = false; - boolean mBooting = false; - boolean mCallFinishBooting = false; - boolean mBootAnimationComplete = false; - boolean mOnBattery = false; - boolean mLaunchWarningShown = false; - Context mContext; + volatile boolean mProcessesReady = false; + volatile boolean mSystemReady = false; + volatile boolean mOnBattery = false; + volatile int mFactoryTest; - int mFactoryTest; + @GuardedBy("this") boolean mBooting = false; + @GuardedBy("this") boolean mCallFinishBooting = false; + @GuardedBy("this") boolean mBootAnimationComplete = false; + @GuardedBy("this") boolean mLaunchWarningShown = false; + @GuardedBy("this") boolean mCheckedForSetup = false; - boolean mCheckedForSetup; + Context mContext; /** * The time at which we will allow normal application switches again, @@ -13227,10 +13227,11 @@ public final class ActivityManagerService extends ActivityManagerNative // Merge several logcat streams, and take the last N lines InputStreamReader input = null; try { - java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat", - "-v", "time", "-b", "events", "-b", "system", "-b", "main", - "-b", "crash", - "-t", String.valueOf(lines)).redirectErrorStream(true).start(); + java.lang.Process logcat = new ProcessBuilder( + "/system/bin/timeout", "-k", "15s", "10s", + "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system", + "-b", "main", "-b", "crash", "-t", String.valueOf(lines)) + .redirectErrorStream(true).start(); try { logcat.getOutputStream().close(); } catch (IOException e) {} try { logcat.getErrorStream().close(); } catch (IOException e) {} @@ -15456,8 +15457,9 @@ public final class ActivityManagerService extends ActivityManagerNative } for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { - if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex] - || oomIndex == (oomPss.length-1)) { + if (oomIndex == (oomPss.length - 1) + || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex] + && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) { oomPss[oomIndex] += myTotalPss; oomSwapPss[oomIndex] += myTotalSwapPss; if (oomProcs[oomIndex] == null) { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 811b48fc4fe5..7b2a37081103 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -1984,6 +1984,8 @@ public final class ActivityStackSupervisor implements DisplayListener { mTmpConfigs.clear(); mTmpInsetBounds.clear(); final ArrayList<TaskRecord> tasks = stack.getAllTasks(); + final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds; + final Rect insetBounds = tempTaskInsetBounds != null ? tempTaskInsetBounds : taskBounds; for (int i = tasks.size() - 1; i >= 0; i--) { final TaskRecord task = tasks.get(i); if (task.isResizeable()) { @@ -1995,9 +1997,7 @@ public final class ActivityStackSupervisor implements DisplayListener { fitWithinBounds(tempRect2, bounds); task.updateOverrideConfiguration(tempRect2); } else { - task.updateOverrideConfiguration( - tempTaskBounds != null ? tempTaskBounds : bounds, - tempTaskInsetBounds != null ? tempTaskInsetBounds : bounds); + task.updateOverrideConfiguration(taskBounds, insetBounds); } } @@ -2043,8 +2043,10 @@ public final class ActivityStackSupervisor implements DisplayListener { resizeStackUncheckedLocked(stack, dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds); - if (stack.mFullscreen) { - // The dock stack went fullscreen which is kinda like dismissing it. + // TODO: Checking for isAttached might not be needed as if the user passes in null + // dockedBounds then they want the docked stack to be dismissed. + if (stack.mFullscreen || (dockedBounds == null && !stack.isAttached())) { + // The dock stack either was dismissed or went fullscreen, which is kinda the same. // In this case we make all other static stacks fullscreen and move all // docked stack tasks to the fullscreen stack. for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { @@ -2072,13 +2074,10 @@ public final class ActivityStackSupervisor implements DisplayListener { mWindowManager.getStackDockedModeBounds( HOME_STACK_ID, tempRect, true /* ignoreVisibility */); for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) { - if (StackId.isResizeableByDockedStack(i)) { - ActivityStack otherStack = getStack(i); - if (otherStack != null) { - resizeStackLocked(i, tempRect, tempOtherTaskBounds, - tempOtherTaskInsetBounds, preserveWindows, - true /* allowResizeInDockedMode */); - } + if (StackId.isResizeableByDockedStack(i) && getStack(i) != null) { + resizeStackLocked(i, tempRect, tempOtherTaskBounds, + tempOtherTaskInsetBounds, preserveWindows, + true /* allowResizeInDockedMode */); } } } diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java index 6cd756186ab7..68bd2fd3ce3e 100644 --- a/services/core/java/com/android/server/am/AppErrors.java +++ b/services/core/java/com/android/server/am/AppErrors.java @@ -724,9 +724,7 @@ class AppErrors { final boolean crashSilenced = mAppsNotReportingCrashes != null && mAppsNotReportingCrashes.contains(proc.info.packageName); if (mService.canShowErrorDialogs() && !crashSilenced) { - Dialog d = new AppErrorDialog(mContext, mService, data); - d.show(); - proc.crashDialog = d; + proc.crashDialog = new AppErrorDialog(mContext, mService, data); } else { // The device is asleep, so just pretend that the user // saw a crash dialog and hit "force quit". @@ -735,6 +733,10 @@ class AppErrors { } } } + // If we've created a crash dialog, show it without the lock held + if(data.proc.crashDialog != null) { + data.proc.crashDialog.show(); + } } void stopReportingCrashesLocked(ProcessRecord proc) { @@ -924,6 +926,7 @@ class AppErrors { } void handleShowAnrUi(Message msg) { + Dialog d = null; synchronized (mService) { HashMap<String, Object> data = (HashMap<String, Object>) msg.obj; ProcessRecord proc = (ProcessRecord)data.get("app"); @@ -944,10 +947,9 @@ class AppErrors { null, false, false, MY_PID, Process.SYSTEM_UID, 0 /* TODO: Verify */); if (mService.canShowErrorDialogs()) { - Dialog d = new AppNotRespondingDialog(mService, + d = new AppNotRespondingDialog(mService, mContext, proc, (ActivityRecord)data.get("activity"), msg.arg1 != 0); - d.show(); proc.anrDialog = d; } else { MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_ANR, @@ -956,6 +958,10 @@ class AppErrors { mService.killAppAtUsersRequest(proc, null); } } + // If we've created a crash dialog, show it without the lock held + if (d != null) { + d.show(); + } } /** diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index aef454ee6357..e0a142befd2d 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -237,7 +237,13 @@ final class UserController { AppOpsManager.OP_NONE, null, true, false, MY_PID, SYSTEM_UID, userId); } - maybeUnlockUser(userId); + // We only attempt to unlock real users here; we delay unlocking + // profiles until after the parent user is unlocked. + if (getUserManager().isManagedProfile(userId)) { + Slog.d(TAG, "User " + userId + " is managed profile; delaying unlock attempt"); + } else { + maybeUnlockUser(userId); + } } } @@ -260,6 +266,9 @@ final class UserController { mUserManager.onBeforeUnlockUser(userId); progress.setProgress(20); + // Dispatch unlocked to system services + mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0)); + // Send PRE_BOOT broadcasts if fingerprint changed final UserInfo info = getUserInfo(userId); if (!Objects.equals(info.lastLoggedInFingerprint, Build.FINGERPRINT)) { @@ -302,9 +311,6 @@ final class UserController { // Remember that we logged in mUserManager.onUserLoggedIn(userId); - // Dispatch unlocked to system services - mHandler.sendMessage(mHandler.obtainMessage(SYSTEM_USER_UNLOCK_MSG, userId, 0)); - // Dispatch unlocked to external apps final Intent unlockedIntent = new Intent(Intent.ACTION_USER_UNLOCKED); unlockedIntent.putExtra(Intent.EXTRA_USER_HANDLE, userId); @@ -905,6 +911,20 @@ final class UserController { finishUserUnlocking(uss, progress); } + // We just unlocked a user, so let's now attempt to unlock any managed + // profiles under that user. + synchronized (mService) { + for (int i = 0; i < mStartedUsers.size(); i++) { + final int testUserId = mStartedUsers.keyAt(i); + final UserInfo parent = getUserManager().getProfileParent(testUserId); + if (parent != null && parent.id == userId && testUserId != userId) { + Slog.d(TAG, "Found user " + testUserId + " with parent " + userId + + "; attempting unlock"); + maybeUnlockUser(testUserId); + } + } + } + return true; } diff --git a/services/core/java/com/android/server/connectivity/MetricsLoggerService.java b/services/core/java/com/android/server/connectivity/MetricsLoggerService.java index 7cac2270950d..f91db7813d42 100644 --- a/services/core/java/com/android/server/connectivity/MetricsLoggerService.java +++ b/services/core/java/com/android/server/connectivity/MetricsLoggerService.java @@ -18,18 +18,21 @@ package com.android.server.connectivity; import com.android.server.SystemService; +import android.app.PendingIntent; import android.content.Context; +import android.content.pm.PackageManager; import android.net.ConnectivityMetricsEvent; import android.net.ConnectivityMetricsLogger; import android.net.IConnectivityMetricsLogger; -import android.net.IConnectivityMetricsLoggerSubscriber; -import android.os.IBinder; -import android.os.RemoteException; -import android.util.ArrayMap; +import android.os.Binder; +import android.os.Parcel; +import android.text.format.DateUtils; import android.util.Log; +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayDeque; import java.util.ArrayList; -import java.util.List; /** {@hide} */ public class MetricsLoggerService extends SystemService { @@ -43,134 +46,307 @@ public class MetricsLoggerService extends SystemService { @Override public void onStart() { + resetThrottlingCounters(System.currentTimeMillis()); } @Override public void onBootPhase(int phase) { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) { - Log.d(TAG, "onBootPhase: PHASE_SYSTEM_SERVICES_READY"); + if (DBG) Log.d(TAG, "onBootPhase: PHASE_SYSTEM_SERVICES_READY"); publishBinderService(ConnectivityMetricsLogger.CONNECTIVITY_METRICS_LOGGER_SERVICE, mBinder); } } - private final int MAX_NUMBER_OF_EVENTS = 100; - private final int MAX_TIME_OFFSET = 15*60*1000; // 15 minutes - private final List<ConnectivityMetricsEvent> mEvents = new ArrayList<>(); - private long mLastSentEventTimeMillis = System.currentTimeMillis(); + // TODO: read from system property + private final int MAX_NUMBER_OF_EVENTS = 1000; - private final void enforceConnectivityInternalPermission() { + // TODO: read from system property + private final int EVENTS_NOTIFICATION_THRESHOLD = 300; + + // TODO: read from system property + private final int THROTTLING_TIME_INTERVAL_MILLIS = 60 * 60 * 1000; // 1 hour + + // TODO: read from system property + private final int THROTTLING_MAX_NUMBER_OF_MESSAGES_PER_COMPONENT = 1000; + + private int mEventCounter = 0; + + /** + * Reference of the last event in the list of cached events. + * + * When client of this service retrieves events by calling getEvents, it is passing + * ConnectivityMetricsEvent.Reference object. After getEvents returns, that object will + * contain this reference. The client can save it and use next time it calls getEvents. + * This way only new events will be returned. + */ + private long mLastEventReference = 0; + + private final int mThrottlingCounters[] = + new int[ConnectivityMetricsLogger.NUMBER_OF_COMPONENTS]; + + private long mThrottlingIntervalBoundaryMillis; + + private final ArrayDeque<ConnectivityMetricsEvent> mEvents = new ArrayDeque<>(); + + private void enforceConnectivityInternalPermission() { getContext().enforceCallingOrSelfPermission( android.Manifest.permission.CONNECTIVITY_INTERNAL, "MetricsLoggerService"); } + private void enforceDumpPermission() { + getContext().enforceCallingOrSelfPermission( + android.Manifest.permission.DUMP, + "MetricsLoggerService"); + } + + private void resetThrottlingCounters(long currentTimeMillis) { + for (int i = 0; i < mThrottlingCounters.length; i++) { + mThrottlingCounters[i] = 0; + } + mThrottlingIntervalBoundaryMillis = + currentTimeMillis + THROTTLING_TIME_INTERVAL_MILLIS; + } + + private void addEvent(ConnectivityMetricsEvent e) { + if (VDBG) { + Log.v(TAG, "writeEvent(" + e.toString() + ")"); + } + + while (mEvents.size() >= MAX_NUMBER_OF_EVENTS) { + mEvents.removeFirst(); + } + + mEvents.addLast(e); + } + /** * Implementation of the IConnectivityMetricsLogger interface. */ private final IConnectivityMetricsLogger.Stub mBinder = new IConnectivityMetricsLogger.Stub() { - private final ArrayMap<IConnectivityMetricsLoggerSubscriber, - IBinder.DeathRecipient> mSubscribers = new ArrayMap<>(); - - - private ConnectivityMetricsEvent[] prepareEventsToSendIfReady() { - ConnectivityMetricsEvent[] eventsToSend = null; - final long currentTimeMillis = System.currentTimeMillis(); - final long timeOffset = currentTimeMillis - mLastSentEventTimeMillis; - if (timeOffset >= MAX_TIME_OFFSET - || timeOffset < 0 // system time has changed - || mEvents.size() >= MAX_NUMBER_OF_EVENTS) { - // batch events - mLastSentEventTimeMillis = currentTimeMillis; - eventsToSend = new ConnectivityMetricsEvent[mEvents.size()]; - mEvents.toArray(eventsToSend); - mEvents.clear(); + private final ArrayList<PendingIntent> mPendingIntents = new ArrayList<>(); + + @Override + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (getContext().checkCallingOrSelfPermission(android.Manifest.permission.DUMP) + != PackageManager.PERMISSION_GRANTED) { + pw.println("Permission Denial: can't dump ConnectivityMetricsLoggerService " + + "from from pid=" + Binder.getCallingPid() + ", uid=" + + Binder.getCallingUid()); + return; } - return eventsToSend; - } - private void maybeSendEventsToSubscribers(ConnectivityMetricsEvent[] eventsToSend) { - if (eventsToSend == null || eventsToSend.length == 0) return; - synchronized (mSubscribers) { - for (IConnectivityMetricsLoggerSubscriber s : mSubscribers.keySet()) { - try { - s.onEvents(eventsToSend); - } catch (RemoteException ex) { - Log.e(TAG, "RemoteException " + ex); + boolean dumpSerializedSize = false; + boolean dumpEvents = false; + for (String arg : args) { + switch (arg) { + case "--events": + dumpEvents = true; + break; + + case "--size": + dumpSerializedSize = true; + break; + + case "--all": + dumpEvents = true; + dumpSerializedSize = true; + break; + } + } + + synchronized (mEvents) { + pw.println("Number of events: " + mEvents.size()); + pw.println("Time span: " + + DateUtils.formatElapsedTime( + (System.currentTimeMillis() - mEvents.peekFirst().timestamp) + / 1000)); + + if (dumpSerializedSize) { + long dataSize = 0; + Parcel p = Parcel.obtain(); + for (ConnectivityMetricsEvent e : mEvents) { + dataSize += 16; // timestamp and 2 stamps + + p.writeParcelable(e.data, 0); + } + dataSize += p.dataSize(); + p.recycle(); + pw.println("Serialized data size: " + dataSize); + } + + if (dumpEvents) { + pw.println(); + pw.println("Events:"); + for (ConnectivityMetricsEvent e : mEvents) { + pw.println(e.toString()); } } } + + if (!mPendingIntents.isEmpty()) { + pw.println(); + pw.println("Pending intents:"); + for (PendingIntent pi : mPendingIntents) { + pw.println(pi.toString()); + } + } } - public void logEvent(ConnectivityMetricsEvent event) { + public long logEvent(ConnectivityMetricsEvent event) { ConnectivityMetricsEvent[] events = new ConnectivityMetricsEvent[]{event}; - logEvents(events); + return logEvents(events); } - public void logEvents(ConnectivityMetricsEvent[] events) { + /** + * @param events + * + * Note: All events must belong to the same component. + * + * @return 0 on success + * <0 if error happened + * >0 timestamp after which new events will be accepted + */ + public long logEvents(ConnectivityMetricsEvent[] events) { enforceConnectivityInternalPermission(); - ConnectivityMetricsEvent[] eventsToSend; - if (VDBG) { - for (ConnectivityMetricsEvent e : events) { - Log.v(TAG, "writeEvent(" + e.toString() + ")"); + if (events == null || events.length == 0) { + Log.wtf(TAG, "No events passed to logEvents()"); + return -1; + } + + int componentTag = events[0].componentTag; + if (componentTag < 0 || + componentTag >= ConnectivityMetricsLogger.NUMBER_OF_COMPONENTS) { + Log.wtf(TAG, "Unexpected tag: " + componentTag); + return -1; + } + + synchronized (mThrottlingCounters) { + long currentTimeMillis = System.currentTimeMillis(); + if (currentTimeMillis > mThrottlingIntervalBoundaryMillis) { + resetThrottlingCounters(currentTimeMillis); + } + + mThrottlingCounters[componentTag] += events.length; + + if (mThrottlingCounters[componentTag] > + THROTTLING_MAX_NUMBER_OF_MESSAGES_PER_COMPONENT) { + Log.w(TAG, "Too many events from #" + componentTag + + ". Block until " + mThrottlingIntervalBoundaryMillis); + + return mThrottlingIntervalBoundaryMillis; } } + boolean sendPendingIntents = false; + synchronized (mEvents) { for (ConnectivityMetricsEvent e : events) { - mEvents.add(e); + if (e.componentTag != componentTag) { + Log.wtf(TAG, "Unexpected tag: " + e.componentTag); + return -1; + } + + addEvent(e); } - eventsToSend = prepareEventsToSendIfReady(); + mLastEventReference += events.length; + + mEventCounter += events.length; + if (mEventCounter >= EVENTS_NOTIFICATION_THRESHOLD) { + mEventCounter = 0; + sendPendingIntents = true; + } + } + + if (sendPendingIntents) { + synchronized (mPendingIntents) { + for (PendingIntent pi : mPendingIntents) { + if (VDBG) Log.v(TAG, "Send pending intent"); + try { + pi.send(getContext(), 0, null, null, null); + } catch (PendingIntent.CanceledException e) { + Log.e(TAG, "Pending intent canceled: " + pi); + mPendingIntents.remove(pi); + } + } + } } - maybeSendEventsToSubscribers(eventsToSend); + return 0; } - public boolean subscribe(IConnectivityMetricsLoggerSubscriber subscriber) { - enforceConnectivityInternalPermission(); - if (VDBG) Log.v(TAG, "subscribe"); + /** + * Retrieve events + * + * @param reference of the last event previously returned. The function will return + * events following it. + * If 0 then all events will be returned. + * After the function call it will contain reference of the + * last returned event. + * @return events + */ + public ConnectivityMetricsEvent[] getEvents(ConnectivityMetricsEvent.Reference reference) { + enforceDumpPermission(); + long ref = reference.value; + if (VDBG) Log.v(TAG, "getEvents(" + ref + ")"); - synchronized (mSubscribers) { - if (mSubscribers.containsKey(subscriber)) { - Log.e(TAG, "subscriber is already subscribed"); - return false; + ConnectivityMetricsEvent[] result; + synchronized (mEvents) { + if (ref > mLastEventReference) { + Log.e(TAG, "Invalid reference"); + reference.value = mLastEventReference; + return null; } - final IConnectivityMetricsLoggerSubscriber s = subscriber; - IBinder.DeathRecipient dr = new IBinder.DeathRecipient() { - @Override - public void binderDied() { - if (VDBG) Log.v(TAG, "subscriber died"); - synchronized (mSubscribers) { - mSubscribers.remove(s); - } + if (ref < mLastEventReference - mEvents.size()) { + ref = mLastEventReference - mEvents.size(); + } + + int numEventsToSkip = + mEvents.size() // Total number of events + - (int)(mLastEventReference - ref); // Number of events to return + + result = new ConnectivityMetricsEvent[mEvents.size() - numEventsToSkip]; + int i = 0; + for (ConnectivityMetricsEvent e : mEvents) { + if (numEventsToSkip > 0) { + numEventsToSkip--; + } else { + result[i++] = e; } - }; - - try { - subscriber.asBinder().linkToDeath(dr, 0); - mSubscribers.put(subscriber, dr); - } catch (RemoteException e) { - Log.e(TAG, "subscribe failed: " + e); - return false; } } + reference.value = mLastEventReference; + + return result; + } + + public boolean register(PendingIntent newEventsIntent) { + enforceDumpPermission(); + if (VDBG) Log.v(TAG, "register(" + newEventsIntent + ")"); + + synchronized (mPendingIntents) { + if (mPendingIntents.remove(newEventsIntent)) { + Log.w(TAG, "Replacing registered pending intent"); + } + mPendingIntents.add(newEventsIntent); + } + return true; } - public void unsubscribe(IConnectivityMetricsLoggerSubscriber subscriber) { - enforceConnectivityInternalPermission(); - if (VDBG) Log.v(TAG, "unsubscribe"); - synchronized (mSubscribers) { - IBinder.DeathRecipient dr = mSubscribers.remove(subscriber); - if (dr == null) { - Log.e(TAG, "subscriber is not subscribed"); - return; + public void unregister(PendingIntent newEventsIntent) { + enforceDumpPermission(); + if (VDBG) Log.v(TAG, "unregister(" + newEventsIntent + ")"); + + synchronized (mPendingIntents) { + if (!mPendingIntents.remove(newEventsIntent)) { + Log.e(TAG, "Pending intent is not registered"); } - subscriber.asBinder().unlinkToDeath(dr, 0); } } }; diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java index d10df02a3f2f..2cba93fdab90 100644 --- a/services/core/java/com/android/server/connectivity/Tethering.java +++ b/services/core/java/com/android/server/connectivity/Tethering.java @@ -1211,6 +1211,11 @@ public class Tethering extends BaseNetworkObserver { Log.e(TAG, "Error Tethering: " + e.toString()); setLastError(ConnectivityManager.TETHER_ERROR_TETHER_IFACE_ERROR); + try { + mNMService.untetherInterface(mIfaceName); + } catch (Exception ee) { + Log.e(TAG, "Error untethering after failure!" + ee.toString()); + } transitionTo(mInitialState); return; } diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index 3b0b79a771ef..a111bf925181 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -264,7 +264,12 @@ public class Vpn { return true; } - // Check if the caller is authorized. + // Stop an existing always-on VPN from being dethroned by other apps. + if (getAlwaysOnPackage() != null) { + return false; + } + + // Check that the caller is authorized. enforceControlPermission(); prepareInternal(newPackage); diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index 7f7ea9d8060c..6e7ea9925f91 100644 --- a/services/core/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java @@ -42,10 +42,10 @@ import android.database.sqlite.SQLiteException; import android.net.Uri; import android.os.Binder; import android.os.Bundle; +import android.os.FactoryTest; import android.os.IBinder; import android.os.Parcel; import android.os.RemoteException; -import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; import android.text.TextUtils; @@ -59,6 +59,7 @@ import android.util.SparseIntArray; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.IndentingPrintWriter; import com.android.server.LocalServices; +import com.android.server.SystemService; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -72,7 +73,31 @@ import java.util.List; * {@hide} */ public final class ContentService extends IContentService.Stub { - private static final String TAG = "ContentService"; + static final String TAG = "ContentService"; + static final boolean DEBUG = false; + + public static class Lifecycle extends SystemService { + private ContentService mContentService; + + public Lifecycle(Context context) { + super(context); + } + + @Override + public void onStart() { + final boolean factoryTest = (FactoryTest + .getMode() == FactoryTest.FACTORY_TEST_LOW_LEVEL); + mContentService = new ContentService(getContext(), factoryTest); + publishBinderService(ContentResolver.CONTENT_SERVICE_NAME, mContentService); + } + + @Override + public void onCleanupUser(int userHandle) { + synchronized (mContentService.mCache) { + mContentService.mCache.remove(userHandle); + } + } + } private Context mContext; private boolean mFactoryTest; @@ -94,12 +119,18 @@ public final class ContentService extends IContentService.Stub { private BroadcastReceiver mCacheReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - final Uri data = intent.getData(); - if (data != null) { - final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, - UserHandle.USER_NULL); - final String packageName = data.getSchemeSpecificPart(); - invalidateCacheLocked(userId, packageName, null); + synchronized (mCache) { + if (Intent.ACTION_LOCALE_CHANGED.equals(intent.getAction())) { + mCache.clear(); + } else { + final Uri data = intent.getData(); + if (data != null) { + final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + UserHandle.USER_NULL); + final String packageName = data.getSchemeSpecificPart(); + invalidateCacheLocked(userId, packageName, null); + } + } } } }; @@ -227,6 +258,11 @@ public final class ContentService extends IContentService.Stub { packageFilter.addDataScheme("package"); mContext.registerReceiverAsUser(mCacheReceiver, UserHandle.ALL, packageFilter, null, null); + + final IntentFilter localeFilter = new IntentFilter(); + localeFilter.addAction(Intent.ACTION_LOCALE_CHANGED); + mContext.registerReceiverAsUser(mCacheReceiver, UserHandle.ALL, + localeFilter, null, null); } public void systemReady() { @@ -304,12 +340,10 @@ public final class ContentService extends IContentService.Stub { */ @Override public void notifyChange(Uri uri, IContentObserver observer, - boolean observerWantsSelfNotifications, boolean syncToNetwork, + boolean observerWantsSelfNotifications, int flags, int userHandle) { - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "Notifying update of " + uri + " for user " + userHandle - + " from observer " + observer + ", syncToNetwork " + syncToNetwork); - } + if (DEBUG) Slog.d(TAG, "Notifying update of " + uri + " for user " + userHandle + + " from observer " + observer + ", flags " + Integer.toHexString(flags)); final int uid = Binder.getCallingUid(); final int pid = Binder.getCallingPid(); @@ -338,16 +372,15 @@ public final class ContentService extends IContentService.Stub { ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>(); synchronized (mRootNode) { mRootNode.collectObserversLocked(uri, 0, observer, observerWantsSelfNotifications, - userHandle, calls); + flags, userHandle, calls); } final int numCalls = calls.size(); for (int i=0; i<numCalls; i++) { ObserverCall oc = calls.get(i); try { oc.mObserver.onChange(oc.mSelfChange, uri, userHandle); - if (Log.isLoggable(TAG, Log.VERBOSE)) { - Log.v(TAG, "Notified " + oc.mObserver + " of " + "update at " + uri); - } + if (DEBUG) Slog.d(TAG, "Notified " + oc.mObserver + " of " + "update at " + + uri); } catch (RemoteException ex) { synchronized (mRootNode) { Log.w(TAG, "Found dead observer, removing"); @@ -366,7 +399,7 @@ public final class ContentService extends IContentService.Stub { } } } - if (syncToNetwork) { + if ((flags&ContentResolver.NOTIFY_SYNC_TO_NETWORK) != 0) { SyncManager syncManager = getSyncManager(); if (syncManager != null) { syncManager.scheduleLocalSync(null /* all accounts */, callingUserHandle, uid, @@ -385,7 +418,8 @@ public final class ContentService extends IContentService.Stub { public void notifyChange(Uri uri, IContentObserver observer, boolean observerWantsSelfNotifications, boolean syncToNetwork) { - notifyChange(uri, observer, observerWantsSelfNotifications, syncToNetwork, + notifyChange(uri, observer, observerWantsSelfNotifications, + syncToNetwork ? ContentResolver.NOTIFY_SYNC_TO_NETWORK : 0, UserHandle.getCallingUserId()); } @@ -1029,14 +1063,14 @@ public final class ContentService extends IContentService.Stub { for (int i = 0; i < packageCache.size();) { final Pair<String, Uri> key = packageCache.keyAt(i); if (key.second != null && key.second.toString().startsWith(uri.toString())) { - Slog.d(TAG, "Invalidating cache for key " + key); + if (DEBUG) Slog.d(TAG, "Invalidating cache for key " + key); packageCache.removeAt(i); } else { i++; } } } else { - Slog.d(TAG, "Invalidating cache for package " + providerPackageName); + if (DEBUG) Slog.d(TAG, "Invalidating cache for package " + providerPackageName); packageCache.clear(); } } @@ -1080,12 +1114,6 @@ public final class ContentService extends IContentService.Stub { } } - public static ContentService main(Context context, boolean factoryTest) { - ContentService service = new ContentService(context, factoryTest); - ServiceManager.addService(ContentResolver.CONTENT_SERVICE_NAME, service); - return service; - } - /** * Checks if the request is from the system or an app that has INTERACT_ACROSS_USERS_FULL * permission, if the userHandle is not for the caller. @@ -1281,8 +1309,8 @@ public final class ContentService extends IContentService.Stub { } private void collectMyObserversLocked(boolean leaf, IContentObserver observer, - boolean observerWantsSelfNotifications, int targetUserHandle, - ArrayList<ObserverCall> calls) { + boolean observerWantsSelfNotifications, int flags, + int targetUserHandle, ArrayList<ObserverCall> calls) { int N = mObservers.size(); IBinder observerBinder = observer == null ? null : observer.asBinder(); for (int i = 0; i < N; i++) { @@ -1300,9 +1328,29 @@ public final class ContentService extends IContentService.Stub { || entry.userHandle == UserHandle.USER_ALL || targetUserHandle == entry.userHandle) { // Make sure the observer is interested in the notification - if (leaf || (!leaf && entry.notifyForDescendants)) { - calls.add(new ObserverCall(this, entry.observer, selfChange)); + if (leaf) { + // If we are at the leaf: we always report, unless the sender has asked + // to skip observers that are notifying for descendants (since they will + // be sending another more specific URI for them). + if ((flags&ContentResolver.NOTIFY_SKIP_NOTIFY_FOR_DESCENDANTS) != 0 + && entry.notifyForDescendants) { + if (DEBUG) Slog.d(TAG, "Skipping " + entry.observer + + ": skip notify for descendants"); + continue; + } + } else { + // If we are not at the leaf: we report if the observer says it wants + // to be notified for all descendants. + if (!entry.notifyForDescendants) { + if (DEBUG) Slog.d(TAG, "Skipping " + entry.observer + + ": not monitor descendants"); + continue; + } } + if (DEBUG) Slog.d(TAG, "Reporting to " + entry.observer + ": leaf=" + leaf + + " flags=" + Integer.toHexString(flags) + + " desc=" + entry.notifyForDescendants); + calls.add(new ObserverCall(this, entry.observer, selfChange)); } } } @@ -1311,19 +1359,22 @@ public final class ContentService extends IContentService.Stub { * targetUserHandle is either a hard user handle or is USER_ALL */ public void collectObserversLocked(Uri uri, int index, IContentObserver observer, - boolean observerWantsSelfNotifications, int targetUserHandle, - ArrayList<ObserverCall> calls) { + boolean observerWantsSelfNotifications, int flags, + int targetUserHandle, ArrayList<ObserverCall> calls) { String segment = null; int segmentCount = countUriSegments(uri); if (index >= segmentCount) { // This is the leaf node, notify all observers + if (DEBUG) Slog.d(TAG, "Collecting leaf observers @ #" + index + ", node " + mName); collectMyObserversLocked(true, observer, observerWantsSelfNotifications, - targetUserHandle, calls); + flags, targetUserHandle, calls); } else if (index < segmentCount){ segment = getUriSegment(uri, index); + if (DEBUG) Slog.d(TAG, "Collecting non-leaf observers @ #" + index + " / " + + segment); // Notify any observers at this level who are interested in descendants collectMyObserversLocked(false, observer, observerWantsSelfNotifications, - targetUserHandle, calls); + flags, targetUserHandle, calls); } int N = mChildren.size(); @@ -1331,8 +1382,8 @@ public final class ContentService extends IContentService.Stub { ObserverNode node = mChildren.get(i); if (segment == null || node.mName.equals(segment)) { // We found the child, - node.collectObserversLocked(uri, index + 1, - observer, observerWantsSelfNotifications, targetUserHandle, calls); + node.collectObserversLocked(uri, index + 1, observer, + observerWantsSelfNotifications, flags, targetUserHandle, calls); if (segment != null) { break; } diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index e5342ceec1dc..db41a54f1a0a 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -1402,12 +1402,24 @@ public class SyncManager { } } + private void restoreLostPeriodicSyncsIfNeeded(int userId) { + List<SyncOperation> periodicSyncs = new ArrayList<SyncOperation>(); + for (SyncOperation sync : getAllPendingSyncs()) { + if (sync.isPeriodic && sync.target.userId == userId) { + periodicSyncs.add(sync); + } + } + mSyncStorageEngine.restorePeriodicSyncsIfNeededForUser(userId, periodicSyncs); + } + private void onUserUnlocked(int userId) { // Make sure that accounts we're about to use are valid. AccountManagerService.getSingleton().validateAccounts(userId); mSyncAdapters.invalidateCache(userId); + restoreLostPeriodicSyncsIfNeeded(userId); + EndPoint target = new EndPoint(null, null, userId); updateRunningAccounts(target); @@ -2578,9 +2590,11 @@ public class SyncManager { } } + // Cancel all jobs from non-existent accounts. + AccountAndUser[] allAccounts = AccountManagerService.getSingleton().getAllAccounts(); List<SyncOperation> ops = getAllPendingSyncs(); for (SyncOperation op: ops) { - if (!containsAccountAndUser(accounts, op.target.account, op.target.userId)) { + if (!containsAccountAndUser(allAccounts, op.target.account, op.target.userId)) { getJobScheduler().cancel(op.jobId); } } diff --git a/services/core/java/com/android/server/content/SyncStorageEngine.java b/services/core/java/com/android/server/content/SyncStorageEngine.java index bc3fc6a47aef..fb23265c2189 100644 --- a/services/core/java/com/android/server/content/SyncStorageEngine.java +++ b/services/core/java/com/android/server/content/SyncStorageEngine.java @@ -826,6 +826,35 @@ public class SyncStorageEngine extends Handler { return true; } + /** + * STOPSHIP This is a temporary workaround and should be removed before shipping: b/28052438 + */ + void restorePeriodicSyncsIfNeededForUser(int userHandle, List<SyncOperation> periodicSyncs) { + if (mPeriodicSyncAddedListener == null) { + return; + } + synchronized (mAuthorities) { + for (int i = 0; i < mAuthorities.size(); i++) { + AuthorityInfo authority = mAuthorities.valueAt(i); + if (authority.target.userId == userHandle && authority.enabled) { + boolean periodicSyncAlreadyExists = false; + for (SyncOperation sync : periodicSyncs) { + if (authority.target.matchesSpec(sync.target)) { + periodicSyncAlreadyExists = true; + break; + } + } + // The periodic sync must have been lost due to previous bug. + if (!periodicSyncAlreadyExists) { + mPeriodicSyncAddedListener.onPeriodicSyncAdded(authority.target, + new Bundle(), DEFAULT_POLL_FREQUENCY_SECONDS, + calculateDefaultFlexTime(DEFAULT_POLL_FREQUENCY_SECONDS)); + } + } + } + } + } + public void setMasterSyncAutomatically(boolean flag, int userId) { synchronized (mAuthorities) { Boolean auto = mMasterSyncAutomatically.get(userId); diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java index 7b134cab2b95..3d8bf5126638 100644 --- a/services/core/java/com/android/server/fingerprint/FingerprintService.java +++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java @@ -107,6 +107,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe private static final int FINGERPRINT_ACQUIRED_GOOD = 0; private final String mKeyguardPackage; private int mCurrentUserId = UserHandle.USER_CURRENT; + private int mUserIdForRemove = UserHandle.USER_NULL; Handler mHandler = new Handler() { @Override @@ -205,10 +206,12 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe protected void handleRemoved(long deviceId, int fingerId, int groupId) { final ClientMonitor client = mRemoveClient; if (fingerId != 0) { - removeTemplateForUser(mRemoveClient, fingerId); + removeTemplateForUser(mUserIdForRemove, fingerId); + } else { + mUserIdForRemove = UserHandle.USER_NULL; } if (client != null && client.sendRemoved(fingerId, groupId)) { - removeClient(mRemoveClient); + removeClient(client); } } @@ -325,8 +328,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe return false; } - private void removeTemplateForUser(ClientMonitor clientMonitor, int fingerId) { - mFingerprintUtils.removeFingerprintIdForUser(mContext, fingerId, clientMonitor.userId); + private void removeTemplateForUser(int userId, int fingerId) { + mFingerprintUtils.removeFingerprintIdForUser(mContext, fingerId, userId); } private void addTemplateForUser(ClientMonitor clientMonitor, int fingerId) { @@ -488,6 +491,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe stopPendingOperations(true); mRemoveClient = new ClientMonitor(token, receiver, userId, restricted, token.toString()); + mUserIdForRemove = mCurrentUserId; // The fingerprint template ids will be removed when we get confirmation from the HAL try { final int result = daemon.remove(fingerId, userId); @@ -943,10 +947,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe if (DEBUG) Slog.v(TAG, "authenticate(): reject " + opPackageName); return; } - - // Group ID is arbitrarily set to parent profile user ID. It just represents - // the default fingerprints for the user. - final int effectiveGroupId = getEffectiveUserId(groupId); final int realUserId = Binder.getCallingUid(); final boolean restricted = isRestricted(); @@ -954,7 +954,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe @Override public void run() { MetricsLogger.histogram(mContext, "fingerprint_token", opId != 0L ? 1 : 0); - startAuthentication(token, opId, realUserId, effectiveGroupId, receiver, + startAuthentication(token, opId, realUserId, groupId, receiver, flags, restricted, opPackageName); } }); @@ -989,14 +989,10 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe final IFingerprintServiceReceiver receiver) { checkPermission(MANAGE_FINGERPRINT); // TODO: Maybe have another permission final boolean restricted = isRestricted(); - - // Group ID is arbitrarily set to parent profile user ID. It just represents - // the default fingerprints for the user. - final int effectiveGroupId = getEffectiveUserId(groupId); mHandler.post(new Runnable() { @Override public void run() { - startRemove(token, fingerId, effectiveGroupId, receiver, restricted); + startRemove(token, fingerId, groupId, receiver, restricted); } }); diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java index a36e6710887e..69c012e3893d 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java @@ -165,15 +165,13 @@ final class HdmiCecLocalDevicePlayback extends HdmiCecLocalDevice { @ServiceThreadOnly protected void onStandby(boolean initiatedByCec, int standbyAction) { assertRunOnServiceThread(); - if (!mService.isControlEnabled() || initiatedByCec) { + if (!mService.isControlEnabled() || initiatedByCec || !mAutoTvOff) { return; } switch (standbyAction) { case HdmiControlService.STANDBY_SCREEN_OFF: - if (mAutoTvOff) { - mService.sendCecCommand( - HdmiCecMessageBuilder.buildStandby(mAddress, Constants.ADDR_TV)); - } + mService.sendCecCommand( + HdmiCecMessageBuilder.buildStandby(mAddress, Constants.ADDR_TV)); break; case HdmiControlService.STANDBY_SHUTDOWN: // ACTION_SHUTDOWN is taken as a signal to power off all the devices. diff --git a/services/core/java/com/android/server/hdmi/HdmiLogger.java b/services/core/java/com/android/server/hdmi/HdmiLogger.java index 0b2017104358..537df815e3a2 100644 --- a/services/core/java/com/android/server/hdmi/HdmiLogger.java +++ b/services/core/java/com/android/server/hdmi/HdmiLogger.java @@ -21,6 +21,7 @@ import android.os.Build; import android.os.SystemClock; import android.util.Pair; import android.util.Slog; +import android.util.Log; import java.util.HashMap; @@ -42,6 +43,7 @@ final class HdmiLogger { // Logging duration for same error message. private static final long ERROR_LOG_DURATTION_MILLIS = 20 * 1000; // 20s + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); private static final ThreadLocal<HdmiLogger> sLogger = new ThreadLocal<>(); @@ -83,10 +85,9 @@ final class HdmiLogger { } private void debugInternal(String logMessage) { - if (true || IS_USER_BUILD) { - return; + if (DEBUG) { + Slog.d(TAG, logMessage); } - Slog.d(TAG, logMessage); } private static final String toLogString(String logMessage, Object[] objs) { diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java index e73beaab6f0b..c7c765bb431e 100644 --- a/services/core/java/com/android/server/input/InputManagerService.java +++ b/services/core/java/com/android/server/input/InputManagerService.java @@ -200,6 +200,7 @@ public class InputManagerService extends IInputManager.Stub private static native int nativeInjectInputEvent(long ptr, InputEvent event, int displayId, int injectorPid, int injectorUid, int syncMode, int timeoutMillis, int policyFlags); + private static native void nativeToggleCapsLock(long ptr, int deviceId); private static native void nativeSetInputWindows(long ptr, InputWindowHandle[] windowHandles); private static native void nativeSetInputDispatchMode(long ptr, boolean enabled, boolean frozen); private static native void nativeSetSystemUiVisibility(long ptr, int visibility); @@ -2279,5 +2280,10 @@ public class InputManagerService extends IInputManager.Stub mHandler.obtainMessage(MSG_INPUT_METHOD_SUBTYPE_CHANGED, userId, 0, someArgs) .sendToTarget(); } + + @Override + public void toggleCapsLock(int deviceId) { + nativeToggleCapsLock(mPtr, deviceId); + } } } diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java index fa8620f20a8f..b2350025152f 100644 --- a/services/core/java/com/android/server/job/JobSchedulerService.java +++ b/services/core/java/com/android/server/job/JobSchedulerService.java @@ -304,7 +304,7 @@ public final class JobSchedulerService extends com.android.server.SystemService toCancel = mJobs.getJobByUidAndJobId(uId, job.getId()); if (toCancel != null) { - cancelJobImpl(toCancel); + cancelJobImpl(toCancel, jobStatus); } startTrackingJob(jobStatus, toCancel); } @@ -331,7 +331,7 @@ public final class JobSchedulerService extends com.android.server.SystemService } for (int i=0; i<jobsForUser.size(); i++) { JobStatus toRemove = jobsForUser.get(i); - cancelJobImpl(toRemove); + cancelJobImpl(toRemove, null); } } @@ -360,7 +360,7 @@ public final class JobSchedulerService extends com.android.server.SystemService } catch (RemoteException e) { } } - cancelJobImpl(toRemove); + cancelJobImpl(toRemove, null); } } @@ -377,13 +377,13 @@ public final class JobSchedulerService extends com.android.server.SystemService toCancel = mJobs.getJobByUidAndJobId(uid, jobId); } if (toCancel != null) { - cancelJobImpl(toCancel); + cancelJobImpl(toCancel, null); } } - private void cancelJobImpl(JobStatus cancelled) { + private void cancelJobImpl(JobStatus cancelled, JobStatus incomingJob) { if (DEBUG) Slog.d(TAG, "CANCEL: " + cancelled.toShortString()); - stopTrackingJob(cancelled, true /* writeBack */); + stopTrackingJob(cancelled, incomingJob, true /* writeBack */); synchronized (mLock) { // Remove from pending queue. mPendingJobs.remove(cancelled); @@ -549,7 +549,7 @@ public final class JobSchedulerService extends com.android.server.SystemService for (int i = 0; i < mControllers.size(); i++) { StateController controller = mControllers.get(i); if (update) { - controller.maybeStopTrackingJobLocked(jobStatus, true); + controller.maybeStopTrackingJobLocked(jobStatus, null, true); } controller.maybeStartTrackingJobLocked(jobStatus, lastJob); } @@ -561,14 +561,15 @@ public final class JobSchedulerService extends com.android.server.SystemService * Called when we want to remove a JobStatus object that we've finished executing. Returns the * object removed. */ - private boolean stopTrackingJob(JobStatus jobStatus, boolean writeBack) { + private boolean stopTrackingJob(JobStatus jobStatus, JobStatus incomingJob, + boolean writeBack) { synchronized (mLock) { // Remove from store as well as controllers. final boolean removed = mJobs.remove(jobStatus, writeBack); if (removed && mReadyToRock) { for (int i=0; i<mControllers.size(); i++) { StateController controller = mControllers.get(i); - controller.maybeStopTrackingJobLocked(jobStatus, false); + controller.maybeStopTrackingJobLocked(jobStatus, incomingJob, false); } } return removed; @@ -696,7 +697,7 @@ public final class JobSchedulerService extends com.android.server.SystemService } // Do not write back immediately if this is a periodic job. The job may get lost if system // shuts down before it is added back. - if (!stopTrackingJob(jobStatus, !jobStatus.getJob().isPeriodic())) { + if (!stopTrackingJob(jobStatus, null, !jobStatus.getJob().isPeriodic())) { if (DEBUG) { Slog.d(TAG, "Could not find job to remove. Was job removed while executing?"); } @@ -780,7 +781,7 @@ public final class JobSchedulerService extends com.android.server.SystemService } break; case MSG_STOP_JOB: - cancelJobImpl((JobStatus)message.obj); + cancelJobImpl((JobStatus)message.obj, null); break; } maybeRunPendingJobsH(); diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java index 2114fc3b07c8..d8490d4de516 100644 --- a/services/core/java/com/android/server/job/controllers/AppIdleController.java +++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java @@ -77,7 +77,7 @@ public class AppIdleController extends StateController { } @Override - public void maybeStopTrackingJobLocked(JobStatus jobStatus, boolean forUpdate) { + public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob, boolean forUpdate) { mTrackedTasks.remove(jobStatus); } diff --git a/services/core/java/com/android/server/job/controllers/BatteryController.java b/services/core/java/com/android/server/job/controllers/BatteryController.java index ac9f42520195..077236443dea 100644 --- a/services/core/java/com/android/server/job/controllers/BatteryController.java +++ b/services/core/java/com/android/server/job/controllers/BatteryController.java @@ -87,7 +87,7 @@ public class BatteryController extends StateController { } @Override - public void maybeStopTrackingJobLocked(JobStatus taskStatus, boolean forUpdate) { + public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob, boolean forUpdate) { if (taskStatus.hasChargingConstraint()) { mTrackedTasks.remove(taskStatus); } diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java index 6ef425a57877..5ad8189da054 100644 --- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java +++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java @@ -92,7 +92,7 @@ public class ConnectivityController extends StateController implements } @Override - public void maybeStopTrackingJobLocked(JobStatus jobStatus, boolean forUpdate) { + public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob, boolean forUpdate) { if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()) { mTrackedJobs.remove(jobStatus); } diff --git a/services/core/java/com/android/server/job/controllers/ContentObserverController.java b/services/core/java/com/android/server/job/controllers/ContentObserverController.java index c5cf30f4739d..b2f1958bac83 100644 --- a/services/core/java/com/android/server/job/controllers/ContentObserverController.java +++ b/services/core/java/com/android/server/job/controllers/ContentObserverController.java @@ -84,17 +84,8 @@ public class ContentObserverController extends StateController { boolean havePendingUris = false; // If there is a previous job associated with the new job, propagate over // any pending content URI trigger reports. - if (lastJob != null && lastJob.contentObserverJobInstance != null - && lastJob.contentObserverJobInstance - != taskStatus.contentObserverJobInstance - && lastJob.contentObserverJobInstance.mChangedAuthorities != null) { + if (taskStatus.contentObserverJobInstance.mChangedAuthorities != null) { havePendingUris = true; - taskStatus.contentObserverJobInstance.mChangedAuthorities - = lastJob.contentObserverJobInstance.mChangedAuthorities; - taskStatus.contentObserverJobInstance.mChangedUris - = lastJob.contentObserverJobInstance.mChangedUris; - lastJob.contentObserverJobInstance.mChangedAuthorities = null; - lastJob.contentObserverJobInstance.mChangedUris = null; } // If we have previously reported changed authorities/uris, then we failed // to complete the job with them so will re-record them to report again. @@ -138,15 +129,34 @@ public class ContentObserverController extends StateController { } @Override - public void maybeStopTrackingJobLocked(JobStatus taskStatus, boolean forUpdate) { + public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob, + boolean forUpdate) { if (taskStatus.hasContentTriggerConstraint()) { - if (!forUpdate) { - // We won't do this reset if being called for an update, because - // we know it will be immediately followed by maybeStartTrackingJobLocked... - // and we don't want to lose any content changes in-between. - if (taskStatus.contentObserverJobInstance != null) { - taskStatus.contentObserverJobInstance.detach(); - taskStatus.contentObserverJobInstance = null; + if (taskStatus.contentObserverJobInstance != null) { + if (incomingJob != null && taskStatus.contentObserverJobInstance != null + && taskStatus.contentObserverJobInstance.mChangedAuthorities != null) { + // We are stopping this job, but it is going to be replaced by this given + // incoming job. We want to propagate our state over to it, so we don't + // lose any content changes that had happend since the last one started. + // If there is a previous job associated with the new job, propagate over + // any pending content URI trigger reports. + if (incomingJob.contentObserverJobInstance == null) { + incomingJob.contentObserverJobInstance = new JobInstance(incomingJob); + } + incomingJob.contentObserverJobInstance.mChangedAuthorities + = taskStatus.contentObserverJobInstance.mChangedAuthorities; + incomingJob.contentObserverJobInstance.mChangedUris + = taskStatus.contentObserverJobInstance.mChangedUris; + taskStatus.contentObserverJobInstance.mChangedAuthorities = null; + taskStatus.contentObserverJobInstance.mChangedUris = null; + } else { + // We won't do this reset if being called for an update, because + // we know it will be immediately followed by maybeStartTrackingJobLocked... + // and we don't want to lose any content changes in-between. + if (taskStatus.contentObserverJobInstance != null) { + taskStatus.contentObserverJobInstance.detach(); + taskStatus.contentObserverJobInstance = null; + } } } mTrackedTasks.remove(taskStatus); diff --git a/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java b/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java index d2ef6a2e5aa2..64887e8d394d 100644 --- a/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java +++ b/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java @@ -166,7 +166,7 @@ public class DeviceIdleJobsController extends StateController { } @Override - public void maybeStopTrackingJobLocked(JobStatus jobStatus, boolean forUpdate) { + public void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob, boolean forUpdate) { mTrackedTasks.remove(jobStatus); } diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java index d9eb45c6026d..50aa88257ace 100644 --- a/services/core/java/com/android/server/job/controllers/IdleController.java +++ b/services/core/java/com/android/server/job/controllers/IdleController.java @@ -75,7 +75,7 @@ public class IdleController extends StateController { } @Override - public void maybeStopTrackingJobLocked(JobStatus taskStatus, boolean forUpdate) { + public void maybeStopTrackingJobLocked(JobStatus taskStatus, JobStatus incomingJob, boolean forUpdate) { mTrackedTasks.remove(taskStatus); } diff --git a/services/core/java/com/android/server/job/controllers/StateController.java b/services/core/java/com/android/server/job/controllers/StateController.java index ac7f4c3f4756..013903939f18 100644 --- a/services/core/java/com/android/server/job/controllers/StateController.java +++ b/services/core/java/com/android/server/job/controllers/StateController.java @@ -56,7 +56,8 @@ public abstract class StateController { /** * Remove task - this will happen if the task is cancelled, completed, etc. */ - public abstract void maybeStopTrackingJobLocked(JobStatus jobStatus, boolean forUpdate); + public abstract void maybeStopTrackingJobLocked(JobStatus jobStatus, JobStatus incomingJob, + boolean forUpdate); /** * Called when a new job is being created to reschedule an old failed job. */ diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java index 35432495942d..ab6768e99878 100644 --- a/services/core/java/com/android/server/job/controllers/TimeController.java +++ b/services/core/java/com/android/server/job/controllers/TimeController.java @@ -74,7 +74,7 @@ public class TimeController extends StateController { @Override public void maybeStartTrackingJobLocked(JobStatus job, JobStatus lastJob) { if (job.hasTimingDelayConstraint() || job.hasDeadlineConstraint()) { - maybeStopTrackingJobLocked(job, false); + maybeStopTrackingJobLocked(job, null, false); boolean isInsert = false; ListIterator<JobStatus> it = mTrackedJobs.listIterator(mTrackedJobs.size()); while (it.hasPrevious()) { @@ -101,7 +101,7 @@ public class TimeController extends StateController { * Really an == comparison should be enough, but why play with fate? We'll do <=. */ @Override - public void maybeStopTrackingJobLocked(JobStatus job, boolean forUpdate) { + public void maybeStopTrackingJobLocked(JobStatus job, JobStatus incomingJob, boolean forUpdate) { if (mTrackedJobs.remove(job)) { checkExpiredDelaysAndResetAlarm(); checkExpiredDeadlinesAndResetAlarm(); diff --git a/services/core/java/com/android/server/lights/LightsService.java b/services/core/java/com/android/server/lights/LightsService.java index 257c7dadfc5d..5953ddecd222 100644 --- a/services/core/java/com/android/server/lights/LightsService.java +++ b/services/core/java/com/android/server/lights/LightsService.java @@ -18,12 +18,17 @@ package com.android.server.lights; import com.android.server.SystemService; import com.android.server.vr.VrManagerInternal; +import com.android.server.vr.VrManagerService; import com.android.server.vr.VrStateListener; import android.content.Context; import android.os.Handler; +import android.os.IBinder; import android.os.Message; +import android.os.RemoteException; import android.os.Trace; +import android.service.vr.IVrManager; +import android.service.vr.IVrStateCallbacks; import android.util.Slog; public class LightsService extends SystemService { @@ -164,13 +169,19 @@ public class LightsService extends SystemService { @Override public void onBootPhase(int phase) { if (phase == PHASE_SYSTEM_SERVICES_READY) { - getLocalService(VrManagerInternal.class).registerListener(mVrStateListener); + IVrManager vrManager = + (IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE); + try { + vrManager.registerListener(mVrStateCallbacks); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to register VR mode state listener: " + e); + } } } - private final VrStateListener mVrStateListener = new VrStateListener() { + private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() { @Override - public void onVrStateChanged(boolean enabled) { + public void onVrStateChanged(boolean enabled) throws RemoteException { LightImpl l = mLights[LightsManager.LIGHT_ID_BACKLIGHT]; if (enabled) { if (DEBUG) Slog.v(TAG, "VR mode enabled, setting brightness to low persistence"); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 124d7f1b9c97..99c41eae22ae 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -771,10 +771,9 @@ public class NotificationManagerService extends SystemService { cancelAllNotificationsInt(MY_UID, MY_PID, null, 0, 0, true, userHandle, REASON_USER_STOPPED, null); } - } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED)) { - boolean inQuietMode = intent.getBooleanExtra(Intent.EXTRA_QUIET_MODE, false); + } else if (action.equals(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE)) { int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1); - if (inQuietMode && userHandle >= 0) { + if (userHandle >= 0) { cancelAllNotificationsInt(MY_UID, MY_PID, null, 0, 0, true, userHandle, REASON_PROFILE_TURNED_OFF, null); } @@ -1008,7 +1007,7 @@ public class NotificationManagerService extends SystemService { filter.addAction(Intent.ACTION_USER_ADDED); filter.addAction(Intent.ACTION_USER_REMOVED); filter.addAction(Intent.ACTION_USER_UNLOCKED); - filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED); + filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); getContext().registerReceiver(mIntentReceiver, filter); IntentFilter pkgFilter = new IntentFilter(); @@ -2898,9 +2897,10 @@ public class NotificationManagerService extends SystemService { } private void scheduleSendRankingUpdate() { - mHandler.removeMessages(MESSAGE_SEND_RANKING_UPDATE); - Message m = Message.obtain(mHandler, MESSAGE_SEND_RANKING_UPDATE); - mHandler.sendMessage(m); + if (!mHandler.hasMessages(MESSAGE_SEND_RANKING_UPDATE)) { + Message m = Message.obtain(mHandler, MESSAGE_SEND_RANKING_UPDATE); + mHandler.sendMessage(m); + } } private void handleSendRankingUpdate() { diff --git a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java index e496132a7451..098b39e50d92 100644 --- a/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java +++ b/services/core/java/com/android/server/pm/DefaultPermissionGrantPolicy.java @@ -595,6 +595,16 @@ final class DefaultPermissionGrantPolicy { grantRuntimePermissionsLPw(emergencyInfoPckg, PHONE_PERMISSIONS, true, userId); } + // NFC Tag viewer + Intent nfcTagIntent = new Intent(Intent.ACTION_VIEW); + nfcTagIntent.setType("vnd.android.cursor.item/ndef_msg"); + PackageParser.Package nfcTagPkg = getDefaultSystemHandlerActivityPackageLPr( + nfcTagIntent, userId); + if (nfcTagPkg != null + && doesPackageSupportRuntimePermissions(nfcTagPkg)) { + grantRuntimePermissionsLPw(nfcTagPkg, CONTACTS_PERMISSIONS, false, userId); + grantRuntimePermissionsLPw(nfcTagPkg, PHONE_PERMISSIONS, false, userId); + } mService.mSettings.onDefaultRuntimePermissionsGrantedLPr(userId); } } diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index 7c71fbc82e77..4c18e15e912a 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -60,6 +60,7 @@ import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.SystemService; +import java.util.ArrayList; import java.util.List; /** @@ -77,7 +78,6 @@ public class LauncherAppsService extends SystemService { @Override public void onStart() { - Binder.LOG_RUNTIME_EXCEPTION = true; publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl); } @@ -121,6 +121,21 @@ public class LauncherAppsService extends SystemService { return getCallingUid(); } + final int injectCallingUserId() { + return UserHandle.getUserId(injectBinderCallingUid()); + } + + @VisibleForTesting + long injectClearCallingIdentity() { + return Binder.clearCallingIdentity(); + } + + // Injection point. + @VisibleForTesting + void injectRestoreCallingIdentity(long token) { + Binder.restoreCallingIdentity(token); + } + private int getCallingUserId() { return UserHandle.getUserId(injectBinderCallingUid()); } @@ -197,14 +212,13 @@ public class LauncherAppsService extends SystemService { /** * Checks if the caller is in the same group as the userToCheck. */ - @VisibleForTesting // We override it in unit tests - void ensureInUserProfiles(UserHandle userToCheck, String message) { - final int callingUserId = UserHandle.getCallingUserId(); + private void ensureInUserProfiles(UserHandle userToCheck, String message) { + final int callingUserId = injectCallingUserId(); final int targetUserId = userToCheck.getIdentifier(); if (targetUserId == callingUserId) return; - long ident = Binder.clearCallingIdentity(); + long ident = injectClearCallingIdentity(); try { UserInfo callingUserInfo = mUm.getUserInfo(callingUserId); UserInfo targetUserInfo = mUm.getUserInfo(targetUserId); @@ -214,7 +228,7 @@ public class LauncherAppsService extends SystemService { throw new SecurityException(message); } } finally { - Binder.restoreCallingIdentity(ident); + injectRestoreCallingIdentity(ident); } } @@ -239,12 +253,12 @@ public class LauncherAppsService extends SystemService { * Checks if the user is enabled. */ private boolean isUserEnabled(UserHandle user) { - long ident = Binder.clearCallingIdentity(); + long ident = injectClearCallingIdentity(); try { UserInfo targetUserInfo = mUm.getUserInfo(user.getIdentifier()); return targetUserInfo != null && targetUserInfo.isEnabled(); } finally { - Binder.restoreCallingIdentity(ident); + injectRestoreCallingIdentity(ident); } } @@ -345,6 +359,9 @@ public class LauncherAppsService extends SystemService { public ParceledListSlice getShortcuts(String callingPackage, long changedSince, String packageName, ComponentName componentName, int flags, UserHandle user) { ensureShortcutPermission(callingPackage, user); + if (!isUserEnabled(user)) { + return new ParceledListSlice<>(new ArrayList(0)); + } return new ParceledListSlice<>( mShortcutServiceInternal.getShortcuts(getCallingUserId(), @@ -356,6 +373,9 @@ public class LauncherAppsService extends SystemService { public ParceledListSlice getShortcutInfo(String callingPackage, String packageName, List<String> ids, UserHandle user) { ensureShortcutPermission(callingPackage, user); + if (!isUserEnabled(user)) { + return new ParceledListSlice<>(new ArrayList(0)); + } return new ParceledListSlice<>( mShortcutServiceInternal.getShortcutInfo(getCallingUserId(), @@ -366,6 +386,10 @@ public class LauncherAppsService extends SystemService { public void pinShortcuts(String callingPackage, String packageName, List<String> ids, UserHandle user) { ensureShortcutPermission(callingPackage, user); + if (!isUserEnabled(user)) { + throw new IllegalStateException("Cannot pin shortcuts for disabled profile " + + user); + } mShortcutServiceInternal.pinShortcuts(getCallingUserId(), callingPackage, packageName, ids, user.getIdentifier()); @@ -375,6 +399,9 @@ public class LauncherAppsService extends SystemService { public int getShortcutIconResId(String callingPackage, ShortcutInfo shortcut, UserHandle user) { ensureShortcutPermission(callingPackage, user); + if (!isUserEnabled(user)) { + return 0; + } return mShortcutServiceInternal.getShortcutIconResId(getCallingUserId(), callingPackage, shortcut, user.getIdentifier()); @@ -384,6 +411,9 @@ public class LauncherAppsService extends SystemService { public ParcelFileDescriptor getShortcutIconFd(String callingPackage, ShortcutInfo shortcut, UserHandle user) { ensureShortcutPermission(callingPackage, user); + if (!isUserEnabled(user)) { + return null; + } return mShortcutServiceInternal.getShortcutIconFd(getCallingUserId(), callingPackage, shortcut, user.getIdentifier()); @@ -402,6 +432,11 @@ public class LauncherAppsService extends SystemService { verifyCallingPackage(callingPackage); ensureInUserProfiles(user, "Cannot start activity for unrelated profile " + user); + if (!isUserEnabled(user)) { + throw new IllegalStateException("Cannot start a shortcut for disabled profile " + + user); + } + // Even without the permission, pinned shortcuts are always launchable. if (!mShortcutServiceInternal.isPinnedByCaller(getCallingUserId(), callingPackage, packageName, shortcutId, user.getIdentifier())) { @@ -530,13 +565,13 @@ public class LauncherAppsService extends SystemService { /** Checks if user is a profile of or same as listeningUser. * and the user is enabled. */ - boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, + private boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, String debugMsg) { if (user.getIdentifier() == listeningUser.getIdentifier()) { if (DEBUG) Log.d(TAG, "Delivering msg to same user " + debugMsg); return true; } - long ident = Binder.clearCallingIdentity(); + long ident = injectClearCallingIdentity(); try { UserInfo userInfo = mUm.getUserInfo(user.getIdentifier()); UserInfo listeningUserInfo = mUm.getUserInfo(listeningUser.getIdentifier()); @@ -557,7 +592,7 @@ public class LauncherAppsService extends SystemService { return true; } } finally { - Binder.restoreCallingIdentity(ident); + injectRestoreCallingIdentity(ident); } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 0a86a849653c..31eac1f3e0ec 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -76,6 +76,7 @@ import static android.content.pm.PackageManager.PERMISSION_DENIED; import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageParser.PARSE_IS_PRIVILEGED; import static android.content.pm.PackageParser.isApkFile; +import static android.os.Process.FIRST_APPLICATION_UID; import static android.os.Process.PACKAGE_INFO_GID; import static android.os.Process.SYSTEM_UID; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; @@ -109,12 +110,14 @@ import android.app.admin.DevicePolicyManagerInternal; import android.app.admin.IDevicePolicyManager; import android.app.admin.SecurityLog; import android.app.backup.IBackupManager; +import android.app.usage.UsageStatsManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; import android.content.IIntentReceiver; import android.content.Intent; import android.content.IntentFilter; +import android.content.IntentFilter.AuthorityEntry; import android.content.IntentSender; import android.content.IntentSender.SendIntentException; import android.content.ServiceConnection; @@ -147,6 +150,7 @@ import android.content.pm.PackageManager.LegacyPackageDeleteObserver; import android.content.pm.PackageManagerInternal; import android.content.pm.PackageParser; import android.content.pm.PackageParser.ActivityIntentInfo; +import android.content.pm.PackageParser.IntentInfo; import android.content.pm.PackageParser.PackageLite; import android.content.pm.PackageParser.PackageParserException; import android.content.pm.PackageStats; @@ -320,6 +324,7 @@ public class PackageManagerService extends IPackageManager.Stub { private static final boolean DEBUG_INTENT_MATCHING = false; private static final boolean DEBUG_PACKAGE_SCANNING = false; private static final boolean DEBUG_VERIFY = false; + private static final boolean DEBUG_FILTERS = false; // Debug output for dexopting. This is shared between PackageManagerService, OtaDexoptService // and PackageDexOptimizer. All these classes have their own flag to allow switching a single @@ -445,6 +450,18 @@ public class PackageManagerService extends IPackageManager.Stub { sBrowserIntent.setData(Uri.parse("http:")); } + /** + * The set of all protected actions [i.e. those actions for which a high priority + * intent filter is disallowed]. + */ + private static final Set<String> PROTECTED_ACTIONS = new ArraySet<>(); + static { + PROTECTED_ACTIONS.add(Intent.ACTION_SEND); + PROTECTED_ACTIONS.add(Intent.ACTION_SENDTO); + PROTECTED_ACTIONS.add(Intent.ACTION_SEND_MULTIPLE); + PROTECTED_ACTIONS.add(Intent.ACTION_VIEW); + } + // Compilation reasons. public static final int REASON_FIRST_BOOT = 0; public static final int REASON_BOOT = 1; @@ -531,6 +548,20 @@ public class PackageManagerService extends IPackageManager.Stub { * are package location. */ final private ArrayMap<String, File> mExpectingBetter = new ArrayMap<>(); + /** + * Tracks high priority intent filters for protected actions. During boot, certain + * filter actions are protected and should never be allowed to have a high priority + * intent filter for them. However, there is one, and only one exception -- the + * setup wizard. It must be able to define a high priority intent filter for these + * actions to ensure there are no escapes from the wizard. We need to delay processing + * of these during boot as we need to look at all of the system packages in order + * to know which component is the setup wizard. + */ + private final List<PackageParser.ActivityIntentInfo> mProtectedFilters = new ArrayList<>(); + /** + * Whether or not processing protected filters should be deferred. + */ + private boolean mDeferProtectedFilters = true; /** * Tracks existing system packages prior to receiving an OTA. Keys are package name. @@ -2429,6 +2460,36 @@ public class PackageManagerService extends IPackageManager.Stub { } mExpectingBetter.clear(); + // Resolve protected action filters. Only the setup wizard is allowed to + // have a high priority filter for these actions. + mSetupWizardPackage = getSetupWizardPackageName(); + if (mProtectedFilters.size() > 0) { + if (DEBUG_FILTERS && mSetupWizardPackage == null) { + Slog.i(TAG, "No setup wizard;" + + " All protected intents capped to priority 0"); + } + for (ActivityIntentInfo filter : mProtectedFilters) { + if (filter.activity.info.packageName.equals(mSetupWizardPackage)) { + if (DEBUG_FILTERS) { + Slog.i(TAG, "Found setup wizard;" + + " allow priority " + filter.getPriority() + ";" + + " package: " + filter.activity.info.packageName + + " activity: " + filter.activity.className + + " priority: " + filter.getPriority()); + } + // skip setup wizard; allow it to keep the high priority filter + continue; + } + Slog.w(TAG, "Protected action; cap priority to 0;" + + " package: " + filter.activity.info.packageName + + " activity: " + filter.activity.className + + " origPrio: " + filter.getPriority()); + filter.setPriority(0); + } + } + mDeferProtectedFilters = false; + mProtectedFilters.clear(); + // Now that we know all of the shared libraries, update all clients to have // the correct library paths. updateAllSharedLibrariesLPw(); @@ -2531,7 +2592,6 @@ public class PackageManagerService extends IPackageManager.Stub { } mInstallerService = new PackageInstallerService(context, this); - mSetupWizardPackage = getSetupWizardPackageName(); final ComponentName ephemeralResolverComponent = getEphemeralResolverLPr(); final ComponentName ephemeralInstallerComponent = getEphemeralInstallerLPr(); @@ -6946,25 +7006,46 @@ public class PackageManagerService extends IPackageManager.Stub { pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this); } + UsageStatsManager usageMgr = + (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE); + int curr = 0; int total = pkgs.size(); for (PackageParser.Package pkg : pkgs) { curr++; + if (!PackageDexOptimizer.canOptimizePackage(pkg)) { + if (DEBUG_DEXOPT) { + Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName); + } + continue; + } + + if (!causeFirstBoot && usageMgr.isAppInactive(pkg.packageName)) { + if (DEBUG_DEXOPT) { + Log.i(TAG, "Skipping update of of idle app " + pkg.packageName); + } + continue; + } + if (DEBUG_DEXOPT) { Log.i(TAG, "Extracting app " + curr + " of " + total + ": " + pkg.packageName); } - if (PackageDexOptimizer.canOptimizePackage(pkg)) { - // If the cache was pruned, any compiled odex files will likely be out of date - // and would have to be patched (would be SELF_PATCHOAT, which is deprecated). - // Instead, force the extraction in this case. - performDexOpt(pkg.packageName, - null /* instructionSet */, - false /* checkProfiles */, - causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT, - false /* force */); + if (!isFirstBoot()) { + try { + ActivityManagerNative.getDefault().showBootMessage( + mContext.getResources().getString(R.string.android_upgrading_apk, + curr, total), true); + } catch (RemoteException e) { + } } + + performDexOpt(pkg.packageName, + null /* instructionSet */, + false /* checkProfiles */, + causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT, + false /* force */); } } @@ -9762,8 +9843,314 @@ public class PackageManagerService extends IPackageManager.Stub { return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId); } + /** + * Finds a privileged activity that matches the specified activity names. + */ + private PackageParser.Activity findMatchingActivity( + List<PackageParser.Activity> activityList, ActivityInfo activityInfo) { + for (PackageParser.Activity sysActivity : activityList) { + if (sysActivity.info.name.equals(activityInfo.name)) { + return sysActivity; + } + if (sysActivity.info.name.equals(activityInfo.targetActivity)) { + return sysActivity; + } + if (sysActivity.info.targetActivity != null) { + if (sysActivity.info.targetActivity.equals(activityInfo.name)) { + return sysActivity; + } + if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) { + return sysActivity; + } + } + } + return null; + } + + public class IterGenerator<E> { + public Iterator<E> generate(ActivityIntentInfo info) { + return null; + } + } + + public class ActionIterGenerator extends IterGenerator<String> { + @Override + public Iterator<String> generate(ActivityIntentInfo info) { + return info.actionsIterator(); + } + } + + public class CategoriesIterGenerator extends IterGenerator<String> { + @Override + public Iterator<String> generate(ActivityIntentInfo info) { + return info.categoriesIterator(); + } + } + + public class SchemesIterGenerator extends IterGenerator<String> { + @Override + public Iterator<String> generate(ActivityIntentInfo info) { + return info.schemesIterator(); + } + } + + public class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> { + @Override + public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) { + return info.authoritiesIterator(); + } + } + + /** + * <em>WARNING</em> for performance reasons, the passed in intentList WILL BE + * MODIFIED. Do not pass in a list that should not be changed. + */ + private <T> void getIntentListSubset(List<ActivityIntentInfo> intentList, + IterGenerator<T> generator, Iterator<T> searchIterator) { + // loop through the set of actions; every one must be found in the intent filter + while (searchIterator.hasNext()) { + // we must have at least one filter in the list to consider a match + if (intentList.size() == 0) { + break; + } + + final T searchAction = searchIterator.next(); + + // loop through the set of intent filters + final Iterator<ActivityIntentInfo> intentIter = intentList.iterator(); + while (intentIter.hasNext()) { + final ActivityIntentInfo intentInfo = intentIter.next(); + boolean selectionFound = false; + + // loop through the intent filter's selection criteria; at least one + // of them must match the searched criteria + final Iterator<T> intentSelectionIter = generator.generate(intentInfo); + while (intentSelectionIter != null && intentSelectionIter.hasNext()) { + final T intentSelection = intentSelectionIter.next(); + if (intentSelection != null && intentSelection.equals(searchAction)) { + selectionFound = true; + break; + } + } + + // the selection criteria wasn't found in this filter's set; this filter + // is not a potential match + if (!selectionFound) { + intentIter.remove(); + } + } + } + } + + private boolean isProtectedAction(ActivityIntentInfo filter) { + final Iterator<String> actionsIter = filter.actionsIterator(); + while (actionsIter != null && actionsIter.hasNext()) { + final String filterAction = actionsIter.next(); + if (PROTECTED_ACTIONS.contains(filterAction)) { + return true; + } + } + return false; + } + + /** + * Adjusts the priority of the given intent filter according to policy. + * <p> + * <ul> + * <li>The priority for non privileged applications is capped to '0'</li> + * <li>The priority for protected actions on privileged applications is capped to '0'</li> + * <li>The priority for unbundled updates to privileged applications is capped to the + * priority defined on the system partition</li> + * </ul> + * <p> + * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is + * allowed to obtain any priority on any action. + */ + private void adjustPriority( + List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { + // nothing to do; priority is fine as-is + if (intent.getPriority() <= 0) { + return; + } + + final ActivityInfo activityInfo = intent.activity.info; + final ApplicationInfo applicationInfo = activityInfo.applicationInfo; + + final boolean privilegedApp = + ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); + if (!privilegedApp) { + // non-privileged applications can never define a priority >0 + Slog.w(TAG, "Non-privileged app; cap priority to 0;" + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + + " origPrio: " + intent.getPriority()); + intent.setPriority(0); + return; + } + + if (systemActivities == null) { + // the system package is not disabled; we're parsing the system partition + if (isProtectedAction(intent)) { + if (mDeferProtectedFilters) { + // We can't deal with these just yet. No component should ever obtain a + // >0 priority for a protected actions, with ONE exception -- the setup + // wizard. The setup wizard, however, cannot be known until we're able to + // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do + // until all intent filters have been processed. Chicken, meet egg. + // Let the filter temporarily have a high priority and rectify the + // priorities after all system packages have been scanned. + mProtectedFilters.add(intent); + if (DEBUG_FILTERS) { + Slog.i(TAG, "Protected action; save for later;" + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + + " origPrio: " + intent.getPriority()); + } + return; + } else { + if (DEBUG_FILTERS && mSetupWizardPackage == null) { + Slog.i(TAG, "No setup wizard;" + + " All protected intents capped to priority 0"); + } + if (intent.activity.info.packageName.equals(mSetupWizardPackage)) { + if (DEBUG_FILTERS) { + Slog.i(TAG, "Found setup wizard;" + + " allow priority " + intent.getPriority() + ";" + + " package: " + intent.activity.info.packageName + + " activity: " + intent.activity.className + + " priority: " + intent.getPriority()); + } + // setup wizard gets whatever it wants + return; + } + Slog.w(TAG, "Protected action; cap priority to 0;" + + " package: " + intent.activity.info.packageName + + " activity: " + intent.activity.className + + " origPrio: " + intent.getPriority()); + intent.setPriority(0); + return; + } + } + // privileged apps on the system image get whatever priority they request + return; + } + + // privileged app unbundled update ... try to find the same activity + final PackageParser.Activity foundActivity = + findMatchingActivity(systemActivities, activityInfo); + if (foundActivity == null) { + // this is a new activity; it cannot obtain >0 priority + if (DEBUG_FILTERS) { + Slog.i(TAG, "New activity; cap priority to 0;" + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + + " origPrio: " + intent.getPriority()); + } + intent.setPriority(0); + return; + } + + // found activity, now check for filter equivalence + + // a shallow copy is enough; we modify the list, not its contents + final List<ActivityIntentInfo> intentListCopy = + new ArrayList<>(foundActivity.intents); + final List<ActivityIntentInfo> foundFilters = findFilters(intent); + + // find matching action subsets + final Iterator<String> actionsIterator = intent.actionsIterator(); + if (actionsIterator != null) { + getIntentListSubset( + intentListCopy, new ActionIterGenerator(), actionsIterator); + if (intentListCopy.size() == 0) { + // no more intents to match; we're not equivalent + if (DEBUG_FILTERS) { + Slog.i(TAG, "Mismatched action; cap priority to 0;" + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + + " origPrio: " + intent.getPriority()); + } + intent.setPriority(0); + return; + } + } + + // find matching category subsets + final Iterator<String> categoriesIterator = intent.categoriesIterator(); + if (categoriesIterator != null) { + getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), + categoriesIterator); + if (intentListCopy.size() == 0) { + // no more intents to match; we're not equivalent + if (DEBUG_FILTERS) { + Slog.i(TAG, "Mismatched category; cap priority to 0;" + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + + " origPrio: " + intent.getPriority()); + } + intent.setPriority(0); + return; + } + } + + // find matching schemes subsets + final Iterator<String> schemesIterator = intent.schemesIterator(); + if (schemesIterator != null) { + getIntentListSubset(intentListCopy, new SchemesIterGenerator(), + schemesIterator); + if (intentListCopy.size() == 0) { + // no more intents to match; we're not equivalent + if (DEBUG_FILTERS) { + Slog.i(TAG, "Mismatched scheme; cap priority to 0;" + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + + " origPrio: " + intent.getPriority()); + } + intent.setPriority(0); + return; + } + } + + // find matching authorities subsets + final Iterator<IntentFilter.AuthorityEntry> + authoritiesIterator = intent.authoritiesIterator(); + if (authoritiesIterator != null) { + getIntentListSubset(intentListCopy, + new AuthoritiesIterGenerator(), + authoritiesIterator); + if (intentListCopy.size() == 0) { + // no more intents to match; we're not equivalent + if (DEBUG_FILTERS) { + Slog.i(TAG, "Mismatched authority; cap priority to 0;" + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + + " origPrio: " + intent.getPriority()); + } + intent.setPriority(0); + return; + } + } + + // we found matching filter(s); app gets the max priority of all intents + int cappedPriority = 0; + for (int i = intentListCopy.size() - 1; i >= 0; --i) { + cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); + } + if (intent.getPriority() > cappedPriority) { + if (DEBUG_FILTERS) { + Slog.i(TAG, "Found matching filter(s);" + + " cap priority to " + cappedPriority + ";" + + " package: " + applicationInfo.packageName + + " activity: " + intent.activity.className + + " origPrio: " + intent.getPriority()); + } + intent.setPriority(cappedPriority); + return; + } + // all this for nothing; the requested priority was <= what was on the system + } + public final void addActivity(PackageParser.Activity a, String type) { - final boolean systemApp = a.info.applicationInfo.isSystemApp(); mActivities.put(a.getComponentName(), a); if (DEBUG_SHOW_INFO) Log.v( @@ -9774,10 +10161,12 @@ public class PackageManagerService extends IPackageManager.Stub { final int NI = a.intents.size(); for (int j=0; j<NI; j++) { PackageParser.ActivityIntentInfo intent = a.intents.get(j); - if (!systemApp && intent.getPriority() > 0 && "activity".equals(type)) { - intent.setPriority(0); - Log.w(TAG, "Package " + a.info.applicationInfo.packageName + " has activity " - + a.className + " with priority > 0, forcing to 0"); + if ("activity".equals(type)) { + final PackageSetting ps = + mSettings.getDisabledSystemPkgLPr(intent.activity.info.packageName); + final List<PackageParser.Activity> systemActivities = + ps != null && ps.pkg != null ? ps.pkg.activities : null; + adjustPriority(systemActivities, intent); } if (DEBUG_SHOW_INFO) { Log.v(TAG, " IntentFilter:"); @@ -9927,18 +10316,6 @@ public class PackageManagerService extends IPackageManager.Stub { out.println(); } -// List<ResolveInfo> filterEnabled(List<ResolveInfo> resolveInfoList) { -// final Iterator<ResolveInfo> i = resolveInfoList.iterator(); -// final List<ResolveInfo> retList = Lists.newArrayList(); -// while (i.hasNext()) { -// final ResolveInfo resolveInfo = i.next(); -// if (isEnabledLP(resolveInfo.activityInfo)) { -// retList.add(resolveInfo); -// } -// } -// return retList; -// } - // Keys are String (activity class name), values are Activity. private final ArrayMap<ComponentName, PackageParser.Activity> mActivities = new ArrayMap<ComponentName, PackageParser.Activity>(); @@ -11290,8 +11667,8 @@ public class PackageManagerService extends IPackageManager.Stub { * @return the current "allow unknown sources" setting */ private int getUnknownSourcesSettings() { - return android.provider.Settings.Global.getInt(mContext.getContentResolver(), - android.provider.Settings.Global.INSTALL_NON_MARKET_APPS, + return android.provider.Settings.Secure.getInt(mContext.getContentResolver(), + android.provider.Settings.Secure.INSTALL_NON_MARKET_APPS, -1); } @@ -11779,8 +12156,23 @@ public class PackageManagerService extends IPackageManager.Stub { // predecessor. As a security measure, this is permited only if this is not a // version downgrade or if the predecessor package is marked as debuggable and // a downgrade is explicitly requested. - if (((dataOwnerPkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) - || ((installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) == 0)) { + // + // On debuggable platform builds, downgrades are permitted even for + // non-debuggable packages to make testing easier. Debuggable platform builds do + // not offer security guarantees and thus it's OK to disable some security + // mechanisms to make debugging/testing easier on those builds. However, even on + // debuggable builds downgrades of packages are permitted only if requested via + // installFlags. This is because we aim to keep the behavior of debuggable + // platform builds as close as possible to the behavior of non-debuggable + // platform builds. + final boolean downgradeRequested = + (installFlags & PackageManager.INSTALL_ALLOW_DOWNGRADE) != 0; + final boolean packageDebuggable = + (dataOwnerPkg.applicationInfo.flags + & ApplicationInfo.FLAG_DEBUGGABLE) != 0; + final boolean downgradePermitted = + (downgradeRequested) && ((Build.IS_DEBUGGABLE) || (packageDebuggable)); + if (!downgradePermitted) { try { checkDowngrade(dataOwnerPkg, pkgLite); } catch (PackageManagerException e) { @@ -12255,8 +12647,6 @@ public class PackageManagerService extends IPackageManager.Stub { * Called after the source arguments are copied. This is used mostly for * MoveParams when it needs to read the source file to put it in the * destination. - * - * @return */ int doPostCopy(int uid) { return PackageManager.INSTALL_SUCCEEDED; @@ -13883,14 +14273,11 @@ public class PackageManagerService extends IPackageManager.Stub { } } - Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates"); try { PackageParser.collectCertificates(pkg, parseFlags); } catch (PackageParserException e) { res.setError("Failed collect during installPackageLI", e); return; - } finally { - Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); } // Get rid of all references to package scan path via parser. @@ -15502,17 +15889,14 @@ public class PackageManagerService extends IPackageManager.Stub { // Otherwise, reset the permission. final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); switch (revokeResult) { - case PERMISSION_OPERATION_SUCCESS: { - writeRuntimePermissions = true; - } break; - + case PERMISSION_OPERATION_SUCCESS: case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: { writeRuntimePermissions = true; final int appId = ps.appId; mHandler.post(new Runnable() { @Override public void run() { - killUid(appId, userId, KILL_APP_REASON_GIDS_CHANGED); + killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED); } }); } break; @@ -16632,7 +17016,9 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); intent.addCategory(Intent.CATEGORY_SETUP_WIZARD); final List<ResolveInfo> matches = queryIntentActivitiesInternal(intent, null, - MATCH_SYSTEM_ONLY | MATCH_DISABLED_COMPONENTS, UserHandle.myUserId()); + MATCH_SYSTEM_ONLY | MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE + | MATCH_DISABLED_COMPONENTS, + UserHandle.myUserId()); if (matches.size() == 1) { return matches.get(0).getComponentInfo().packageName; } else { diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 7aefcb82a158..5c1e7a8dde9b 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -2159,6 +2159,9 @@ public class ShortcutService extends IShortcutService.Stub { case "refresh-default-launcher": handleRefreshDefaultLauncher(); break; + case "unload-user": + handleUnloadUser(); + break; default: return handleDefaultCommands(cmd); } @@ -2196,6 +2199,10 @@ public class ShortcutService extends IShortcutService.Stub { pw.println("cmd shortcut refresh-default-launcher [--user USER_ID]"); pw.println(" Refresh the cached default launcher"); pw.println(); + pw.println("cmd shortcut unload-user [--user USER_ID]"); + pw.println(" Unload a user from the memory"); + pw.println(" (This should not affect any observable behavior)"); + pw.println(); } private int handleResetThrottling() throws CommandException { @@ -2267,6 +2274,12 @@ public class ShortcutService extends IShortcutService.Stub { clearLauncher(); showLauncher(); } + + private void handleUnloadUser() throws CommandException { + parseOptions(/* takeUser =*/ true); + + ShortcutService.this.handleCleanupUser(mUserId); + } } // === Unit test support === diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 3ff46acb5d31..06a91fb0c857 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -500,6 +500,9 @@ public class UserManagerService extends IUserManager.Stub { if (mRemovingUserIds.get(profile.id)) { continue; } + if (profile.partial) { + continue; + } users.add(userWithName(profile)); } return users; @@ -573,12 +576,26 @@ public class UserManagerService extends IUserManager.Stub { private void broadcastProfileAvailabilityChanges(UserHandle profileHandle, UserHandle parentHandle, boolean inQuietMode) { - Intent intent = new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED); + Intent intent = new Intent(); + if (inQuietMode) { + intent.setAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE); + } else { + intent.setAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE); + } intent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode); intent.putExtra(Intent.EXTRA_USER, profileHandle); intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier()); intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); mContext.sendBroadcastAsUser(intent, parentHandle); + + //TODO: remove once Launcher3 is updated. + Intent oldIntent = new Intent(Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED); + oldIntent.putExtra(Intent.EXTRA_QUIET_MODE, inQuietMode); + oldIntent.putExtra(Intent.EXTRA_USER, profileHandle); + oldIntent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier()); + oldIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY); + mContext.sendBroadcastAsUser(oldIntent, parentHandle); + } @Override diff --git a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java index 4b355de62e87..364e9fa6719c 100644 --- a/services/core/java/com/android/server/pm/UserRestrictionsUtils.java +++ b/services/core/java/com/android/server/pm/UserRestrictionsUtils.java @@ -425,6 +425,18 @@ public class UserRestrictionsUtils { } } } + break; + case UserManager.DISALLOW_SAFE_BOOT: + // Unlike with the other restrictions, we want to propagate the new value to + // the system settings even if it is false. The other restrictions modify + // settings which could be manually changed by the user from the Settings app + // after the policies enforcing these restrictions have been revoked, so we + // leave re-setting of those settings to the user. + android.provider.Settings.Global.putInt( + context.getContentResolver(), + android.provider.Settings.Global.SAFE_BOOT_DISALLOWED, + newValue ? 1 : 0); + break; } } finally { Binder.restoreCallingIdentity(id); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 14d0457e41c1..fb56a0c7ee3e 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -69,6 +69,7 @@ import android.graphics.Rect; import android.hardware.hdmi.HdmiControlManager; import android.hardware.hdmi.HdmiPlaybackClient; import android.hardware.hdmi.HdmiPlaybackClient.OneTouchPlayCallback; +import android.hardware.input.InputManagerInternal; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.AudioSystem; @@ -107,6 +108,7 @@ import android.telecom.TelecomManager; import android.util.DisplayMetrics; import android.util.EventLog; import android.util.Log; +import android.util.MutableBoolean; import android.util.Slog; import android.util.SparseArray; import android.util.LongSparseArray; @@ -304,6 +306,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowManagerInternal mWindowManagerInternal; PowerManager mPowerManager; ActivityManagerInternal mActivityManagerInternal; + InputManagerInternal mInputManagerInternal; DreamManagerInternal mDreamManagerInternal; PowerManagerInternal mPowerManagerInternal; IStatusBarService mStatusBarService; @@ -396,6 +399,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { volatile boolean mBeganFromNonInteractive; volatile int mPowerKeyPressCounter; volatile boolean mEndCallKeyHandled; + volatile boolean mCameraGestureTriggeredDuringGoingToSleep; + volatile boolean mGoingToSleep; boolean mRecentsVisible; int mRecentAppsHeldModifiers; @@ -601,6 +606,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mConsumeSearchKeyUp; boolean mAssistKeyLongPressed; boolean mPendingMetaAction; + boolean mPendingCapsLockToggle; + int mMetaState; + int mInitialMetaState; boolean mForceShowSystemBars; // support for activating the lock screen while the screen is on @@ -685,6 +693,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { = new LogDecelerateInterpolator(100, 0); private boolean mForceWindowDrawsStatusBarBackground; + private final MutableBoolean mTmpBoolean = new MutableBoolean(false); private static final int MSG_ENABLE_POINTER_LOCATION = 1; private static final int MSG_DISABLE_POINTER_LOCATION = 2; @@ -1032,7 +1041,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { GestureLauncherService.class); boolean gesturedServiceIntercepted = false; if (gestureService != null) { - gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive); + gesturedServiceIntercepted = gestureService.interceptPowerKeyDown(event, interactive, + mTmpBoolean); + if (mTmpBoolean.value && mGoingToSleep) { + mCameraGestureTriggeredDuringGoingToSleep = true; + } } // If the power key has still not yet been handled, then detect short @@ -1486,6 +1499,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mWindowManagerFuncs = windowManagerFuncs; mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class); mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); + mInputManagerInternal = LocalServices.getService(InputManagerInternal.class); mDreamManagerInternal = LocalServices.getService(DreamManagerInternal.class); mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); mAppOpsManager = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE); @@ -1817,41 +1831,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - mStatusBarHeight = - res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); - - // Height of the navigation bar when presented horizontally at bottom - mNavigationBarHeightForRotationDefault[mPortraitRotation] = - mNavigationBarHeightForRotationDefault[mUpsideDownRotation] = - res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height); - mNavigationBarHeightForRotationDefault[mLandscapeRotation] = - mNavigationBarHeightForRotationDefault[mSeascapeRotation] = res.getDimensionPixelSize( - com.android.internal.R.dimen.navigation_bar_height_landscape); - - // Width of the navigation bar when presented vertically along one side - mNavigationBarWidthForRotationDefault[mPortraitRotation] = - mNavigationBarWidthForRotationDefault[mUpsideDownRotation] = - mNavigationBarWidthForRotationDefault[mLandscapeRotation] = - mNavigationBarWidthForRotationDefault[mSeascapeRotation] = - res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width); - - // Height of the navigation bar when presented horizontally at bottom - mNavigationBarHeightForRotationInCarMode[mPortraitRotation] = - mNavigationBarHeightForRotationInCarMode[mUpsideDownRotation] = - res.getDimensionPixelSize( - com.android.internal.R.dimen.navigation_bar_height_car_mode); - mNavigationBarHeightForRotationInCarMode[mLandscapeRotation] = - mNavigationBarHeightForRotationInCarMode[mSeascapeRotation] = res.getDimensionPixelSize( - com.android.internal.R.dimen.navigation_bar_height_landscape_car_mode); - - // Width of the navigation bar when presented vertically along one side - mNavigationBarWidthForRotationInCarMode[mPortraitRotation] = - mNavigationBarWidthForRotationInCarMode[mUpsideDownRotation] = - mNavigationBarWidthForRotationInCarMode[mLandscapeRotation] = - mNavigationBarWidthForRotationInCarMode[mSeascapeRotation] = - res.getDimensionPixelSize( - com.android.internal.R.dimen.navigation_bar_width_car_mode); - // SystemUI (status bar) layout policy int shortSizeDp = shortSize * DisplayMetrics.DENSITY_DEFAULT / density; int longSizeDp = longSize * DisplayMetrics.DENSITY_DEFAULT / density; @@ -1860,6 +1839,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mNavigationBarCanMove = width != height && shortSizeDp < 600; mHasNavigationBar = res.getBoolean(com.android.internal.R.bool.config_showNavigationBar); + // Allow a system property to override this. Used by the emulator. // See also hasNavigationBar(). String navBarOverride = SystemProperties.get("qemu.hw.mainkeys"); @@ -2290,6 +2270,46 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + @Override + public void onConfigurationChanged() { + final Resources res = mContext.getResources(); + + mStatusBarHeight = + res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); + + // Height of the navigation bar when presented horizontally at bottom + mNavigationBarHeightForRotationDefault[mPortraitRotation] = + mNavigationBarHeightForRotationDefault[mUpsideDownRotation] = + res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_height); + mNavigationBarHeightForRotationDefault[mLandscapeRotation] = + mNavigationBarHeightForRotationDefault[mSeascapeRotation] = res.getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_height_landscape); + + // Width of the navigation bar when presented vertically along one side + mNavigationBarWidthForRotationDefault[mPortraitRotation] = + mNavigationBarWidthForRotationDefault[mUpsideDownRotation] = + mNavigationBarWidthForRotationDefault[mLandscapeRotation] = + mNavigationBarWidthForRotationDefault[mSeascapeRotation] = + res.getDimensionPixelSize(com.android.internal.R.dimen.navigation_bar_width); + + // Height of the navigation bar when presented horizontally at bottom + mNavigationBarHeightForRotationInCarMode[mPortraitRotation] = + mNavigationBarHeightForRotationInCarMode[mUpsideDownRotation] = + res.getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_height_car_mode); + mNavigationBarHeightForRotationInCarMode[mLandscapeRotation] = + mNavigationBarHeightForRotationInCarMode[mSeascapeRotation] = res.getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_height_landscape_car_mode); + + // Width of the navigation bar when presented vertically along one side + mNavigationBarWidthForRotationInCarMode[mPortraitRotation] = + mNavigationBarWidthForRotationInCarMode[mUpsideDownRotation] = + mNavigationBarWidthForRotationInCarMode[mLandscapeRotation] = + mNavigationBarWidthForRotationInCarMode[mSeascapeRotation] = + res.getDimensionPixelSize( + com.android.internal.R.dimen.navigation_bar_width_car_mode); + } + /** {@inheritDoc} */ @Override public int windowTypeToLayerLw(int type) { @@ -2954,6 +2974,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mPendingMetaAction && !KeyEvent.isMetaKey(keyCode)) { mPendingMetaAction = false; } + // Any key that is not Alt or Meta cancels Caps Lock combo tracking. + if (mPendingCapsLockToggle && !KeyEvent.isMetaKey(keyCode) && !KeyEvent.isAltKey(keyCode)) { + mPendingCapsLockToggle = false; + } // First we always handle the home key here, so applications // can never break it, although if keyguard is on, we do let @@ -3202,6 +3226,38 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + // Toggle Caps Lock on META-ALT. + boolean actionTriggered = false; + if (KeyEvent.isModifierKey(keyCode)) { + if (!mPendingCapsLockToggle) { + // Start tracking meta state for combo. + mInitialMetaState = mMetaState; + mPendingCapsLockToggle = true; + } else if (event.getAction() == KeyEvent.ACTION_UP) { + int altOnMask = mMetaState & KeyEvent.META_ALT_MASK; + int metaOnMask = mMetaState & KeyEvent.META_META_MASK; + + // Check for Caps Lock toggle + if ((metaOnMask != 0) && (altOnMask != 0)) { + // Check if nothing else is pressed + if (mInitialMetaState == (mMetaState ^ (altOnMask | metaOnMask))) { + // Handle Caps Lock Toggle + mInputManagerInternal.toggleCapsLock(event.getDeviceId()); + actionTriggered = true; + } + } + + // Always stop tracking when key goes up. + mPendingCapsLockToggle = false; + } + } + // Store current meta state to be able to evaluate it later. + mMetaState = metaState; + + if (actionTriggered) { + return -1; + } + if (KeyEvent.isMetaKey(keyCode)) { if (down) { mPendingMetaAction = true; @@ -5948,6 +6004,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { @Override public void startedGoingToSleep(int why) { if (DEBUG_WAKEUP) Slog.i(TAG, "Started going to sleep... (why=" + why + ")"); + mCameraGestureTriggeredDuringGoingToSleep = false; + mGoingToSleep = true; if (mKeyguardDelegate != null) { mKeyguardDelegate.onStartedGoingToSleep(why); } @@ -5960,6 +6018,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (DEBUG_WAKEUP) Slog.i(TAG, "Finished going to sleep... (why=" + why + ")"); MetricsLogger.histogram(mContext, "screen_timeout", mLockScreenTimeout / 1000); + mGoingToSleep = false; + // We must get this work done here because the power manager will drop // the wake lock and let the system suspend once this function returns. synchronized (mLock) { @@ -5969,8 +6029,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { updateLockScreenTimeout(); } if (mKeyguardDelegate != null) { - mKeyguardDelegate.onFinishedGoingToSleep(why); + mKeyguardDelegate.onFinishedGoingToSleep(why, + mCameraGestureTriggeredDuringGoingToSleep); } + mCameraGestureTriggeredDuringGoingToSleep = false; } // Called on the PowerManager's Notifier thread. diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java index 8d296d505c4c..52e588015177 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java @@ -294,9 +294,9 @@ public class KeyguardServiceDelegate { mKeyguardState.interactiveState = INTERACTIVE_STATE_GOING_TO_SLEEP; } - public void onFinishedGoingToSleep(int why) { + public void onFinishedGoingToSleep(int why, boolean cameraGestureTriggered) { if (mKeyguardService != null) { - mKeyguardService.onFinishedGoingToSleep(why); + mKeyguardService.onFinishedGoingToSleep(why, cameraGestureTriggered); } mKeyguardState.interactiveState = INTERACTIVE_STATE_SLEEP; } diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java index 429b18866a61..dacdec042a45 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceWrapper.java @@ -117,9 +117,9 @@ public class KeyguardServiceWrapper implements IKeyguardService { } @Override - public void onFinishedGoingToSleep(int reason) { + public void onFinishedGoingToSleep(int reason, boolean cameraGestureTriggered) { try { - mService.onFinishedGoingToSleep(reason); + mService.onFinishedGoingToSleep(reason, cameraGestureTriggered); } catch (RemoteException e) { Slog.w(TAG , "Remote Exception", e); } diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index ff5a0f967b54..8cd536de9b54 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -53,6 +53,8 @@ import android.provider.Settings; import android.provider.Settings.Secure; import android.provider.Settings.SettingNotFoundException; import android.service.dreams.DreamManagerInternal; +import android.service.vr.IVrManager; +import android.service.vr.IVrStateCallbacks; import android.util.EventLog; import android.util.Slog; import android.util.SparseIntArray; @@ -72,6 +74,7 @@ import com.android.server.am.BatteryStatsService; import com.android.server.lights.Light; import com.android.server.lights.LightsManager; import com.android.server.vr.VrManagerInternal; +import com.android.server.vr.VrManagerService; import com.android.server.vr.VrStateListener; import libcore.util.Objects; @@ -538,7 +541,10 @@ public final class PowerManagerService extends SystemService @Override public void onBootPhase(int phase) { synchronized (mLock) { - if (phase == PHASE_BOOT_COMPLETED) { + if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { + incrementBootCount(); + + } else if (phase == PHASE_BOOT_COMPLETED) { final long now = SystemClock.uptimeMillis(); mBootCompleted = true; mDirty |= DIRTY_BOOT_COMPLETED; @@ -553,8 +559,6 @@ public final class PowerManagerService extends SystemService } } mBootCompletedRunnables = null; - - incrementBootCount(); } } } @@ -657,7 +661,13 @@ public final class PowerManagerService extends SystemService resolver.registerContentObserver(Settings.Secure.getUriFor( Secure.BRIGHTNESS_USE_TWILIGHT), false, mSettingsObserver, UserHandle.USER_ALL); - getLocalService(VrManagerInternal.class).registerListener(mVrStateListener); + IVrManager vrManager = + (IVrManager) getBinderService(VrManagerService.VR_MANAGER_BINDER_SERVICE); + try { + vrManager.registerListener(mVrStateCallbacks); + } catch (RemoteException e) { + Slog.e(TAG, "Failed to register VR mode state listener: " + e); + } // Go. readConfigurationLocked(); updateSettingsLocked(); @@ -3006,7 +3016,7 @@ public final class PowerManagerService extends SystemService } } - private final VrStateListener mVrStateListener = new VrStateListener() { + private final IVrStateCallbacks mVrStateCallbacks = new IVrStateCallbacks.Stub() { @Override public void onVrStateChanged(boolean enabled) { powerHintInternal(POWER_HINT_VR_MODE, enabled ? 1 : 0); diff --git a/services/core/java/com/android/server/trust/TrustAgentWrapper.java b/services/core/java/com/android/server/trust/TrustAgentWrapper.java index 858f7c70663c..9c2c6bfe828c 100644 --- a/services/core/java/com/android/server/trust/TrustAgentWrapper.java +++ b/services/core/java/com/android/server/trust/TrustAgentWrapper.java @@ -375,7 +375,7 @@ public class TrustAgentWrapper { } else { mTrustAgentService.onConfigure(Collections.EMPTY_LIST, null); } - final long maxTimeToLock = dpm.getMaximumTimeToLock(null); + final long maxTimeToLock = dpm.getMaximumTimeToLockForUserAndProfiles(mUserId); if (maxTimeToLock != mMaximumTimeToLock) { // If the timeout changes, cancel the alarm and send a timeout event to have // the agent re-evaluate trust. diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java index 93bb9d795ddd..1bbb9f52c818 100644 --- a/services/core/java/com/android/server/vr/VrManagerInternal.java +++ b/services/core/java/com/android/server/vr/VrManagerInternal.java @@ -31,13 +31,6 @@ public abstract class VrManagerInternal { public static final int NO_ERROR = 0; /** - * Return current VR mode state. - * - * @return {@code true} if VR mode is enabled. - */ - public abstract boolean isInVrMode(); - - /** * Return {@code true} if the given package is the currently bound VrListenerService for the * given user. * @@ -59,22 +52,6 @@ public abstract class VrManagerInternal { public abstract void setVrMode(boolean enabled, @NonNull ComponentName packageName, int userId, @NonNull ComponentName calling); - /** - * Add a listener for VR mode state changes. - * <p> - * This listener will immediately be called with the current VR mode state. - * </p> - * @param listener the listener instance to add. - */ - public abstract void registerListener(@NonNull VrStateListener listener); - - /** - * Remove the listener from the current set of listeners. - * - * @param listener the listener to remove. - */ - public abstract void unregisterListener(@NonNull VrStateListener listener); - /** * Return NO_ERROR if the given package is installed on the device and enabled as a * VrListenerService for the given current user, or a negative error code indicating a failure. diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java index c572e766f1ec..e6e5a2db0725 100644 --- a/services/core/java/com/android/server/vr/VrManagerService.java +++ b/services/core/java/com/android/server/vr/VrManagerService.java @@ -15,6 +15,7 @@ */ package com.android.server.vr; +import android.Manifest; import android.app.AppOpsManager; import android.app.NotificationManager; import android.annotation.NonNull; @@ -29,11 +30,15 @@ import android.os.Handler; import android.os.IBinder; import android.os.IInterface; import android.os.Looper; +import android.os.Message; +import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.UserHandle; import android.provider.Settings; import android.service.notification.NotificationListenerService; import android.service.vr.IVrListener; +import android.service.vr.IVrManager; +import android.service.vr.IVrStateCallbacks; import android.service.vr.VrListenerService; import android.util.ArraySet; import android.util.Slog; @@ -46,6 +51,7 @@ import com.android.server.utils.ManagedApplicationService; import com.android.server.utils.ManagedApplicationService.BinderChecker; import java.lang.StringBuilder; +import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Collection; import java.util.Objects; @@ -75,6 +81,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC public static final String TAG = "VrManagerService"; + public static final String VR_MANAGER_BINDER_SERVICE = "vrmanager"; + private static native void initializeNative(); private static native void setVrModeNative(boolean enabled); @@ -84,7 +92,6 @@ public class VrManagerService extends SystemService implements EnabledComponentC // State protected by mLock private boolean mVrModeEnabled; - private final Set<VrStateListener> mListeners = new ArraySet<>(); private EnabledComponentsObserver mComponentObserver; private ManagedApplicationService mCurrentVrService; private Context mContext; @@ -92,10 +99,37 @@ public class VrManagerService extends SystemService implements EnabledComponentC private int mCurrentVrModeUser; private boolean mWasDefaultGranted; private boolean mGuard; + private final RemoteCallbackList<IVrStateCallbacks> mRemoteCallbacks = + new RemoteCallbackList<>(); private final ArraySet<String> mPreviousToggledListenerSettings = new ArraySet<>(); private String mPreviousNotificationPolicyAccessPackage; private String mPreviousManageOverlayPackage; + private static final int MSG_VR_STATE_CHANGE = 0; + + private final Handler mHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + switch(msg.what) { + case MSG_VR_STATE_CHANGE : { + boolean state = (msg.arg1 == 1); + int i = mRemoteCallbacks.beginBroadcast(); + while (i > 0) { + i--; + try { + mRemoteCallbacks.getBroadcastItem(i).onVrStateChanged(state); + } catch (RemoteException e) { + // Noop + } + } + mRemoteCallbacks.finishBroadcast(); + } break; + default : + throw new IllegalStateException("Unknown message type: " + msg.what); + } + } + }; + private static final BinderChecker sBinderChecker = new BinderChecker() { @Override public IInterface asInterface(IBinder binder) { @@ -125,34 +159,55 @@ public class VrManagerService extends SystemService implements EnabledComponentC } } - /** - * Implementation of VrManagerInternal. Callable only from system services. - */ - private final class LocalService extends VrManagerInternal { + private final IVrManager mVrManager = new IVrManager.Stub() { + @Override - public boolean isInVrMode() { - return VrManagerService.this.getVrMode(); + public void registerListener(IVrStateCallbacks cb) { + enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); + if (cb == null) { + throw new IllegalArgumentException("Callback binder object is null."); + } + + VrManagerService.this.addStateCallback(cb); } @Override - public void setVrMode(boolean enabled, ComponentName packageName, int userId, - ComponentName callingPackage) { - VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage); + public void unregisterListener(IVrStateCallbacks cb) { + enforceCallerPermission(Manifest.permission.ACCESS_VR_MANAGER); + if (cb == null) { + throw new IllegalArgumentException("Callback binder object is null."); + } + + VrManagerService.this.removeStateCallback(cb); } @Override - public boolean isCurrentVrListener(String packageName, int userId) { - return VrManagerService.this.isCurrentVrListener(packageName, userId); + public boolean getVrModeState() { + return VrManagerService.this.getVrMode(); + } + + }; + + private void enforceCallerPermission(String permission) { + if (mContext.checkCallingOrSelfPermission(permission) + != PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Caller does not hold the permission " + permission); } + } + /** + * Implementation of VrManagerInternal. Callable only from system services. + */ + private final class LocalService extends VrManagerInternal { @Override - public void registerListener(VrStateListener listener) { - VrManagerService.this.addListener(listener); + public void setVrMode(boolean enabled, ComponentName packageName, int userId, + ComponentName callingPackage) { + VrManagerService.this.setVrMode(enabled, packageName, userId, callingPackage); } @Override - public void unregisterListener(VrStateListener listener) { - VrManagerService.this.removeListener(listener); + public boolean isCurrentVrListener(String packageName, int userId) { + return VrManagerService.this.isCurrentVrListener(packageName, userId); } @Override @@ -173,6 +228,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC } publishLocalService(VrManagerInternal.class, new LocalService()); + publishBinderService(VR_MANAGER_BINDER_SERVICE, mVrManager.asBinder()); } @Override @@ -551,9 +607,8 @@ public class VrManagerService extends SystemService implements EnabledComponentC * Note: Must be called while holding {@code mLock}. */ private void onVrModeChangedLocked() { - for (VrStateListener l : mListeners) { - l.onVrStateChanged(mVrModeEnabled); - } + mHandler.sendMessage(mHandler.obtainMessage(MSG_VR_STATE_CHANGE, + (mVrModeEnabled) ? 1 : 0, 0)); } /** @@ -577,9 +632,9 @@ public class VrManagerService extends SystemService implements EnabledComponentC } } - private boolean getVrMode() { + private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) { synchronized (mLock) { - return mVrModeEnabled; + return mComponentObserver.isValid(targetPackageName, userId); } } @@ -593,21 +648,21 @@ public class VrManagerService extends SystemService implements EnabledComponentC } } - private void addListener(VrStateListener listener) { - synchronized (mLock) { - mListeners.add(listener); - } + /* + * Implementation of IVrManager calls. + */ + + private void addStateCallback(IVrStateCallbacks cb) { + mRemoteCallbacks.register(cb); } - private void removeListener(VrStateListener listener) { - synchronized (mLock) { - mListeners.remove(listener); - } + private void removeStateCallback(IVrStateCallbacks cb) { + mRemoteCallbacks.unregister(cb); } - private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) { + private boolean getVrMode() { synchronized (mLock) { - return mComponentObserver.isValid(targetPackageName, userId); + return mVrModeEnabled; } } } diff --git a/services/core/java/com/android/server/webkit/WebViewUtilityImpl.java b/services/core/java/com/android/server/webkit/SystemImpl.java index aaa7977208a1..9486cfdb87a0 100644 --- a/services/core/java/com/android/server/webkit/WebViewUtilityImpl.java +++ b/services/core/java/com/android/server/webkit/SystemImpl.java @@ -19,15 +19,22 @@ package com.android.server.webkit; import android.app.ActivityManagerNative; import android.app.AppGlobals; import android.content.Context; +import android.content.pm.IPackageDeleteObserver; import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.UserInfo; import android.content.res.XmlResourceParser; +import android.os.Build; import android.os.RemoteException; import android.os.UserHandle; +import android.os.UserManager; +import android.provider.Settings.Global; import android.provider.Settings; import android.util.AndroidRuntimeException; import android.util.Log; -import android.webkit.WebViewFactory; import android.webkit.WebViewFactory.MissingWebViewPackageException; +import android.webkit.WebViewFactory; import android.webkit.WebViewProviderInfo; import com.android.internal.util.XmlUtils; @@ -42,8 +49,8 @@ import org.xmlpull.v1.XmlPullParserException; * Default implementation for the WebView preparation Utility interface. * @hide */ -public class WebViewUtilityImpl implements WebViewUtilityInterface { - private static final String TAG = WebViewUtilityImpl.class.getSimpleName(); +public class SystemImpl implements SystemInterface { + private static final String TAG = SystemImpl.class.getSimpleName(); private static final String TAG_START = "webviewproviders"; private static final String TAG_WEBVIEW_PROVIDER = "webviewprovider"; private static final String TAG_PACKAGE_NAME = "packageName"; @@ -103,9 +110,7 @@ public class WebViewUtilityImpl implements WebViewUtilityInterface { Log.e(TAG, "Found an element that is not a webview provider"); } } - } catch(XmlPullParserException e) { - throw new MissingWebViewPackageException("Error when parsing WebView meta data " + e); - } catch(IOException e) { + } catch (XmlPullParserException | IOException e) { throw new MissingWebViewPackageException("Error when parsing WebView meta data " + e); } finally { if (parser != null) parser.close(); @@ -113,6 +118,11 @@ public class WebViewUtilityImpl implements WebViewUtilityInterface { return webViewProviders.toArray(new WebViewProviderInfo[webViewProviders.size()]); } + public int getFactoryPackageVersion(String packageName) throws NameNotFoundException { + PackageManager pm = AppGlobals.getInitialApplication().getPackageManager(); + return pm.getPackageInfo(packageName, PackageManager.MATCH_FACTORY_ONLY).versionCode; + } + /** * Reads all signatures at the current depth (within the current provider) from the XML parser. */ @@ -158,4 +168,70 @@ public class WebViewUtilityImpl implements WebViewUtilityInterface { } catch (RemoteException e) { } } + + @Override + public boolean isFallbackLogicEnabled() { + // Note that this is enabled by default (i.e. if the setting hasn't been set). + return Settings.Global.getInt(AppGlobals.getInitialApplication().getContentResolver(), + Settings.Global.WEBVIEW_FALLBACK_LOGIC_ENABLED, 1) == 1; + } + + @Override + public void enableFallbackLogic(boolean enable) { + Settings.Global.putInt(AppGlobals.getInitialApplication().getContentResolver(), + Settings.Global.WEBVIEW_FALLBACK_LOGIC_ENABLED, enable ? 1 : 0); + } + + @Override + public void uninstallAndDisablePackageForAllUsers(Context context, String packageName) { + enablePackageForAllUsers(context, packageName, false); + try { + PackageManager pm = AppGlobals.getInitialApplication().getPackageManager(); + if (pm.getApplicationInfo(packageName, 0).isUpdatedSystemApp()) { + pm.deletePackage(packageName, new IPackageDeleteObserver.Stub() { + public void packageDeleted(String packageName, int returnCode) { + enablePackageForAllUsers(context, packageName, false); + } + }, PackageManager.DELETE_SYSTEM_APP | PackageManager.DELETE_ALL_USERS); + } + } catch (NameNotFoundException e) { + } + } + + @Override + public void enablePackageForAllUsers(Context context, String packageName, boolean enable) { + UserManager userManager = (UserManager)context.getSystemService(Context.USER_SERVICE); + for(UserInfo userInfo : userManager.getUsers()) { + enablePackageForUser(packageName, enable, userInfo.id); + } + } + + @Override + public void enablePackageForUser(String packageName, boolean enable, int userId) { + try { + AppGlobals.getPackageManager().setApplicationEnabledSetting( + packageName, + enable ? PackageManager.COMPONENT_ENABLED_STATE_DEFAULT : + PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER, 0, + userId, null); + } catch (RemoteException e) { + Log.w(TAG, "Tried to disable " + packageName + " for user " + userId + ": " + e); + } + } + + @Override + public boolean systemIsDebuggable() { + return Build.IS_DEBUGGABLE; + } + + @Override + public PackageInfo getPackageInfoForProvider(WebViewProviderInfo configInfo) + throws NameNotFoundException { + PackageManager pm = AppGlobals.getInitialApplication().getPackageManager(); + return pm.getPackageInfo(configInfo.packageName, PACKAGE_FLAGS); + } + + // flags declaring we want extra info from the package manager for webview providers + private final static int PACKAGE_FLAGS = PackageManager.GET_META_DATA + | PackageManager.GET_SIGNATURES | PackageManager.MATCH_DEBUG_TRIAGED_MISSING; } diff --git a/services/core/java/com/android/server/webkit/WebViewUtilityInterface.java b/services/core/java/com/android/server/webkit/SystemInterface.java index 1919f400c29a..7bde37a5a4fd 100644 --- a/services/core/java/com/android/server/webkit/WebViewUtilityInterface.java +++ b/services/core/java/com/android/server/webkit/SystemInterface.java @@ -16,22 +16,36 @@ package com.android.server.webkit; -import android.webkit.WebViewProviderInfo; import android.content.Context; import android.content.pm.PackageInfo; +import android.content.pm.PackageManager.NameNotFoundException; +import android.webkit.WebViewProviderInfo; /** - * Utility interface for the WebViewUpdateService. + * System interface for the WebViewUpdateService. * This interface provides a way to test the WebView preparation mechanism - during normal use this * interface is implemented using calls to the Android framework, but by providing an alternative * implementation we can test the WebView preparation logic without reaching other framework code. + * * @hide */ -public interface WebViewUtilityInterface { +public interface SystemInterface { public WebViewProviderInfo[] getWebViewPackages(); public int onWebViewProviderChanged(PackageInfo packageInfo); + public int getFactoryPackageVersion(String packageName) throws NameNotFoundException; public String getUserChosenWebViewProvider(Context context); public void updateUserSetting(Context context, String newProviderName); public void killPackageDependents(String packageName); + + public boolean isFallbackLogicEnabled(); + public void enableFallbackLogic(boolean enable); + + public void uninstallAndDisablePackageForAllUsers(Context context, String packageName); + public void enablePackageForAllUsers(Context context, String packageName, boolean enable); + public void enablePackageForUser(String packageName, boolean enable, int userId); + + public boolean systemIsDebuggable(); + public PackageInfo getPackageInfoForProvider(WebViewProviderInfo configInfo) + throws NameNotFoundException; } diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java index c4f9cc125411..ebec44554210 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java @@ -16,30 +16,20 @@ package com.android.server.webkit; -import android.app.ActivityManagerNative; -import android.app.AppGlobals; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.ApplicationInfo; -import android.content.pm.IPackageDeleteObserver; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.Signature; -import android.content.pm.UserInfo; import android.os.Binder; -import android.os.Build; import android.os.PatternMatcher; import android.os.Process; -import android.os.RemoteException; import android.os.ResultReceiver; import android.os.UserHandle; -import android.os.UserManager; -import android.provider.Settings.Global; -import android.provider.Settings; -import android.util.AndroidRuntimeException; import android.util.Base64; import android.util.Slog; import android.webkit.IWebViewUpdateService; @@ -52,7 +42,6 @@ import com.android.server.SystemService; import java.io.FileDescriptor; import java.util.ArrayList; import java.util.Arrays; -import java.util.Iterator; import java.util.List; /** @@ -62,26 +51,21 @@ import java.util.List; public class WebViewUpdateService extends SystemService { private static final String TAG = "WebViewUpdateService"; - private static final int WAIT_TIMEOUT_MS = 4500; // KEY_DISPATCHING_TIMEOUT is 5000. - // Keeps track of the number of running relro creations - private int mNumRelroCreationsStarted = 0; - private int mNumRelroCreationsFinished = 0; - // Implies that we need to rerun relro creation because we are using an out-of-date package - private boolean mWebViewPackageDirty = false; - private boolean mAnyWebViewInstalled = false; - - private int NUMBER_OF_RELROS_UNKNOWN = Integer.MAX_VALUE; + private BroadcastReceiver mWebViewUpdatedReceiver; + private SystemInterface mSystemInterface; - // The WebView package currently in use (or the one we are preparing). - private PackageInfo mCurrentWebViewPackage = null; + static final int PACKAGE_CHANGED = 0; + static final int PACKAGE_ADDED = 1; + static final int PACKAGE_ADDED_REPLACED = 2; + static final int PACKAGE_REMOVED = 3; - private BroadcastReceiver mWebViewUpdatedReceiver; - private WebViewUtilityInterface mWebViewUtility; + private WebViewUpdater mWebViewUpdater; public WebViewUpdateService(Context context) { super(context); - mWebViewUtility = new WebViewUtilityImpl(); + mSystemInterface = new SystemImpl(); + mWebViewUpdater = new WebViewUpdater(getContext(), mSystemInterface); } @Override @@ -89,76 +73,34 @@ public class WebViewUpdateService extends SystemService { mWebViewUpdatedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { - // When a package is replaced we will receive two intents, one representing - // the removal of the old package and one representing the addition of the - // new package. - // In the case where we receive an intent to remove the old version of the - // package that is being replaced we early-out here so that we don't run the - // update-logic twice. - if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED) - && intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)) { - return; - } - - // Ensure that we only heed PACKAGE_CHANGED intents if they change an entire - // package, not just a component - if (intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED)) { - if (!WebViewFactory.entirePackageChanged(intent)) { - return; - } - } - - if (intent.getAction().equals(Intent.ACTION_USER_ADDED)) { - int userId = - intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); - handleNewUser(userId); - return; - } - - updateFallbackState(context, intent); - - for (WebViewProviderInfo provider : mWebViewUtility.getWebViewPackages()) { - String webviewPackage = "package:" + provider.packageName; - - if (webviewPackage.equals(intent.getDataString())) { - boolean updateWebView = false; - boolean removedOrChangedOldPackage = false; - String oldProviderName = null; - PackageInfo newPackage = null; - synchronized(WebViewUpdateService.this) { - try { - newPackage = findPreferredWebViewPackage(); - if (mCurrentWebViewPackage != null) - oldProviderName = mCurrentWebViewPackage.packageName; - // Only trigger update actions if the updated package is the one - // that will be used, or the one that was in use before the - // update, or if we haven't seen a valid WebView package before. - updateWebView = - provider.packageName.equals(newPackage.packageName) - || provider.packageName.equals(oldProviderName) - || mCurrentWebViewPackage == null; - // We removed the old package if we received an intent to remove - // or replace the old package. - removedOrChangedOldPackage = - provider.packageName.equals(oldProviderName); - if (updateWebView) { - onWebViewProviderChanged(newPackage); - } - } catch (WebViewFactory.MissingWebViewPackageException e) { - Slog.e(TAG, "Could not find valid WebView package to create " + - "relro with " + e); - } + switch (intent.getAction()) { + case Intent.ACTION_PACKAGE_REMOVED: + // When a package is replaced we will receive two intents, one + // representing the removal of the old package and one representing the + // addition of the new package. + // In the case where we receive an intent to remove the old version of + // the package that is being replaced we early-out here so that we don't + // run the update-logic twice. + if (intent.getExtras().getBoolean(Intent.EXTRA_REPLACING)) return; + packageStateChanged(packageNameFromIntent(intent), PACKAGE_REMOVED); + break; + case Intent.ACTION_PACKAGE_CHANGED: + // Ensure that we only heed PACKAGE_CHANGED intents if they change an + // entire package, not just a component + if (entirePackageChanged(intent)) { + packageStateChanged(packageNameFromIntent(intent), PACKAGE_CHANGED); } - if(updateWebView && !removedOrChangedOldPackage - && oldProviderName != null) { - // If the provider change is the result of adding or replacing a - // package that was not the previous provider then we must kill - // packages dependent on the old package ourselves. The framework - // only kills dependents of packages that are being removed. - mWebViewUtility.killPackageDependents(oldProviderName); - } - return; - } + break; + case Intent.ACTION_PACKAGE_ADDED: + packageStateChanged(packageNameFromIntent(intent), + (intent.getExtras().getBoolean(Intent.EXTRA_REPLACING) + ? PACKAGE_ADDED_REPLACED : PACKAGE_ADDED)); + break; + case Intent.ACTION_USER_ADDED: + int userId = + intent.getIntExtra(Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL); + handleNewUser(userId); + break; } } }; @@ -168,7 +110,7 @@ public class WebViewUpdateService extends SystemService { filter.addAction(Intent.ACTION_PACKAGE_CHANGED); filter.addDataScheme("package"); // Make sure we only receive intents for WebView packages from our config file. - for (WebViewProviderInfo provider : mWebViewUtility.getWebViewPackages()) { + for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) { filter.addDataSchemeSpecificPart(provider.packageName, PatternMatcher.PATTERN_LITERAL); } getContext().registerReceiver(mWebViewUpdatedReceiver, filter); @@ -180,12 +122,27 @@ public class WebViewUpdateService extends SystemService { publishBinderService("webviewupdate", new BinderService(), true /*allowIsolated*/); } + private void packageStateChanged(String packageName, int changedState) { + updateFallbackState(packageName, changedState); + mWebViewUpdater.packageStateChanged(packageName, changedState); + } + + public void prepareWebViewInSystemServer() { + updateFallbackStateOnBoot(); + mWebViewUpdater.prepareWebViewInSystemServer(); + } + + private static String packageNameFromIntent(Intent intent) { + return intent.getDataString().substring("package:".length()); + } + private boolean existsValidNonFallbackProvider(WebViewProviderInfo[] providers) { for (WebViewProviderInfo provider : providers) { if (provider.availableByDefault && !provider.isFallback) { try { - PackageInfo packageInfo = getPackageInfoForProvider(provider); - if (isEnabledPackage(packageInfo) && isValidProvider(provider, packageInfo)) { + PackageInfo packageInfo = mSystemInterface.getPackageInfoForProvider(provider); + if (isEnabledPackage(packageInfo) + && mWebViewUpdater.isValidProvider(provider, packageInfo)) { return true; } } catch (NameNotFoundException e) { @@ -196,59 +153,51 @@ public class WebViewUpdateService extends SystemService { return false; } - private static void enablePackageForUser(String packageName, boolean enable, int userId) { - try { - AppGlobals.getPackageManager().setApplicationEnabledSetting( - packageName, - enable ? PackageManager.COMPONENT_ENABLED_STATE_DEFAULT : - PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER, 0, - userId, null); - } catch (RemoteException e) { - Slog.w(TAG, "Tried to disable " + packageName + " for user " + userId + ": " + e); - } - } - /** * Called when a new user has been added to update the state of its fallback package. */ void handleNewUser(int userId) { - if (!isFallbackLogicEnabled()) return; + if (!mSystemInterface.isFallbackLogicEnabled()) return; - WebViewProviderInfo[] webviewProviders = mWebViewUtility.getWebViewPackages(); + WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages(); WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders); if (fallbackProvider == null) return; - enablePackageForUser(fallbackProvider.packageName, + mSystemInterface.enablePackageForUser(fallbackProvider.packageName, !existsValidNonFallbackProvider(webviewProviders), userId); } + public void updateFallbackStateOnBoot() { + WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages(); + updateFallbackState(webviewProviders, true); + } + /** * Handle the enabled-state of our fallback package, i.e. if there exists some non-fallback * package that is valid (and available by default) then disable the fallback package, * otherwise, enable the fallback package. */ - void updateFallbackState(final Context context, final Intent intent) { - if (!isFallbackLogicEnabled()) return; - - WebViewProviderInfo[] webviewProviders = mWebViewUtility.getWebViewPackages(); - - if (intent != null && (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED) - || intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED))) { - // A package was changed / updated / downgraded, early out if it is not one of the - // webview packages that are available by default. - String changedPackage = null; - for (WebViewProviderInfo provider : webviewProviders) { - String webviewPackage = "package:" + provider.packageName; - if (webviewPackage.equals(intent.getDataString())) { - if (provider.availableByDefault) { - changedPackage = provider.packageName; - } - break; + public void updateFallbackState(String changedPackage, int changedState) { + if (!mSystemInterface.isFallbackLogicEnabled()) return; + + WebViewProviderInfo[] webviewProviders = mSystemInterface.getWebViewPackages(); + + // A package was changed / updated / downgraded, early out if it is not one of the + // webview packages that are available by default. + boolean changedPackageAvailableByDefault = false; + for (WebViewProviderInfo provider : webviewProviders) { + if (provider.packageName.equals(changedPackage)) { + if (provider.availableByDefault) { + changedPackageAvailableByDefault = true; } + break; } - if (changedPackage == null) return; } + if (!changedPackageAvailableByDefault) return; + updateFallbackState(webviewProviders, false); + } + private void updateFallbackState(WebViewProviderInfo[] webviewProviders, boolean isBoot) { // If there exists a valid and enabled non-fallback package - disable the fallback // package, otherwise, enable it. WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewProviders); @@ -257,55 +206,29 @@ public class WebViewUpdateService extends SystemService { boolean isFallbackEnabled = false; try { - isFallbackEnabled = isEnabledPackage(getPackageInfoForProvider(fallbackProvider)); + isFallbackEnabled = isEnabledPackage( + mSystemInterface.getPackageInfoForProvider(fallbackProvider)); } catch (NameNotFoundException e) { } if (existsValidNonFallbackProvider // During an OTA the primary user's WebView state might differ from other users', so // ignore the state of that user during boot. - && (isFallbackEnabled || intent == null)) { - // Uninstall and disable fallback package for all users. - context.getPackageManager().deletePackage(fallbackProvider.packageName, - new IPackageDeleteObserver.Stub() { - public void packageDeleted(String packageName, int returnCode) { - // Ignore returnCode since the deletion could fail, e.g. we might be trying - // to delete a non-updated system-package (and we should still disable the - // package) - UserManager userManager = - (UserManager)context.getSystemService(Context.USER_SERVICE); - // Disable the fallback package for all users. - for(UserInfo userInfo : userManager.getUsers()) { - enablePackageForUser(packageName, false, userInfo.id); - } - } - }, PackageManager.DELETE_SYSTEM_APP | PackageManager.DELETE_ALL_USERS); + && (isFallbackEnabled || isBoot)) { + mSystemInterface.uninstallAndDisablePackageForAllUsers(getContext(), + fallbackProvider.packageName); } else if (!existsValidNonFallbackProvider // During an OTA the primary user's WebView state might differ from other users', so // ignore the state of that user during boot. - && (!isFallbackEnabled || intent==null)) { + && (!isFallbackEnabled || isBoot)) { // Enable the fallback package for all users. - UserManager userManager = - (UserManager)context.getSystemService(Context.USER_SERVICE); - for(UserInfo userInfo : userManager.getUsers()) { - enablePackageForUser(fallbackProvider.packageName, true, userInfo.id); - } + mSystemInterface.enablePackageForAllUsers(getContext(), + fallbackProvider.packageName, true); } } - private static boolean isFallbackLogicEnabled() { - // Note that this is enabled by default (i.e. if the setting hasn't been set). - return Settings.Global.getInt(AppGlobals.getInitialApplication().getContentResolver(), - Settings.Global.WEBVIEW_FALLBACK_LOGIC_ENABLED, 1) == 1; - } - - private static void enableFallbackLogic(boolean enable) { - Settings.Global.putInt(AppGlobals.getInitialApplication().getContentResolver(), - Settings.Global.WEBVIEW_FALLBACK_LOGIC_ENABLED, enable ? 1 : 0); - } - /** - * Returns the only fallback provider, or null if there is none. + * Returns the only fallback provider in the set of given packages, or null if there is none. */ private static WebViewProviderInfo getFallbackProvider(WebViewProviderInfo[] webviewPackages) { for (WebViewProviderInfo provider : webviewPackages) { @@ -317,188 +240,372 @@ public class WebViewUpdateService extends SystemService { } private boolean isFallbackPackage(String packageName) { - if (packageName == null || !isFallbackLogicEnabled()) return false; + if (packageName == null || !mSystemInterface.isFallbackLogicEnabled()) return false; - WebViewProviderInfo[] webviewPackages = mWebViewUtility.getWebViewPackages(); + WebViewProviderInfo[] webviewPackages = mSystemInterface.getWebViewPackages(); WebViewProviderInfo fallbackProvider = getFallbackProvider(webviewPackages); return (fallbackProvider != null && packageName.equals(fallbackProvider.packageName)); } /** - * Perform any WebView loading preparations that must happen at boot from the system server, - * after the package manager has started or after an update to the webview is installed. - * This must be called in the system server. - * Currently, this means spawning the child processes which will create the relro files. + * Class that decides what WebView implementation to use and prepares that implementation for + * use. */ - public void prepareWebViewInSystemServer() { - updateFallbackState(getContext(), null); - try { - synchronized(this) { - mCurrentWebViewPackage = findPreferredWebViewPackage(); - onWebViewProviderChanged(mCurrentWebViewPackage); - } - } catch (Throwable t) { - // Log and discard errors at this stage as we must not crash the system server. - Slog.e(TAG, "error preparing webview provider from system server", t); + private static class WebViewUpdater { + private Context mContext; + private SystemInterface mSystemInterface; + private int mMinimumVersionCode = -1; + + public WebViewUpdater(Context context, SystemInterface systemInterface) { + mContext = context; + mSystemInterface = systemInterface; } - } - - /** - * Change WebView provider and provider setting and kill packages using the old provider. - * Return the new provider (in case we are in the middle of creating relro files this new - * provider will not be in use directly, but will when the relros are done). - */ - private String changeProviderAndSetting(String newProviderName) { - PackageInfo oldPackage = null; - PackageInfo newPackage = null; - synchronized(this) { - oldPackage = mCurrentWebViewPackage; - mWebViewUtility.updateUserSetting(getContext(), newProviderName); + private static final int WAIT_TIMEOUT_MS = 4500; // KEY_DISPATCHING_TIMEOUT is 5000. + + // Keeps track of the number of running relro creations + private int mNumRelroCreationsStarted = 0; + private int mNumRelroCreationsFinished = 0; + // Implies that we need to rerun relro creation because we are using an out-of-date package + private boolean mWebViewPackageDirty = false; + private boolean mAnyWebViewInstalled = false; + + private int NUMBER_OF_RELROS_UNKNOWN = Integer.MAX_VALUE; + + // The WebView package currently in use (or the one we are preparing). + private PackageInfo mCurrentWebViewPackage = null; + + private Object mLock = new Object(); + + public void packageStateChanged(String packageName, int changedState) { + for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) { + String webviewPackage = provider.packageName; + + if (webviewPackage.equals(packageName)) { + boolean updateWebView = false; + boolean removedOrChangedOldPackage = false; + String oldProviderName = null; + PackageInfo newPackage = null; + synchronized(mLock) { + try { + newPackage = findPreferredWebViewPackage(); + if (mCurrentWebViewPackage != null) + oldProviderName = mCurrentWebViewPackage.packageName; + // Only trigger update actions if the updated package is the one + // that will be used, or the one that was in use before the + // update, or if we haven't seen a valid WebView package before. + updateWebView = + provider.packageName.equals(newPackage.packageName) + || provider.packageName.equals(oldProviderName) + || mCurrentWebViewPackage == null; + // We removed the old package if we received an intent to remove + // or replace the old package. + removedOrChangedOldPackage = + provider.packageName.equals(oldProviderName); + if (updateWebView) { + onWebViewProviderChanged(newPackage); + } + } catch (WebViewFactory.MissingWebViewPackageException e) { + Slog.e(TAG, "Could not find valid WebView package to create " + + "relro with " + e); + } + } + if(updateWebView && !removedOrChangedOldPackage + && oldProviderName != null) { + // If the provider change is the result of adding or replacing a + // package that was not the previous provider then we must kill + // packages dependent on the old package ourselves. The framework + // only kills dependents of packages that are being removed. + mSystemInterface.killPackageDependents(oldProviderName); + } + return; + } + } + } + public void prepareWebViewInSystemServer() { try { - newPackage = findPreferredWebViewPackage(); - if (oldPackage != null && newPackage.packageName.equals(oldPackage.packageName)) { - // If we don't perform the user change, revert the settings change. - mWebViewUtility.updateUserSetting(getContext(), newPackage.packageName); - return newPackage.packageName; + synchronized(mLock) { + mCurrentWebViewPackage = findPreferredWebViewPackage(); + onWebViewProviderChanged(mCurrentWebViewPackage); } - } catch (WebViewFactory.MissingWebViewPackageException e) { - Slog.e(TAG, "Tried to change WebView provider but failed to fetch WebView package " - + e); - // If we don't perform the user change but don't have an installed WebView package, - // we will have changed the setting and it will be used when a package is available. - return newProviderName; + } catch (Throwable t) { + // Log and discard errors at this stage as we must not crash the system server. + Slog.e(TAG, "error preparing webview provider from system server", t); } - onWebViewProviderChanged(newPackage); } - // Kill apps using the old provider - if (oldPackage != null) { - mWebViewUtility.killPackageDependents(oldPackage.packageName); + + /** + * Change WebView provider and provider setting and kill packages using the old provider. + * Return the new provider (in case we are in the middle of creating relro files this new + * provider will not be in use directly, but will when the relros are done). + */ + public String changeProviderAndSetting(String newProviderName) { + PackageInfo oldPackage = null; + PackageInfo newPackage = null; + synchronized(mLock) { + oldPackage = mCurrentWebViewPackage; + mSystemInterface.updateUserSetting(mContext, newProviderName); + + try { + newPackage = findPreferredWebViewPackage(); + if (oldPackage != null + && newPackage.packageName.equals(oldPackage.packageName)) { + // If we don't perform the user change, revert the settings change. + mSystemInterface.updateUserSetting(mContext, newPackage.packageName); + return newPackage.packageName; + } + } catch (WebViewFactory.MissingWebViewPackageException e) { + Slog.e(TAG, "Tried to change WebView provider but failed to fetch WebView " + + "package " + e); + // If we don't perform the user change but don't have an installed WebView + // package, we will have changed the setting and it will be used when a package + // is available. + return newProviderName; + } + onWebViewProviderChanged(newPackage); + } + // Kill apps using the old provider + if (oldPackage != null) { + mSystemInterface.killPackageDependents(oldPackage.packageName); + } + return newPackage.packageName; } - return newPackage.packageName; - } - /** - * This is called when we change WebView provider, either when the current provider is updated - * or a new provider is chosen / takes precedence. - */ - private void onWebViewProviderChanged(PackageInfo newPackage) { - synchronized(this) { - mAnyWebViewInstalled = true; - if (mNumRelroCreationsStarted == mNumRelroCreationsFinished) { - mCurrentWebViewPackage = newPackage; - mWebViewUtility.updateUserSetting(getContext(), newPackage.packageName); - - // The relro creations might 'finish' (not start at all) before - // WebViewFactory.onWebViewProviderChanged which means we might not know the number - // of started creations before they finish. - mNumRelroCreationsStarted = NUMBER_OF_RELROS_UNKNOWN; - mNumRelroCreationsFinished = 0; - mNumRelroCreationsStarted = mWebViewUtility.onWebViewProviderChanged(newPackage); - // If the relro creations finish before we know the number of started creations we - // will have to do any cleanup/notifying here. - checkIfRelrosDoneLocked(); - } else { - mWebViewPackageDirty = true; + /** + * This is called when we change WebView provider, either when the current provider is + * updated or a new provider is chosen / takes precedence. + */ + private void onWebViewProviderChanged(PackageInfo newPackage) { + synchronized(mLock) { + mAnyWebViewInstalled = true; + if (mNumRelroCreationsStarted == mNumRelroCreationsFinished) { + mCurrentWebViewPackage = newPackage; + mSystemInterface.updateUserSetting(mContext, newPackage.packageName); + + // The relro creations might 'finish' (not start at all) before + // WebViewFactory.onWebViewProviderChanged which means we might not know the + // number of started creations before they finish. + mNumRelroCreationsStarted = NUMBER_OF_RELROS_UNKNOWN; + mNumRelroCreationsFinished = 0; + mNumRelroCreationsStarted = + mSystemInterface.onWebViewProviderChanged(newPackage); + // If the relro creations finish before we know the number of started creations + // we will have to do any cleanup/notifying here. + checkIfRelrosDoneLocked(); + } else { + mWebViewPackageDirty = true; + } } } - } - private ProviderAndPackageInfo[] getValidWebViewPackagesAndInfos() { - WebViewProviderInfo[] allProviders = mWebViewUtility.getWebViewPackages(); - List<ProviderAndPackageInfo> providers = new ArrayList<>(); - for(int n = 0; n < allProviders.length; n++) { - try { - PackageInfo packageInfo = getPackageInfoForProvider(allProviders[n]); - if (isValidProvider(allProviders[n], packageInfo)) { - providers.add(new ProviderAndPackageInfo(allProviders[n], packageInfo)); + private ProviderAndPackageInfo[] getValidWebViewPackagesAndInfos() { + WebViewProviderInfo[] allProviders = mSystemInterface.getWebViewPackages(); + List<ProviderAndPackageInfo> providers = new ArrayList<>(); + for(int n = 0; n < allProviders.length; n++) { + try { + PackageInfo packageInfo = + mSystemInterface.getPackageInfoForProvider(allProviders[n]); + if (isValidProvider(allProviders[n], packageInfo)) { + providers.add(new ProviderAndPackageInfo(allProviders[n], packageInfo)); + } + } catch (NameNotFoundException e) { + // Don't add non-existent packages } - } catch (NameNotFoundException e) { - // Don't add non-existent packages } + return providers.toArray(new ProviderAndPackageInfo[providers.size()]); } - return providers.toArray(new ProviderAndPackageInfo[providers.size()]); - } - /** - * Fetch only the currently valid WebView packages. - **/ - private WebViewProviderInfo[] getValidWebViewPackages() { - ProviderAndPackageInfo[] providersAndPackageInfos = getValidWebViewPackagesAndInfos(); - WebViewProviderInfo[] providers = new WebViewProviderInfo[providersAndPackageInfos.length]; - for(int n = 0; n < providersAndPackageInfos.length; n++) { - providers[n] = providersAndPackageInfos[n].provider; - } - return providers; - } + /** + * Fetch only the currently valid WebView packages. + **/ + public WebViewProviderInfo[] getValidWebViewPackages() { + ProviderAndPackageInfo[] providersAndPackageInfos = getValidWebViewPackagesAndInfos(); + WebViewProviderInfo[] providers = + new WebViewProviderInfo[providersAndPackageInfos.length]; + for(int n = 0; n < providersAndPackageInfos.length; n++) { + providers[n] = providersAndPackageInfos[n].provider; + } + return providers; + } - private class ProviderAndPackageInfo { - public final WebViewProviderInfo provider; - public final PackageInfo packageInfo; - public ProviderAndPackageInfo(WebViewProviderInfo provider, PackageInfo packageInfo) { - this.provider = provider; - this.packageInfo = packageInfo; + private class ProviderAndPackageInfo { + public final WebViewProviderInfo provider; + public final PackageInfo packageInfo; + + public ProviderAndPackageInfo(WebViewProviderInfo provider, PackageInfo packageInfo) { + this.provider = provider; + this.packageInfo = packageInfo; + } } - } - /** - * Returns either the package info of the WebView provider determined in the following way: - * If the user has chosen a provider then use that if it is valid, - * otherwise use the first package in the webview priority list that is valid. - * - * @hide - */ - private PackageInfo findPreferredWebViewPackage() { - ProviderAndPackageInfo[] providers = getValidWebViewPackagesAndInfos(); + /** + * Returns either the package info of the WebView provider determined in the following way: + * If the user has chosen a provider then use that if it is valid, + * otherwise use the first package in the webview priority list that is valid. + * + */ + private PackageInfo findPreferredWebViewPackage() { + ProviderAndPackageInfo[] providers = getValidWebViewPackagesAndInfos(); - String userChosenProvider = mWebViewUtility.getUserChosenWebViewProvider(getContext()); + String userChosenProvider = mSystemInterface.getUserChosenWebViewProvider(mContext); - // If the user has chosen provider, use that - for (ProviderAndPackageInfo providerAndPackage : providers) { - if (providerAndPackage.provider.packageName.equals(userChosenProvider) - && isEnabledPackage(providerAndPackage.packageInfo)) { + // If the user has chosen provider, use that + for (ProviderAndPackageInfo providerAndPackage : providers) { + if (providerAndPackage.provider.packageName.equals(userChosenProvider) + && isEnabledPackage(providerAndPackage.packageInfo)) { + return providerAndPackage.packageInfo; + } + } + + // User did not choose, or the choice failed; use the most stable provider that is + // enabled and available by default (not through user choice). + for (ProviderAndPackageInfo providerAndPackage : providers) { + if (providerAndPackage.provider.availableByDefault + && isEnabledPackage(providerAndPackage.packageInfo)) { + return providerAndPackage.packageInfo; + } + } + + // Could not find any enabled package either, use the most stable provider. + for (ProviderAndPackageInfo providerAndPackage : providers) { return providerAndPackage.packageInfo; } + + mAnyWebViewInstalled = false; + throw new WebViewFactory.MissingWebViewPackageException( + "Could not find a loadable WebView package"); } - // User did not choose, or the choice failed; use the most stable provider that is - // enabled and available by default (not through user choice). - for (ProviderAndPackageInfo providerAndPackage : providers) { - if (providerAndPackage.provider.availableByDefault - && isEnabledPackage(providerAndPackage.packageInfo)) { - return providerAndPackage.packageInfo; + public void notifyRelroCreationCompleted() { + synchronized (mLock) { + mNumRelroCreationsFinished++; + checkIfRelrosDoneLocked(); } } - // Could not find any enabled package either, use the most stable provider. - for (ProviderAndPackageInfo providerAndPackage : providers) { - return providerAndPackage.packageInfo; + public WebViewProviderResponse waitForAndGetProvider() { + PackageInfo webViewPackage = null; + final long NS_PER_MS = 1000000; + final long timeoutTimeMs = System.nanoTime() / NS_PER_MS + WAIT_TIMEOUT_MS; + boolean webViewReady = false; + int webViewStatus = WebViewFactory.LIBLOAD_SUCCESS; + synchronized (mLock) { + webViewReady = webViewIsReadyLocked(); + while (!webViewReady) { + final long timeNowMs = System.nanoTime() / NS_PER_MS; + if (timeNowMs >= timeoutTimeMs) break; + try { + mLock.wait(timeoutTimeMs - timeNowMs); + } catch (InterruptedException e) {} + webViewReady = webViewIsReadyLocked(); + } + // Make sure we return the provider that was used to create the relro file + webViewPackage = mCurrentWebViewPackage; + if (webViewReady) { + } else if (!mAnyWebViewInstalled) { + webViewStatus = WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES; + } else { + // Either the current relro creation isn't done yet, or the new relro creatioin + // hasn't kicked off yet (the last relro creation used an out-of-date WebView). + webViewStatus = WebViewFactory.LIBLOAD_FAILED_WAITING_FOR_RELRO; + } + } + if (!webViewReady) Slog.w(TAG, "creating relro file timed out"); + return new WebViewProviderResponse(webViewPackage, webViewStatus); } - mAnyWebViewInstalled = false; - throw new WebViewFactory.MissingWebViewPackageException( - "Could not find a loadable WebView package"); - } + public String getCurrentWebViewPackageName() { + synchronized(mLock) { + if (mCurrentWebViewPackage == null) + return null; + return mCurrentWebViewPackage.packageName; + } + } - /** - * Returns whether this provider is valid for use as a WebView provider. - */ - private static boolean isValidProvider(WebViewProviderInfo configInfo, - PackageInfo packageInfo) { - if (providerHasValidSignature(configInfo, packageInfo) && - WebViewFactory.getWebViewLibrary(packageInfo.applicationInfo) != null) { - return true; + /** + * Returns whether WebView is ready and is not going to go through its preparation phase + * again directly. + */ + private boolean webViewIsReadyLocked() { + return !mWebViewPackageDirty + && (mNumRelroCreationsStarted == mNumRelroCreationsFinished) + // The current package might be replaced though we haven't received an intent + // declaring this yet, the following flag makes anyone loading WebView to wait in + // this case. + && mAnyWebViewInstalled; + } + + private void checkIfRelrosDoneLocked() { + if (mNumRelroCreationsStarted == mNumRelroCreationsFinished) { + if (mWebViewPackageDirty) { + mWebViewPackageDirty = false; + // If we have changed provider since we started the relro creation we need to + // redo the whole process using the new package instead. + PackageInfo newPackage = findPreferredWebViewPackage(); + onWebViewProviderChanged(newPackage); + } else { + mLock.notifyAll(); + } + } + } + + /** + * Returns whether this provider is valid for use as a WebView provider. + */ + public boolean isValidProvider(WebViewProviderInfo configInfo, + PackageInfo packageInfo) { + if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 + && packageInfo.versionCode < getMinimumVersionCode() + && !mSystemInterface.systemIsDebuggable()) { + // Non-system package webview providers may be downgraded arbitrarily low, prevent + // that by enforcing minimum version code. This check is only enforced for user + // builds. + return false; + } + if (providerHasValidSignature(configInfo, packageInfo, mSystemInterface) && + WebViewFactory.getWebViewLibrary(packageInfo.applicationInfo) != null) { + return true; + } + return false; + } + + /** + * Gets the minimum version code allowed for a valid provider. It is the minimum versionCode + * of all available-by-default and non-fallback WebView provider packages. If there is no + * such WebView provider package on the system, then return -1, which means all positive + * versionCode WebView packages are accepted. + */ + private int getMinimumVersionCode() { + if (mMinimumVersionCode > 0) { + return mMinimumVersionCode; + } + + for (WebViewProviderInfo provider : mSystemInterface.getWebViewPackages()) { + if (provider.availableByDefault && !provider.isFallback) { + try { + int versionCode = + mSystemInterface.getFactoryPackageVersion(provider.packageName); + if (mMinimumVersionCode < 0 || versionCode < mMinimumVersionCode) { + mMinimumVersionCode = versionCode; + } + } catch (PackageManager.NameNotFoundException e) { + // Safe to ignore. + } + } + } + + return mMinimumVersionCode; } - return false; } private static boolean providerHasValidSignature(WebViewProviderInfo provider, - PackageInfo packageInfo) { - if (Build.IS_DEBUGGABLE) + PackageInfo packageInfo, SystemInterface systemInterface) { + if (systemInterface.systemIsDebuggable()) { return true; + } Signature[] packageSignatures; // If no signature is declared, instead check whether the package is included in the // system. @@ -527,40 +634,16 @@ public class WebViewUpdateService extends SystemService { return packageInfo.applicationInfo.enabled; } - private static PackageInfo getPackageInfoForProvider(WebViewProviderInfo configInfo) - throws NameNotFoundException { - PackageManager pm = AppGlobals.getInitialApplication().getPackageManager(); - return pm.getPackageInfo(configInfo.packageName, PACKAGE_FLAGS); - } - - // flags declaring we want extra info from the package manager for webview providers - private final static int PACKAGE_FLAGS = PackageManager.GET_META_DATA - | PackageManager.GET_SIGNATURES | PackageManager.MATCH_DEBUG_TRIAGED_MISSING; - /** - * Returns whether WebView is ready and is not going to go through its preparation phase again - * directly. + * Returns whether the entire package from an ACTION_PACKAGE_CHANGED intent was changed (rather + * than just one of its components). + * @hide */ - private boolean webViewIsReadyLocked() { - return !mWebViewPackageDirty - && (mNumRelroCreationsStarted == mNumRelroCreationsFinished) - // The current package might be replaced though we haven't received an intent declaring - // this yet, the following flag makes anyone loading WebView to wait in this case. - && mAnyWebViewInstalled; - } - - private void checkIfRelrosDoneLocked() { - if (mNumRelroCreationsStarted == mNumRelroCreationsFinished) { - if (mWebViewPackageDirty) { - mWebViewPackageDirty = false; - // If we have changed provider since we started the relro creation we need to - // redo the whole process using the new package instead. - PackageInfo newPackage = findPreferredWebViewPackage(); - onWebViewProviderChanged(newPackage); - } else { - this.notifyAll(); - } - } + public static boolean entirePackageChanged(Intent intent) { + String[] componentList = + intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST); + return Arrays.asList(componentList).contains( + intent.getDataString().substring("package:".length())); } private class BinderService extends IWebViewUpdateService.Stub { @@ -590,10 +673,7 @@ public class WebViewUpdateService extends SystemService { long callingId = Binder.clearCallingIdentity(); try { - synchronized (WebViewUpdateService.this) { - mNumRelroCreationsFinished++; - checkIfRelrosDoneLocked(); - } + WebViewUpdateService.this.mWebViewUpdater.notifyRelroCreationCompleted(); } finally { Binder.restoreCallingIdentity(callingId); } @@ -613,34 +693,7 @@ public class WebViewUpdateService extends SystemService { throw new IllegalStateException("Cannot create a WebView from the SystemServer"); } - PackageInfo webViewPackage = null; - final long NS_PER_MS = 1000000; - final long timeoutTimeMs = System.nanoTime() / NS_PER_MS + WAIT_TIMEOUT_MS; - boolean webViewReady = false; - int webViewStatus = WebViewFactory.LIBLOAD_SUCCESS; - synchronized (WebViewUpdateService.this) { - webViewReady = WebViewUpdateService.this.webViewIsReadyLocked(); - while (!webViewReady) { - final long timeNowMs = System.nanoTime() / NS_PER_MS; - if (timeNowMs >= timeoutTimeMs) break; - try { - WebViewUpdateService.this.wait(timeoutTimeMs - timeNowMs); - } catch (InterruptedException e) {} - webViewReady = WebViewUpdateService.this.webViewIsReadyLocked(); - } - // Make sure we return the provider that was used to create the relro file - webViewPackage = WebViewUpdateService.this.mCurrentWebViewPackage; - if (webViewReady) { - } else if (!mAnyWebViewInstalled) { - webViewStatus = WebViewFactory.LIBLOAD_FAILED_LISTING_WEBVIEW_PACKAGES; - } else { - // Either the current relro creation isn't done yet, or the new relro creatioin - // hasn't kicked off yet (the last relro creation used an out-of-date WebView). - webViewStatus = WebViewFactory.LIBLOAD_FAILED_WAITING_FOR_RELRO; - } - } - if (!webViewReady) Slog.w(TAG, "creating relro file timed out"); - return new WebViewProviderResponse(webViewPackage, webViewStatus); + return WebViewUpdateService.this.mWebViewUpdater.waitForAndGetProvider(); } /** @@ -659,26 +712,28 @@ public class WebViewUpdateService extends SystemService { throw new SecurityException(msg); } - return WebViewUpdateService.this.changeProviderAndSetting(newProvider); + long callingId = Binder.clearCallingIdentity(); + try { + return WebViewUpdateService.this.mWebViewUpdater.changeProviderAndSetting( + newProvider); + } finally { + Binder.restoreCallingIdentity(callingId); + } } @Override // Binder call public WebViewProviderInfo[] getValidWebViewPackages() { - return WebViewUpdateService.this.getValidWebViewPackages(); + return WebViewUpdateService.this.mWebViewUpdater.getValidWebViewPackages(); } @Override // Binder call public WebViewProviderInfo[] getAllWebViewPackages() { - return WebViewUpdateService.this.mWebViewUtility.getWebViewPackages(); + return WebViewUpdateService.this.mSystemInterface.getWebViewPackages(); } @Override // Binder call public String getCurrentWebViewPackageName() { - synchronized(WebViewUpdateService.this) { - if (WebViewUpdateService.this.mCurrentWebViewPackage == null) - return null; - return WebViewUpdateService.this.mCurrentWebViewPackage.packageName; - } + return WebViewUpdateService.this.mWebViewUpdater.getCurrentWebViewPackageName(); } @Override // Binder call @@ -699,7 +754,7 @@ public class WebViewUpdateService extends SystemService { throw new SecurityException(msg); } - WebViewUpdateService.enableFallbackLogic(enable); + WebViewUpdateService.this.mSystemInterface.enableFallbackLogic(enable); } } } diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java index a9461e82a596..68448f30b82d 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceShellCommand.java @@ -36,12 +36,13 @@ class WebViewUpdateServiceShellCommand extends ShellCommand { final PrintWriter pw = getOutPrintWriter(); try { - // TODO(gsennton) add command for changing WebView provider switch(cmd) { case "enable-redundant-packages": return enableFallbackLogic(false); case "disable-redundant-packages": return enableFallbackLogic(true); + case "set-webview-implementation": + return setWebViewImplementation(); default: return handleDefaultCommands(cmd); } @@ -58,6 +59,21 @@ class WebViewUpdateServiceShellCommand extends ShellCommand { return 0; } + private int setWebViewImplementation() throws RemoteException { + final PrintWriter pw = getOutPrintWriter(); + String shellChosenPackage = getNextArg(); + String newPackage = mInterface.changeProviderAndSetting(shellChosenPackage); + if (shellChosenPackage.equals(newPackage)) { + pw.println("Success"); + return 0; + } else { + pw.println(String.format( + "Failed to switch to %s, the WebView implementation is now provided by %s.", + shellChosenPackage, newPackage)); + return 1; + } + } + @Override public void onHelp() { PrintWriter pw = getOutPrintWriter(); @@ -72,6 +88,8 @@ class WebViewUpdateServiceShellCommand extends ShellCommand { pw.println(" disable-redundant-packages"); pw.println(" Disallow installing and enabling fallback packages when a more-preferred"); pw.println(" package is available."); + pw.println(" set-webview-implementation PACKAGE"); + pw.println(" Set the WebView implementation to the specified package."); pw.println(); } } diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index b501398c7d57..bae628ab1892 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -39,6 +39,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.Looper; import android.os.Message; +import android.text.TextUtils; import android.util.ArraySet; import android.util.Log; import android.util.Slog; @@ -1213,6 +1214,8 @@ final class AccessibilityController { window.type = windowState.mAttrs.type; window.layer = windowState.mLayer; window.token = windowState.mClient.asBinder(); + window.title = windowState.mAttrs.getTitle(); + window.accessibilityIdOfAnchor = windowState.mAttrs.accessibilityIdOfAnchor; WindowState attachedWindow = windowState.mAttachedWindow; if (attachedWindow != null) { @@ -1285,6 +1288,12 @@ final class AccessibilityController { && !oldWindow.childTokens.equals(newWindow.childTokens)) { return true; } + if (!TextUtils.equals(oldWindow.title, newWindow.title)) { + return true; + } + if (oldWindow.accessibilityIdOfAnchor != newWindow.accessibilityIdOfAnchor) { + return true; + } return false; } diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java index d6842787eef5..11b01ccb9c68 100644 --- a/services/core/java/com/android/server/wm/AppTransition.java +++ b/services/core/java/com/android/server/wm/AppTransition.java @@ -881,7 +881,7 @@ public class AppTransition implements Dump { * when a thumbnail is specified with the pending animation override. */ Animation createThumbnailAspectScaleAnimationLocked(Rect appRect, @Nullable Rect contentInsets, - Bitmap thumbnailHeader, final int taskId, int orientation) { + Bitmap thumbnailHeader, final int taskId, int uiMode, int orientation) { Animation a; final int thumbWidthI = thumbnailHeader.getWidth(); final float thumbWidth = thumbWidthI > 0 ? thumbWidthI : 1; @@ -896,7 +896,7 @@ public class AppTransition implements Dump { final float toY; final float pivotX; final float pivotY; - if (orientation == Configuration.ORIENTATION_PORTRAIT) { + if (isTvUiMode(uiMode) || orientation == Configuration.ORIENTATION_PORTRAIT) { fromX = mTmpRect.left; fromY = mTmpRect.top; @@ -1028,7 +1028,7 @@ public class AppTransition implements Dump { * activity that is leaving, and the activity that is entering. */ Animation createAspectScaledThumbnailEnterExitAnimationLocked(int thumbTransitState, - int orientation, int transit, Rect containingFrame, Rect contentInsets, + int uiMode, int orientation, int transit, Rect containingFrame, Rect contentInsets, @Nullable Rect surfaceInsets, boolean freeform, int taskId) { Animation a; final int appWidth = containingFrame.width(); @@ -1067,8 +1067,7 @@ public class AppTransition implements Dump { mTmpFromClipRect.inset(contentInsets); mNextAppTransitionInsets.set(contentInsets); - if (orientation == Configuration.ORIENTATION_PORTRAIT) { - // We scale the width and clip to the top/left square + if (isTvUiMode(uiMode) || orientation == Configuration.ORIENTATION_PORTRAIT) { // We scale the width and clip to the top/left square float scale = thumbWidth / (appWidth - contentInsets.left - contentInsets.right); @@ -1401,7 +1400,7 @@ public class AppTransition implements Dump { * to the recents thumbnail and hence need to account for the surface being * bigger. */ - Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter, + Animation loadAnimation(WindowManager.LayoutParams lp, int transit, boolean enter, int uiMode, int orientation, Rect frame, Rect displayFrame, Rect insets, @Nullable Rect surfaceInsets, boolean isVoiceInteraction, boolean freeform, int taskId) { @@ -1481,7 +1480,7 @@ public class AppTransition implements Dump { mNextAppTransitionScaleUp = (mNextAppTransitionType == NEXT_TRANSIT_TYPE_THUMBNAIL_ASPECT_SCALE_UP); a = createAspectScaledThumbnailEnterExitAnimationLocked( - getThumbnailTransitionState(enter), orientation, transit, frame, + getThumbnailTransitionState(enter), uiMode, orientation, transit, frame, insets, surfaceInsets, freeform, taskId); if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { String animName = mNextAppTransitionScaleUp ? @@ -1922,4 +1921,11 @@ public class AppTransition implements Dump { } return prepared; } + + /** + * @return whether the specified {@param uiMode} is the TV mode. + */ + private boolean isTvUiMode(int uiMode) { + return (uiMode & Configuration.UI_MODE_TYPE_TELEVISION) > 0; + } } diff --git a/services/core/java/com/android/server/wm/DimLayerController.java b/services/core/java/com/android/server/wm/DimLayerController.java index 97d0ae0f8546..3ec02b9f66fc 100644 --- a/services/core/java/com/android/server/wm/DimLayerController.java +++ b/services/core/java/com/android/server/wm/DimLayerController.java @@ -183,7 +183,12 @@ class DimLayerController { for (int i = mState.size() - 1; i >= 0; i--) { DimLayer.DimLayerUser user = mState.keyAt(i); - if (user.isFullscreen()) { + DimLayerState state = mState.valueAt(i); + // We have to check that we are acutally the shared fullscreen layer + // for this path. If we began as non fullscreen and became fullscreen + // (e.g. Docked stack closing), then we may not be the shared layer + // and we have to make sure we always animate the layer. + if (user.isFullscreen() && state.dimLayer == mSharedFullScreenDimLayer) { fullScreen = i; if (mState.valueAt(i).continueDimming) { fullScreenAndDimming = i; diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java index 68ea4df0c0b0..6ac71c795ca7 100644 --- a/services/core/java/com/android/server/wm/DockedStackDividerController.java +++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java @@ -76,8 +76,8 @@ public class DockedStackDividerController implements DimLayerUser { private final WindowManagerService mService; private final DisplayContent mDisplayContent; - private final int mDividerWindowWidth; - private final int mDividerInsets; + private int mDividerWindowWidth; + private int mDividerInsets; private boolean mResizing; private WindowState mWindow; private final Rect mTmpRect = new Rect(); @@ -105,14 +105,23 @@ public class DockedStackDividerController implements DimLayerUser { mService = service; mDisplayContent = displayContent; final Context context = service.mContext; - mDividerWindowWidth = context.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.docked_stack_divider_thickness); - mDividerInsets = context.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.docked_stack_divider_insets); mDimLayer = new DimLayer(displayContent.mService, this, displayContent.getDisplayId(), "DockedStackDim"); mMinimizedDockInterpolator = AnimationUtils.loadInterpolator( context, android.R.interpolator.fast_out_slow_in); + loadDimens(); + } + + private void loadDimens() { + final Context context = mService.mContext; + mDividerWindowWidth = context.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.docked_stack_divider_thickness); + mDividerInsets = context.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.docked_stack_divider_insets); + } + + void onConfigurationChanged() { + loadDimens(); } boolean isResizing() { @@ -243,6 +252,9 @@ public class DockedStackDividerController implements DimLayerUser { } } mDockedStackListeners.finishBroadcast(); + if (!exists) { + setMinimizedDockedStack(false); + } } void notifyDockedStackMinimizedChanged(boolean minimizedDock, long animDuration) { @@ -263,6 +275,7 @@ public class DockedStackDividerController implements DimLayerUser { notifyDockedDividerVisibilityChanged(wasVisible()); notifyDockedStackExistsChanged( mDisplayContent.mService.mStackIdToStack.get(DOCKED_STACK_ID) != null); + notifyDockedStackMinimizedChanged(mMinimizedDock, 0 /* animDuration */); } void setResizeDimLayer(boolean visible, int targetStackId, float alpha) { @@ -338,12 +351,13 @@ public class DockedStackDividerController implements DimLayerUser { * @param animate Whether to animate the change. */ private void setMinimizedDockedStack(boolean minimizedDock, boolean animate) { - if (minimizedDock == mMinimizedDock + final boolean wasMinimized = mMinimizedDock; + mMinimizedDock = minimizedDock; + if (minimizedDock == wasMinimized || mDisplayContent.getDockedStackVisibleForUserLocked() == null) { return; } - mMinimizedDock = minimizedDock; mAnimatingForIme = false; if (minimizedDock) { if (animate) { @@ -369,13 +383,13 @@ public class DockedStackDividerController implements DimLayerUser { private void setMinimizedDockedStack(boolean minimized) { final TaskStack stack = mDisplayContent.getDockedStackVisibleForUserLocked(); + notifyDockedStackMinimizedChanged(minimized, 0); if (stack == null) { return; } if (stack.setAdjustedForMinimizedDock(minimized ? 1f : 0f)) { mService.mWindowPlacerLocked.performSurfacePlacement(); } - notifyDockedStackMinimizedChanged(minimized, 0); } private boolean isAnimationMaximizing() { diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index eea0ca0666f7..8a9ace780ad5 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -595,6 +595,12 @@ class Task implements DimLayer.DimLayerUser { if (win.mHasSurface && !resizingWindows.contains(win)) { if (DEBUG_RESIZE) Slog.d(TAG, "resizeWindows: Resizing " + win); resizingWindows.add(win); + + // If we are not drag resizing, force recreating of a new surface so updating + // the content and positioning that surface will be in sync. + if (!win.computeDragResizing()) { + win.mResizedWhileNotDragResizing = true; + } } if (win.isGoneForLayoutLw()) { win.mResizedWhileGone = true; diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index bb0ec4c33049..3430ac9289a5 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -37,8 +37,8 @@ import java.util.ArrayList; import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; -import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; +import static android.content.res.Configuration.DENSITY_DPI_UNDEFINED; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.WindowManager.DOCKED_BOTTOM; import static android.view.WindowManager.DOCKED_INVALID; @@ -89,6 +89,9 @@ public class TaskStack implements DimLayer.DimLayerUser, // Device rotation as of the last time {@link #mBounds} was set. int mRotation; + /** Density as of last time {@link #mBounds} was set. */ + int mDensity; + /** Support for non-zero {@link android.view.animation.Animation#getBackgroundColor()} */ DimLayer mAnimationBackgroundSurface; @@ -250,9 +253,11 @@ public class TaskStack implements DimLayer.DimLayerUser, private boolean setBounds(Rect bounds) { boolean oldFullscreen = mFullscreen; int rotation = Surface.ROTATION_0; + int density = DENSITY_DPI_UNDEFINED; if (mDisplayContent != null) { mDisplayContent.getLogicalDisplayRect(mTmpRect); rotation = mDisplayContent.getDisplayInfo().rotation; + density = mDisplayContent.getDisplayInfo().logicalDensityDpi; mFullscreen = bounds == null; if (mFullscreen) { bounds = mTmpRect; @@ -274,6 +279,7 @@ public class TaskStack implements DimLayer.DimLayerUser, mBounds.set(bounds); mRotation = rotation; + mDensity = density; updateAdjustedBounds(); @@ -343,20 +349,21 @@ public class TaskStack implements DimLayer.DimLayerUser, mTmpRect2.set(mBounds); final int newRotation = mDisplayContent.getDisplayInfo().rotation; - if (mRotation == newRotation) { + final int newDensity = mDisplayContent.getDisplayInfo().logicalDensityDpi; + if (mRotation == newRotation && mDensity == newDensity) { setBounds(mTmpRect2); } else { mLastUpdateDisplayInfoRotation = newRotation; - updateBoundsAfterRotation(true); + updateBoundsAfterConfigChange(true); } } boolean onConfigurationChanged() { mLastConfigChangedRotation = getDisplayInfo().rotation; - return updateBoundsAfterRotation(false); + return updateBoundsAfterConfigChange(false); } - boolean updateBoundsAfterRotation(boolean scheduleResize) { + boolean updateBoundsAfterConfigChange(boolean scheduleResize) { if (mLastConfigChangedRotation != mLastUpdateDisplayInfoRotation) { // We wait for the rotation values after configuration change and display info. update // to be equal before updating the bounds due to rotation change otherwise things might @@ -365,8 +372,9 @@ public class TaskStack implements DimLayer.DimLayerUser, } final int newRotation = getDisplayInfo().rotation; + final int newDensity = getDisplayInfo().logicalDensityDpi; - if (mRotation == newRotation) { + if (mRotation == newRotation && mDensity == newDensity) { // Nothing to do here if the rotation didn't change return false; } @@ -957,9 +965,11 @@ public class TaskStack implements DimLayer.DimLayerUser, (int) (minimizeAmount * topInset + (1 - minimizeAmount) * mBounds.bottom); } else if (dockSide == DOCKED_LEFT) { mTmpAdjustedBounds.set(mBounds); + final int width = mBounds.width(); mTmpAdjustedBounds.right = (int) (minimizeAmount * mDockedStackMinimizeThickness + (1 - minimizeAmount) * mBounds.right); + mTmpAdjustedBounds.left = mTmpAdjustedBounds.right - width; } else if (dockSide == DOCKED_RIGHT) { mTmpAdjustedBounds.set(mBounds); mTmpAdjustedBounds.left = diff --git a/services/core/java/com/android/server/wm/WindowLayersController.java b/services/core/java/com/android/server/wm/WindowLayersController.java index f76f03fdc0fe..6bdcd42ee081 100644 --- a/services/core/java/com/android/server/wm/WindowLayersController.java +++ b/services/core/java/com/android/server/wm/WindowLayersController.java @@ -191,18 +191,20 @@ public class WindowLayersController { } private void adjustSpecialWindows() { - int layer = mHighestApplicationLayer + 1; + int layer = mHighestApplicationLayer + WINDOW_LAYER_MULTIPLIER; // For pinned and docked stack window, we want to make them above other windows also when // these windows are animating. while (!mDockedWindows.isEmpty()) { layer = assignAndIncreaseLayerIfNeeded(mDockedWindows.remove(), layer); } - // Leave some space here so the dim layer while dismissing docked/fullscreen stack has space - // below the divider but above the app windows. It needs to be below the divider in because - // the divider sometimes overlaps the app windows. - layer++; layer = assignAndIncreaseLayerIfNeeded(mDockDivider, layer); + + if (mDockDivider != null && mDockDivider.isVisibleLw() + && mService.mInputMethodWindow != null) { + layer = assignAndIncreaseLayerIfNeeded(mService.mInputMethodWindow, layer); + } + // We know that we will be animating a relaunching window in the near future, which will // receive a z-order increase. We want the replaced window to immediately receive the same // treatment, e.g. to be above the dock divider. @@ -216,13 +218,14 @@ public class WindowLayersController { } private int assignAndIncreaseLayerIfNeeded(WindowState win, int layer) { - if (win != null) { + if (win != null && layer > win.mLayer) { assignAnimLayer(win, layer); - layer++; + // Make sure we leave space inbetween normal windows for dims and such. + layer += WINDOW_LAYER_MULTIPLIER; } return layer; } - + private void assignAnimLayer(WindowState w, int layer) { w.mLayer = layer; w.mWinAnimator.mAnimLayer = w.mLayer + w.getAnimLayerAdjustment() + diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index 14ae74f3967d..2af324d19710 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -1369,11 +1369,8 @@ public class WindowManagerService extends IWindowManager.Stub final int fl = w.mAttrs.flags & (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM); final int type = w.mAttrs.type; - // The dock divider has to sit above the application windows and so does the IME. IME also - // needs to sit above the dock divider, so it doesn't get cut in half. We make the dock - // divider be a target for IME, so this relationship can occur naturally. if (fl == 0 || fl == (FLAG_NOT_FOCUSABLE|FLAG_ALT_FOCUSABLE_IM) - || type == TYPE_APPLICATION_STARTING || type == TYPE_DOCK_DIVIDER) { + || type == TYPE_APPLICATION_STARTING) { if (DEBUG_INPUT_METHOD) { Slog.i(TAG_WM, "isVisibleOrAdding " + w + ": " + w.isVisibleOrAdding()); if (!w.isVisibleOrAdding()) { @@ -2020,7 +2017,13 @@ public class WindowManagerService extends IWindowManager.Stub final WindowStateAnimator winAnimator = win.mWinAnimator; winAnimator.mEnterAnimationPending = true; winAnimator.mEnteringAnimation = true; - prepareWindowReplacementTransition(atoken); + // Check if we need to prepare a transition for replacing window first. + if (atoken != null && !prepareWindowReplacementTransition(atoken)) { + // If not, check if need to set up a dummy transition during display freeze + // so that the unfreeze wait for the apps to draw. This might be needed if + // the app is relaunching. + prepareNoneTransitionForRelaunching(atoken); + } if (displayContent.isDefaultDisplay) { if (mPolicy.getInsetHintLw(win.mAttrs, mRotation, outContentInsets, outStableInsets, @@ -2080,10 +2083,10 @@ public class WindowManagerService extends IWindowManager.Stub return res; } - private void prepareWindowReplacementTransition(AppWindowToken atoken) { - if (atoken == null) { - return; - } + /** + * Returns true if we're done setting up any transitions. + */ + private boolean prepareWindowReplacementTransition(AppWindowToken atoken) { atoken.allDrawn = false; WindowState replacedWindow = null; for (int i = atoken.windows.size() - 1; i >= 0 && replacedWindow == null; i--) { @@ -2096,7 +2099,7 @@ public class WindowManagerService extends IWindowManager.Stub if (replacedWindow == null) { // We expect to already receive a request to remove the old window. If it did not // happen, let's just simply add a window. - return; + return false; } // We use the visible frame, because we want the animation to morph the window from what // was visible to the user to the final destination of the new window. @@ -2108,6 +2111,19 @@ public class WindowManagerService extends IWindowManager.Stub mAppTransition.overridePendingAppTransitionClipReveal(frame.left, frame.top, frame.width(), frame.height()); executeAppTransition(); + return true; + } + + private void prepareNoneTransitionForRelaunching(AppWindowToken atoken) { + // Set up a none-transition and add the app to opening apps, so that the display + // unfreeze wait for the apps to be drawn. + // Note that if the display unfroze already because app unfreeze timed out, + // we don't set up the transition anymore and just let it go. + if (mDisplayFrozen && !mOpeningApps.contains(atoken) && atoken.isRelaunching()) { + mOpeningApps.add(atoken); + prepareAppTransition(AppTransition.TRANSIT_NONE, !ALWAYS_KEEP_CURRENT); + executeAppTransition(); + } } /** @@ -2570,7 +2586,7 @@ public class WindowManagerService extends IWindowManager.Stub try { - win.applyGravityAndUpdateFrame(); + win.applyGravityAndUpdateFrame(win.mContainingFrame, win.mDisplayFrame); win.mWinAnimator.computeShownFrameLocked(); win.mWinAnimator.setSurfaceBoundariesLocked(false); @@ -2919,8 +2935,9 @@ public class WindowManagerService extends IWindowManager.Stub // If we're starting a drag-resize, we'll be changing the surface size as well as // notifying the client to render to with an offset from the surface's top-left. - if (win.isDragResizeChanged()) { + if (win.isDragResizeChanged() || win.mResizedWhileNotDragResizing) { win.setDragResizing(); + win.mResizedWhileNotDragResizing = false; // We can only change top level windows to the full-screen surface when // resizing (as we only have one full-screen surface). So there is no need // to preserve and destroy windows which are attached to another, they @@ -3042,7 +3059,7 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_APP_TRANSITIONS) Slog.d(TAG_WM, "Loading animation for app transition." + " transit=" + AppTransition.appTransitionToString(transit) + " enter=" + enter + " frame=" + frame + " insets=" + insets + " surfaceInsets=" + surfaceInsets); - Animation a = mAppTransition.loadAnimation(lp, transit, enter, + Animation a = mAppTransition.loadAnimation(lp, transit, enter, mCurConfiguration.uiMode, mCurConfiguration.orientation, frame, displayFrame, insets, surfaceInsets, isVoiceInteraction, freeform, atoken.mTask.mTaskId); if (a != null) { @@ -3611,6 +3628,8 @@ public class WindowManagerService extends IWindowManager.Stub } private int[] onConfigurationChanged() { + mPolicy.onConfigurationChanged(); + getDefaultDisplayContentLocked().getDockedDividerController().onConfigurationChanged(); mChangedStackList.clear(); for (int stackNdx = mStackIdToStack.size() - 1; stackNdx >= 0; stackNdx--) { final TaskStack stack = mStackIdToStack.valueAt(stackNdx); @@ -4135,6 +4154,14 @@ public class WindowManagerService extends IWindowManager.Stub for (int i = 0; i < windowsCount; i++) { WindowState win = wtoken.allAppWindows.get(i); if (win == wtoken.startingWindow) { + // Starting window that's exiting will be removed when the animation + // finishes. Mark all relevant flags for that finishExit will proceed + // all the way to actually remove it. + if (!visible && win.isVisibleNow() && wtoken.mAppAnimator.isAnimating()) { + win.mAnimatingExit = true; + win.mRemoveOnExit = true; + win.mWindowRemovalAllowed = true; + } continue; } @@ -4284,9 +4311,13 @@ public class WindowManagerService extends IWindowManager.Stub wtoken.appDied = false; wtoken.removeAllWindows(); } else if (visible) { - mOpeningApps.add(wtoken); + if (!mAppTransition.isTransitionSet() && mAppTransition.isReady()) { + // Add the app mOpeningApps if transition is unset but ready. This means + // we're doing a screen freeze, and the unfreeze will wait for all opening + // apps to be ready. + mOpeningApps.add(wtoken); + } wtoken.startingMoved = false; - // If the token is currently hidden (should be the common case), or has been // stopped, then we need to set up to wait for its windows to be ready. if (wtoken.hidden || wtoken.mAppStopped) { @@ -4330,6 +4361,7 @@ public class WindowManagerService extends IWindowManager.Stub } wtoken.inPendingTransaction = true; if (visible) { + mOpeningApps.add(wtoken); wtoken.mEnteringAnimation = true; } else { mClosingApps.add(wtoken); @@ -6086,7 +6118,7 @@ public class WindowManagerService extends IWindowManager.Stub int bottom = wf.bottom - cr.bottom; frame.union(left, top, right, bottom); ws.getVisibleBounds(stackBounds); - if (!frame.intersect(stackBounds)) { + if (!Rect.intersects(frame, stackBounds)) { // Set frame empty if there's no intersection. frame.setEmpty(); } @@ -7586,6 +7618,11 @@ public class WindowManagerService extends IWindowManager.Stub + " milliseconds before attempting to detect safe mode."); } + if (Settings.Global.getInt( + mContext.getContentResolver(), Settings.Global.SAFE_BOOT_DISALLOWED, 0) != 0) { + return false; + } + int menuState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_MENU); int sState = mInputManager.getKeyCodeState(-1, InputDevice.SOURCE_ANY, KeyEvent.KEYCODE_S); @@ -8987,7 +9024,8 @@ public class WindowManagerService extends IWindowManager.Stub || winAnimator.mSurfaceResized || w.mOutsetsChanged || configChanged - || dragResizingChanged) { + || dragResizingChanged + || w.mResizedWhileNotDragResizing) { if (DEBUG_RESIZE || DEBUG_ORIENTATION) { Slog.v(TAG_WM, "Resize reasons for w=" + w + ": " + " contentInsetsChanged=" + w.mContentInsetsChanged @@ -9021,7 +9059,8 @@ public class WindowManagerService extends IWindowManager.Stub // the display until this window has been redrawn; to do that, // we need to go through the process of getting informed by the // application when it has finished drawing. - if (w.mOrientationChanging || dragResizingChanged) { + if (w.mOrientationChanging || dragResizingChanged + || w.mResizedWhileNotDragResizing) { if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || DEBUG_ORIENTATION || DEBUG_RESIZE) { Slog.v(TAG_WM, "Orientation or resize start waiting for draw" + ", mDrawState=DRAW_PENDING in " + w @@ -9381,6 +9420,10 @@ public class WindowManagerService extends IWindowManager.Stub return; } + if (DEBUG_ORIENTATION) Slog.d(TAG_WM, + "startFreezingDisplayLocked: inTransaction=" + inTransaction + + " exitAnim=" + exitAnim + " enterAnim=" + enterAnim + + " called by " + Debug.getCallers(8)); mScreenFrozenLock.acquire(); mDisplayFrozen = true; @@ -9451,6 +9494,9 @@ public class WindowManagerService extends IWindowManager.Stub return; } + if (DEBUG_ORIENTATION) Slog.d(TAG_WM, + "stopFreezingDisplayLocked: Unfreezing now"); + mDisplayFrozen = false; mLastDisplayFreezeDuration = (int)(SystemClock.elapsedRealtime() - mDisplayFreezeTime); StringBuilder sb = new StringBuilder(128); @@ -10615,7 +10661,10 @@ public class WindowManagerService extends IWindowManager.Stub @Override public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId) { try { - getFocusedWindow().mClient.requestAppKeyboardShortcuts(receiver, deviceId); + WindowState focusedWindow = getFocusedWindow(); + if (focusedWindow != null && focusedWindow.mClient != null) { + getFocusedWindow().mClient.requestAppKeyboardShortcuts(receiver, deviceId); + } } catch (RemoteException e) { } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 57ead8b3a617..ddfc022aeb3f 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -328,6 +328,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { */ final Rect mInsetFrame = new Rect(); + private static final Rect sTmpRect = new Rect(); + boolean mContentChanged; // If a window showing a wallpaper: the requested offset for the @@ -466,6 +468,13 @@ final class WindowState implements WindowManagerPolicy.WindowState { */ boolean mResizedWhileGone = false; + /** + * Indicates whether we got resized but drag resizing flag was false. In this case, we also + * need to recreate the surface and defer surface bound updates in order to make sure the + * buffer contents and the positioning/size stay in sync. + */ + boolean mResizedWhileNotDragResizing; + WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a, int viewVisibility, final DisplayContent displayContent) { @@ -629,6 +638,20 @@ final class WindowState implements WindowManagerPolicy.WindowState { return mAttrs.packageName; } + /** + * Subtracts the insets calculated by intersecting {@param layoutFrame} with {@param insetFrame} + * from {@param frame}. In other words, it applies the insets that would result if + * {@param frame} would be shifted to {@param layoutFrame} and then applying the insets from + * {@param insetFrame}. + */ + private void subtractInsets(Rect frame, Rect layoutFrame, Rect insetFrame) { + final int left = Math.max(0, insetFrame.left - layoutFrame.left); + final int top = Math.max(0, insetFrame.top - layoutFrame.top); + final int right = Math.max(0, layoutFrame.right - insetFrame.right); + final int bottom = Math.max(0, layoutFrame.bottom - insetFrame.bottom); + frame.inset(left, top, right, bottom); + } + @Override public void computeFrameLw(Rect pf, Rect df, Rect of, Rect cf, Rect vf, Rect dcf, Rect sf, Rect osf) { @@ -654,11 +677,25 @@ final class WindowState implements WindowManagerPolicy.WindowState { task.getTempInsetBounds(mInsetFrame); } + // Denotes the actual frame used to calculate the insets and to perform the layout. When + // resizing in docked mode, we'd like to freeze the layout, so we also need to freeze the + // insets temporarily. By the notion of a task having a different layout frame, we can + // achieve that while still moving the task around. + final Rect layoutContainingFrame; + final Rect layoutDisplayFrame; + + // The offset from the layout containing frame to the actual containing frame. + final int layoutXDiff; + final int layoutYDiff; if (mInsetFrame.isEmpty() && (fullscreenTask || layoutInParentFrame())) { // We use the parent frame as the containing frame for fullscreen and child windows mContainingFrame.set(pf); mDisplayFrame.set(df); + layoutDisplayFrame = df; + layoutContainingFrame = pf; + layoutXDiff = 0; + layoutYDiff = 0; } else { task.getBounds(mContainingFrame); if (mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) { @@ -670,10 +707,18 @@ final class WindowState implements WindowManagerPolicy.WindowState { mContainingFrame.bottom = mContainingFrame.top + frozen.height(); } final WindowState imeWin = mService.mInputMethodWindow; - if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this - && mContainingFrame.bottom > cf.bottom) { - // IME is up and obscuring this window. Adjust the window position so it is visible. - mContainingFrame.top -= mContainingFrame.bottom - cf.bottom; + // IME is up and obscuring this window. Adjust the window position so it is visible. + if (imeWin != null && imeWin.isVisibleNow() && mService.mInputMethodTarget == this) { + if (windowsAreFloating && mContainingFrame.bottom > cf.bottom) { + // In freeform we want to move the top up directly. + // TODO: Investigate why this is cf not pf. + mContainingFrame.top -= mContainingFrame.bottom - cf.bottom; + } else if (mContainingFrame.bottom > pf.bottom) { + // But in docked we want to behave like fullscreen + // and behave as if the task were given smaller bounds + // for the purposes of layout. + mContainingFrame.bottom = pf.bottom; + } } if (windowsAreFloating) { @@ -685,6 +730,14 @@ final class WindowState implements WindowManagerPolicy.WindowState { } } mDisplayFrame.set(mContainingFrame); + layoutXDiff = !mInsetFrame.isEmpty() ? mInsetFrame.left - mContainingFrame.left : 0; + layoutYDiff = !mInsetFrame.isEmpty() ? mInsetFrame.top - mContainingFrame.top : 0; + layoutContainingFrame = !mInsetFrame.isEmpty() ? mInsetFrame : mContainingFrame; + subtractInsets(mDisplayFrame, layoutContainingFrame, df); + subtractInsets(mContainingFrame, layoutContainingFrame, pf); + subtractInsets(mInsetFrame, layoutContainingFrame, pf); + layoutDisplayFrame = df; + layoutDisplayFrame.intersect(layoutContainingFrame); } final int pw = mContainingFrame.width(); @@ -715,7 +768,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { final int fw = mFrame.width(); final int fh = mFrame.height(); - applyGravityAndUpdateFrame(); + applyGravityAndUpdateFrame(layoutContainingFrame, layoutDisplayFrame); + + // Offset the actual frame by the amount layout frame is off. + mFrame.offset(-layoutXDiff, -layoutYDiff); + mCompatFrame.offset(-layoutXDiff, -layoutYDiff); // Calculate the outsets before the content frame gets shrinked to the window frame. if (hasOutsets) { @@ -727,12 +784,6 @@ final class WindowState implements WindowManagerPolicy.WindowState { mOutsets.set(0, 0, 0, 0); } - // Denotes the actual frame used to calculate the insets. When resizing in docked mode, - // we'd like to freeze the layout, so we also need to freeze the insets temporarily. By the - // notion of a task having a different inset frame, we can achieve that while still moving - // the task around. - final Rect frame = !mInsetFrame.isEmpty() ? mInsetFrame : mFrame; - // Make sure the content and visible frames are inside of the // final window frame. if (windowsAreFloating && !mFrame.isEmpty()) { @@ -761,29 +812,29 @@ final class WindowState implements WindowManagerPolicy.WindowState { mMovedByResize = true; } } else { - mContentFrame.set(Math.max(mContentFrame.left, frame.left), - Math.max(mContentFrame.top, frame.top), - Math.min(mContentFrame.right, frame.right), - Math.min(mContentFrame.bottom, frame.bottom)); + mContentFrame.set(Math.max(mContentFrame.left, layoutContainingFrame.left), + Math.max(mContentFrame.top, layoutContainingFrame.top), + Math.min(mContentFrame.right, layoutContainingFrame.right), + Math.min(mContentFrame.bottom, layoutContainingFrame.bottom)); - mVisibleFrame.set(Math.max(mVisibleFrame.left, frame.left), - Math.max(mVisibleFrame.top, frame.top), - Math.min(mVisibleFrame.right, frame.right), - Math.min(mVisibleFrame.bottom, frame.bottom)); + mVisibleFrame.set(Math.max(mVisibleFrame.left, layoutContainingFrame.left), + Math.max(mVisibleFrame.top, layoutContainingFrame.top), + Math.min(mVisibleFrame.right, layoutContainingFrame.right), + Math.min(mVisibleFrame.bottom, layoutContainingFrame.bottom)); - mStableFrame.set(Math.max(mStableFrame.left, frame.left), - Math.max(mStableFrame.top, frame.top), - Math.min(mStableFrame.right, frame.right), - Math.min(mStableFrame.bottom, frame.bottom)); + mStableFrame.set(Math.max(mStableFrame.left, layoutContainingFrame.left), + Math.max(mStableFrame.top, layoutContainingFrame.top), + Math.min(mStableFrame.right, layoutContainingFrame.right), + Math.min(mStableFrame.bottom, layoutContainingFrame.bottom)); } if (fullscreenTask && !windowsAreFloating) { // Windows that are not fullscreen can be positioned outside of the display frame, // but that is not a reason to provide them with overscan insets. - mOverscanInsets.set(Math.max(mOverscanFrame.left - frame.left, 0), - Math.max(mOverscanFrame.top - frame.top, 0), - Math.max(frame.right - mOverscanFrame.right, 0), - Math.max(frame.bottom - mOverscanFrame.bottom, 0)); + mOverscanInsets.set(Math.max(mOverscanFrame.left - layoutContainingFrame.left, 0), + Math.max(mOverscanFrame.top - layoutContainingFrame.top, 0), + Math.max(layoutContainingFrame.right - mOverscanFrame.right, 0), + Math.max(layoutContainingFrame.bottom - mOverscanFrame.bottom, 0)); } if (mAttrs.type == TYPE_DOCK_DIVIDER) { @@ -799,45 +850,37 @@ final class WindowState implements WindowManagerPolicy.WindowState { mContentInsets.setEmpty(); mVisibleInsets.setEmpty(); } else { - // Using mContentInsets as a temp rect. It is safe because we're setting it below. - getDisplayContent().getLogicalDisplayRect(mContentInsets); + getDisplayContent().getLogicalDisplayRect(mTmpRect); // Override right and/or bottom insets in case if the frame doesn't fit the screen in // non-fullscreen mode. - boolean overrideRightInset = !fullscreenTask && mFrame.right > mContentInsets.right; - boolean overrideBottomInset = !fullscreenTask && mFrame.bottom > mContentInsets.bottom; - mContentInsets.set(mContentFrame.left - frame.left, - mContentFrame.top - frame.top, - overrideRightInset ? 0 : frame.right - mContentFrame.right, - overrideBottomInset ? 0 : frame.bottom - mContentFrame.bottom); - - mVisibleInsets.set(mVisibleFrame.left - frame.left, - mVisibleFrame.top - frame.top, - overrideRightInset ? 0 : frame.right - mVisibleFrame.right, - overrideBottomInset ? 0 : frame.bottom - mVisibleFrame.bottom); + boolean overrideRightInset = !fullscreenTask && mFrame.right > mTmpRect.right; + boolean overrideBottomInset = !fullscreenTask && mFrame.bottom > mTmpRect.bottom; + mContentInsets.set(mContentFrame.left - layoutContainingFrame.left, + mContentFrame.top - layoutContainingFrame.top, + overrideRightInset ? mTmpRect.right - mContentFrame.right + : layoutContainingFrame.right - mContentFrame.right, + overrideBottomInset ? mTmpRect.bottom - mContentFrame.bottom + : layoutContainingFrame.bottom - mContentFrame.bottom); + + mVisibleInsets.set(mVisibleFrame.left - layoutContainingFrame.left, + mVisibleFrame.top - layoutContainingFrame.top, + overrideRightInset ? mTmpRect.right - mVisibleFrame.right + : layoutContainingFrame.right - mVisibleFrame.right, + overrideBottomInset ? mTmpRect.bottom - mVisibleFrame.bottom + : layoutContainingFrame.bottom - mVisibleFrame.bottom); + + mStableInsets.set(Math.max(mStableFrame.left - layoutContainingFrame.left, 0), + Math.max(mStableFrame.top - layoutContainingFrame.top, 0), + overrideRightInset ? Math.max(mTmpRect.right - mStableFrame.right, 0) + : Math.max(layoutContainingFrame.right - mStableFrame.right, 0), + overrideBottomInset ? Math.max(mTmpRect.bottom - mStableFrame.bottom, 0) + : Math.max(layoutContainingFrame.bottom - mStableFrame.bottom, 0)); + } + + mContentFrame.offset(-layoutXDiff, -layoutYDiff); + mVisibleFrame.offset(-layoutXDiff, -layoutYDiff); + mStableFrame.offset(-layoutXDiff, -layoutYDiff); - mStableInsets.set(Math.max(mStableFrame.left - frame.left, 0), - Math.max(mStableFrame.top - frame.top, 0), - overrideRightInset ? 0 : Math.max(frame.right - mStableFrame.right, 0), - overrideBottomInset ? 0 : Math.max(frame.bottom - mStableFrame.bottom, 0)); - } - - if (!mInsetFrame.isEmpty()) { - mContentFrame.set(mFrame); - mContentFrame.top += mContentInsets.top; - mContentFrame.bottom -= mContentInsets.bottom; - mContentFrame.left += mContentInsets.left; - mContentFrame.right -= mContentInsets.right; - mVisibleFrame.set(mFrame); - mVisibleFrame.top += mVisibleInsets.top; - mVisibleFrame.bottom -= mVisibleInsets.bottom; - mVisibleFrame.left += mVisibleInsets.left; - mVisibleFrame.right -= mVisibleInsets.right; - mStableFrame.set(mFrame); - mStableFrame.top += mStableInsets.top; - mStableFrame.bottom -= mStableInsets.bottom; - mStableFrame.left += mStableInsets.left; - mStableFrame.right -= mStableInsets.right; - } mCompatFrame.set(mFrame); if (mEnforceSizeCompat) { // If there is a size compatibility scale being applied to the @@ -1878,6 +1921,11 @@ final class WindowState implements WindowManagerPolicy.WindowState { } private boolean shouldSaveSurface() { + if (mWinAnimator.mSurfaceController == null) { + // Don't bother if the surface controller is gone for any reason. + return false; + } + if ((mAttrs.flags & FLAG_SECURE) != 0) { // We don't save secure surfaces since their content shouldn't be shown while the app // isn't on screen and content might leak through during the transition animation with @@ -1951,10 +1999,18 @@ final class WindowState implements WindowManagerPolicy.WindowState { return; } mSurfaceSaved = false; - setHasSurface(true); - mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW; - if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { - Slog.v(TAG, "Restoring saved surface: " + this); + if (mWinAnimator.mSurfaceController != null) { + setHasSurface(true); + mWinAnimator.mDrawState = WindowStateAnimator.READY_TO_SHOW; + + if (DEBUG_APP_TRANSITIONS || DEBUG_ANIM) { + Slog.v(TAG, "Restoring saved surface: " + this); + } + } else { + // mSurfaceController shouldn't be null if mSurfaceSaved was still true at + // this point. Even if we destroyed the saved surface because of rotation + // or resize, mSurfaceSaved flag should have been cleared. So this is a wtf. + Slog.wtf(TAG, "Failed to restore saved surface: surface gone! " + this); } } @@ -2523,9 +2579,9 @@ final class WindowState implements WindowManagerPolicy.WindowState { } } - void applyGravityAndUpdateFrame() { - final int pw = mContainingFrame.width(); - final int ph = mContainingFrame.height(); + void applyGravityAndUpdateFrame(Rect containingFrame, Rect displayFrame) { + final int pw = containingFrame.width(); + final int ph = containingFrame.height(); final Task task = getTask(); final boolean nonFullscreenTask = isInMultiWindowMode(); final boolean fitToDisplay = task != null && !task.isFloating() && !layoutInParentFrame(); @@ -2572,7 +2628,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { y = mAttrs.y; } - if (nonFullscreenTask) { + if (nonFullscreenTask && !layoutInParentFrame()) { // Make sure window fits in containing frame since it is in a non-fullscreen task as // required by {@link Gravity#apply} call. w = Math.min(w, pw); @@ -2580,13 +2636,13 @@ final class WindowState implements WindowManagerPolicy.WindowState { } // Set mFrame - Gravity.apply(mAttrs.gravity, w, h, mContainingFrame, + Gravity.apply(mAttrs.gravity, w, h, containingFrame, (int) (x + mAttrs.horizontalMargin * pw), (int) (y + mAttrs.verticalMargin * ph), mFrame); // Now make sure the window fits in the overall display frame. if (fitToDisplay) { - Gravity.applyDisplay(mAttrs.gravity, mDisplayFrame, mFrame); + Gravity.applyDisplay(mAttrs.gravity, displayFrame, mFrame); } // We need to make sure we update the CompatFrame as it is used for diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java index 1e103f0573e0..34452ee1eefa 100644 --- a/services/core/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java @@ -967,13 +967,15 @@ class WindowStateAnimator { if (appTransformation != null) { tmpMatrix.postConcat(appTransformation.getMatrix()); } - if (screenAnimation) { - tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix()); - } + // The translation that applies the position of the window needs to be applied at the // end in case that other translations include scaling. Otherwise the scaling will - // affect this translation. + // affect this translation. But it needs to be set before the screen rotation animation + // so the pivot point is at the center of the screen for all windows. tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset); + if (screenAnimation) { + tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix()); + } //TODO (multidisplay): Magnification is supported only for the default display. if (mService.mAccessibilityController != null && displayId == DEFAULT_DISPLAY) { @@ -1316,6 +1318,11 @@ class WindowStateAnimator { final WindowState w = mWin; final Task task = w.getTask(); + // We got resized, so block all updates until we got the new surface. + if (w.mResizedWhileNotDragResizing) { + return; + } + mTmpSize.set(w.mShownPosition.x, w.mShownPosition.y, 0, 0); calculateSurfaceBounds(w, w.getAttrs()); diff --git a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java index eda2f39480a8..04aa735bc99d 100644 --- a/services/core/java/com/android/server/wm/WindowSurfacePlacer.java +++ b/services/core/java/com/android/server/wm/WindowSurfacePlacer.java @@ -1582,7 +1582,8 @@ class WindowSurfacePlacer { // synchronize its thumbnail surface with the surface for the // open/close animation (only on the way down) anim = mService.mAppTransition.createThumbnailAspectScaleAnimationLocked(appRect, - insets, thumbnailHeader, taskId, mService.mCurConfiguration.orientation); + insets, thumbnailHeader, taskId, mService.mCurConfiguration.uiMode, + mService.mCurConfiguration.orientation); openingAppAnimator.thumbnailForceAboveLayer = Math.max(openingLayer, closingLayer); openingAppAnimator.deferThumbnailDestruction = !mService.mAppTransition.isNextThumbnailTransitionScaleUp(); diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp index a5237ca89520..cd485c55c816 100644 --- a/services/core/jni/com_android_server_input_InputManagerService.cpp +++ b/services/core/jni/com_android_server_input_InputManagerService.cpp @@ -1312,6 +1312,12 @@ static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */, } } +static void nativeToggleCapsLock(JNIEnv* env, jclass /* clazz */, + jlong ptr, jint deviceId) { + NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); + im->getInputManager()->getReader()->toggleCapsLockState(deviceId); +} + static void nativeSetInputWindows(JNIEnv* env, jclass /* clazz */, jlong ptr, jobjectArray windowHandleObjArray) { NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr); @@ -1508,6 +1514,8 @@ static const JNINativeMethod gInputManagerMethods[] = { (void*) nativeSetInputFilterEnabled }, { "nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIIII)I", (void*) nativeInjectInputEvent }, + { "nativeToggleCapsLock", "(JI)V", + (void*) nativeToggleCapsLock }, { "nativeSetInputWindows", "(J[Lcom/android/server/input/InputWindowHandle;)V", (void*) nativeSetInputWindows }, { "nativeSetFocusedApplication", "(JLcom/android/server/input/InputApplicationHandle;)V", diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 6fe5c1680b1a..fdea84b4c2a4 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1131,9 +1131,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } String tagDAM = parser.getName(); if (TAG_TRUST_AGENT_COMPONENT_OPTIONS.equals(tagDAM)) { - PersistableBundle bundle = new PersistableBundle(); - bundle.restoreFromXml(parser); - result.options = bundle; + result.options = PersistableBundle.restoreFromXml(parser); } else { Slog.w(LOG_TAG, "Unknown tag under " + tag + ": " + tagDAM); } @@ -2805,6 +2803,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { && getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null) { throw new IllegalArgumentException("Admin is already added"); } + if (policy.mRemovingAdmins.contains(adminReceiver)) { + throw new IllegalArgumentException( + "Trying to set an admin which is being removed"); + } ActiveAdmin newAdmin = new ActiveAdmin(info, /* parent */ false); policy.mAdminMap.put(adminReceiver, newAdmin); int replaceIndex = -1; @@ -3006,7 +3008,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { ArrayList<ActiveAdmin> admins = new ArrayList<ActiveAdmin>(); for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) { DevicePolicyData policy = getUserData(userInfo.id); - if (!isManagedProfile(userInfo.id)) { + if (!userInfo.isManagedProfile()) { admins.addAll(policy.mAdminList); } else { // For managed profiles, we always include the policies set on the parent @@ -3740,32 +3742,26 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final int callingUid = mInjector.binderGetCallingUid(); final int userHandle = mInjector.userHandleGetCallingUserId(); - if (getCredentialOwner(userHandle, /* parent */ false) != userHandle) { - throw new SecurityException("You can not change password for this profile because" - + " it shares the password with the owner profile"); - } - String password = passwordOrNull != null ? passwordOrNull : ""; + // Password resetting to empty/null is not allowed for managed profiles. + if (TextUtils.isEmpty(password)) { + enforceNotManagedProfile(userHandle, "clear the active password"); + } + int quality; synchronized (this) { - // If caller has PO (or DO), it can clear the password, so see if that's the case - // first. + // If caller has PO (or DO) it can change the password, so see if that's the case first. ActiveAdmin admin = getActiveAdminWithPolicyForUidLocked( null, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, callingUid); if (admin == null) { // Otherwise, make sure the caller has any active admin with the right policy. admin = getActiveAdminForCallerLocked(null, DeviceAdminInfo.USES_POLICY_RESET_PASSWORD); - } - final ComponentName adminComponent = admin.info.getComponent(); - - // As of N, only profile owners and device owners can reset the password. - if (!(isProfileOwner(adminComponent, userHandle) - || isDeviceOwner(adminComponent, userHandle))) { final boolean preN = getTargetSdk(admin.info.getPackageName(), userHandle) <= android.os.Build.VERSION_CODES.M; + // As of N, password resetting to empty/null is not allowed anymore. // TODO Should we allow DO/PO to set an empty password? if (TextUtils.isEmpty(password)) { @@ -3982,6 +3978,15 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { && timeMs > admin.maximumTimeToUnlock) { timeMs = admin.maximumTimeToUnlock; } + // If userInfo.id is a managed profile, we also need to look at + // the policies set on the parent. + if (admin.hasParentActiveAdmin()) { + final ActiveAdmin parentAdmin = admin.getParentActiveAdmin(); + if (parentAdmin.maximumTimeToUnlock > 0 + && timeMs > parentAdmin.maximumTimeToUnlock) { + timeMs = parentAdmin.maximumTimeToUnlock; + } + } } } @@ -4015,30 +4020,57 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } enforceFullCrossUsersPermission(userHandle); synchronized (this) { - long time = 0; - if (who != null) { ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent); - return admin != null ? admin.maximumTimeToUnlock : time; + return admin != null ? admin.maximumTimeToUnlock : 0; } - // Return the strictest policy across all participating admins. List<ActiveAdmin> admins = getActiveAdminsForLockscreenPoliciesLocked( userHandle, parent); - final int N = admins.size(); - for (int i = 0; i < N; i++) { - ActiveAdmin admin = admins.get(i); - if (time == 0) { - time = admin.maximumTimeToUnlock; - } else if (admin.maximumTimeToUnlock != 0 - && time > admin.maximumTimeToUnlock) { - time = admin.maximumTimeToUnlock; + return getMaximumTimeToLockPolicyFromAdmins(admins); + } + } + + @Override + public long getMaximumTimeToLockForUserAndProfiles(int userHandle) { + if (!mHasFeature) { + return 0; + } + enforceFullCrossUsersPermission(userHandle); + synchronized (this) { + // All admins for this user. + ArrayList<ActiveAdmin> admins = new ArrayList<ActiveAdmin>(); + for (UserInfo userInfo : mUserManager.getProfiles(userHandle)) { + DevicePolicyData policy = getUserData(userInfo.id); + admins.addAll(policy.mAdminList); + // If it is a managed profile, it may have parent active admins + if (userInfo.isManagedProfile()) { + for (ActiveAdmin admin : policy.mAdminList) { + if (admin.hasParentActiveAdmin()) { + admins.add(admin.getParentActiveAdmin()); + } + } } } - return time; + return getMaximumTimeToLockPolicyFromAdmins(admins); } } + private long getMaximumTimeToLockPolicyFromAdmins(List<ActiveAdmin> admins) { + long time = 0; + final int N = admins.size(); + for (int i = 0; i < N; i++) { + ActiveAdmin admin = admins.get(i); + if (time == 0) { + time = admin.maximumTimeToUnlock; + } else if (admin.maximumTimeToUnlock != 0 + && time > admin.maximumTimeToUnlock) { + time = admin.maximumTimeToUnlock; + } + } + return time; + } + @Override public void lockNow(boolean parent) { if (!mHasFeature) { @@ -4356,6 +4388,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + /** + * @return {@code true} if the package is installed and set as always-on, {@code false} if it is + * not installed and therefore not available. + * + * @throws SecurityException if the caller is not a profile or device owner. + * @throws UnsupportedException if the package does not support being set as always-on. + */ @Override public boolean setAlwaysOnVpnPackage(ComponentName admin, String vpnPackage) throws SecurityException { @@ -4365,13 +4404,19 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final int userId = mInjector.userHandleGetCallingUserId(); final long token = mInjector.binderClearCallingIdentity(); - try{ + try { + if (vpnPackage != null && !isPackageInstalledForUser(vpnPackage, userId)) { + return false; + } ConnectivityManager connectivityManager = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); - return connectivityManager.setAlwaysOnVpnPackageForUser(userId, vpnPackage); + if (!connectivityManager.setAlwaysOnVpnPackageForUser(userId, vpnPackage)) { + throw new UnsupportedOperationException(); + } } finally { mInjector.binderRestoreCallingIdentity(token); } + return true; } @Override @@ -6394,17 +6439,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void setTrustAgentConfiguration(ComponentName admin, ComponentName agent, - PersistableBundle args) { + PersistableBundle args, boolean parent) { if (!mHasFeature) { return; } Preconditions.checkNotNull(admin, "admin is null"); Preconditions.checkNotNull(agent, "agent is null"); final int userHandle = UserHandle.getCallingUserId(); - enforceNotManagedProfile(userHandle, "set trust agent configuration"); synchronized (this) { ActiveAdmin ap = getActiveAdminForCallerLocked(admin, - DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES); + DeviceAdminInfo.USES_POLICY_DISABLE_KEYGUARD_FEATURES, parent); ap.trustAgentInfos.put(agent.flattenToString(), new TrustAgentInfo(args)); saveSettingsLocked(userHandle); } @@ -6412,7 +6456,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public List<PersistableBundle> getTrustAgentConfiguration(ComponentName admin, - ComponentName agent, int userHandle) { + ComponentName agent, int userHandle, boolean parent) { if (!mHasFeature) { return null; } @@ -6422,46 +6466,44 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { synchronized (this) { final String componentName = agent.flattenToString(); if (admin != null) { - final ActiveAdmin ap = getActiveAdminUncheckedLocked(admin, userHandle); + final ActiveAdmin ap = getActiveAdminUncheckedLocked(admin, userHandle, parent); if (ap == null) return null; TrustAgentInfo trustAgentInfo = ap.trustAgentInfos.get(componentName); if (trustAgentInfo == null || trustAgentInfo.options == null) return null; - List<PersistableBundle> result = new ArrayList<PersistableBundle>(); + List<PersistableBundle> result = new ArrayList<>(); result.add(trustAgentInfo.options); return result; } // Return strictest policy for this user and profiles that are visible from this user. - final List<UserInfo> profiles = mUserManager.getProfiles(userHandle); List<PersistableBundle> result = null; - // Search through all admins that use KEYGUARD_DISABLE_TRUST_AGENTS and keep track // of the options. If any admin doesn't have options, discard options for the rest // and return null. + List<ActiveAdmin> admins = + getActiveAdminsForLockscreenPoliciesLocked(userHandle, parent); boolean allAdminsHaveOptions = true; - for (UserInfo userInfo : profiles) { - DevicePolicyData policy = getUserDataUnchecked(userInfo.id); - final int N = policy.mAdminList.size(); - for (int i=0; i < N; i++) { - final ActiveAdmin active = policy.mAdminList.get(i); - final boolean disablesTrust = (active.disabledKeyguardFeatures - & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0; - final TrustAgentInfo info = active.trustAgentInfos.get(componentName); - if (info != null && info.options != null && !info.options.isEmpty()) { - if (disablesTrust) { - if (result == null) { - result = new ArrayList<PersistableBundle>(); - } - result.add(info.options); - } else { - Log.w(LOG_TAG, "Ignoring admin " + active.info - + " because it has trust options but doesn't declare " - + "KEYGUARD_DISABLE_TRUST_AGENTS"); + final int N = admins.size(); + for (int i = 0; i < N; i++) { + final ActiveAdmin active = admins.get(i); + + final boolean disablesTrust = (active.disabledKeyguardFeatures + & DevicePolicyManager.KEYGUARD_DISABLE_TRUST_AGENTS) != 0; + final TrustAgentInfo info = active.trustAgentInfos.get(componentName); + if (info != null && info.options != null && !info.options.isEmpty()) { + if (disablesTrust) { + if (result == null) { + result = new ArrayList<>(); } - } else if (disablesTrust) { - allAdminsHaveOptions = false; - break; + result.add(info.options); + } else { + Log.w(LOG_TAG, "Ignoring admin " + active.info + + " because it has trust options but doesn't declare " + + "KEYGUARD_DISABLE_TRUST_AGENTS"); } + } else if (disablesTrust) { + allAdminsHaveOptions = false; + break; } } return allAdminsHaveOptions ? result : null; diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 659450efcce3..e7ae2b0fcfd5 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -157,6 +157,8 @@ public final class SystemServer { "com.google.android.clockwork.ThermalObserver"; private static final String WEAR_BLUETOOTH_SERVICE_CLASS = "com.google.android.clockwork.bluetooth.WearBluetoothService"; + private static final String CONTENT_SERVICE_CLASS = + "com.android.server.content.ContentService$Lifecycle"; private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst"; @@ -574,8 +576,7 @@ public final class SystemServer { Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); traceBeginAndSlog("StartContentService"); - contentService = ContentService.main(context, - mFactoryTestMode == FactoryTest.FACTORY_TEST_LOW_LEVEL); + mSystemServiceManager.startService(CONTENT_SERVICE_CLASS); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); traceBeginAndSlog("InstallSystemProviders"); @@ -1324,7 +1325,7 @@ public final class SystemServer { reportWtf("starting System UI", e); } Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); - Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeMountServiceReady"); + Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeNetworkScoreReady"); try { if (networkScoreF != null) networkScoreF.systemReady(); } catch (Throwable e) { @@ -1423,6 +1424,12 @@ public final class SystemServer { } catch (Throwable e) { reportWtf("Notifying MmsService running", e); } + + try { + if (networkScoreF != null) networkScoreF.systemRunning(); + } catch (Throwable e) { + reportWtf("Notifying NetworkScoreService running", e); + } Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } }); diff --git a/services/net/java/android/net/apf/ApfFilter.java b/services/net/java/android/net/apf/ApfFilter.java index ebbf99101e42..f430a3034630 100644 --- a/services/net/java/android/net/apf/ApfFilter.java +++ b/services/net/java/android/net/apf/ApfFilter.java @@ -18,6 +18,7 @@ package android.net.apf; import static android.system.OsConstants.*; +import android.net.LinkProperties; import android.net.NetworkUtils; import android.net.apf.ApfGenerator; import android.net.apf.ApfGenerator.IllegalInstructionException; @@ -136,6 +137,16 @@ public class ApfFilter { // NOTE: this must be added to the IPv4 header length in IPV4_HEADER_SIZE_MEMORY_SLOT private static final int DHCP_CLIENT_MAC_OFFSET = ETH_HEADER_LEN + UDP_HEADER_LEN + 28; + private static int ARP_HEADER_OFFSET = ETH_HEADER_LEN; + private static final byte[] ARP_IPV4_REQUEST_HEADER = new byte[]{ + 0, 1, // Hardware type: Ethernet (1) + 8, 0, // Protocol type: IP (0x0800) + 6, // Hardware size: 6 + 4, // Protocol size: 4 + 0, 1 // Opcode: request (1) + }; + private static int ARP_TARGET_IP_ADDRESS_OFFSET = ETH_HEADER_LEN + 24; + private final ApfCapabilities mApfCapabilities; private final IpManager.Callback mIpManagerCallback; private final NetworkInterface mNetworkInterface; @@ -145,12 +156,16 @@ public class ApfFilter { private long mUniqueCounter; @GuardedBy("this") private boolean mMulticastFilter; + // Our IPv4 address, if we have just one, otherwise null. + @GuardedBy("this") + private byte[] mIPv4Address; private ApfFilter(ApfCapabilities apfCapabilities, NetworkInterface networkInterface, - IpManager.Callback ipManagerCallback) { + IpManager.Callback ipManagerCallback, boolean multicastFilter) { mApfCapabilities = apfCapabilities; mIpManagerCallback = ipManagerCallback; mNetworkInterface = networkInterface; + mMulticastFilter = multicastFilter; maybeStartFilter(); } @@ -225,6 +240,7 @@ public class ApfFilter { private static final int ICMP6_4_BYTE_LIFETIME_OFFSET = 4; private static final int ICMP6_4_BYTE_LIFETIME_LEN = 4; + // Note: mPacket's position() cannot be assumed to be reset. private final ByteBuffer mPacket; // List of binary ranges that include the whole packet except the lifetimes. // Pairs consist of offset and length. @@ -378,17 +394,12 @@ public class ApfFilter { // Ignoring lifetimes (which may change) does {@code packet} match this RA? boolean matches(byte[] packet, int length) { - if (length != mPacket.limit()) return false; - ByteBuffer a = ByteBuffer.wrap(packet); - ByteBuffer b = mPacket; + if (length != mPacket.capacity()) return false; + byte[] referencePacket = mPacket.array(); for (Pair<Integer, Integer> nonLifetime : mNonLifetimes) { - a.clear(); - b.clear(); - a.position(nonLifetime.first); - b.position(nonLifetime.first); - a.limit(nonLifetime.first + nonLifetime.second); - b.limit(nonLifetime.first + nonLifetime.second); - if (a.compareTo(b) != 0) return false; + for (int i = nonLifetime.first; i < (nonLifetime.first + nonLifetime.second); i++) { + if (packet[i] != referencePacket[i]) return false; + } } return true; } @@ -440,7 +451,7 @@ public class ApfFilter { String nextFilterLabel = "Ra" + getUniqueNumberLocked(); // Skip if packet is not the right size gen.addLoadFromMemory(Register.R0, gen.PACKET_SIZE_MEMORY_SLOT); - gen.addJumpIfR0NotEquals(mPacket.limit(), nextFilterLabel); + gen.addJumpIfR0NotEquals(mPacket.capacity(), nextFilterLabel); int filterLifetime = (int)(currentLifetime() / FRACTION_OF_LIFETIME_TO_FILTER); // Skip filter if expired gen.addLoadFromMemory(Register.R0, gen.FILTER_AGE_MEMORY_SLOT); @@ -510,6 +521,33 @@ public class ApfFilter { private byte[] mLastInstalledProgram; /** + * Generate filter code to process ARP packets. Execution of this code ends in either the + * DROP_LABEL or PASS_LABEL and does not fall off the end. + * Preconditions: + * - Packet being filtered is ARP + */ + @GuardedBy("this") + private void generateArpFilterLocked(ApfGenerator gen) throws IllegalInstructionException { + // Here's a basic summary of what the ARP filter program does: + // + // if it's not an ARP IPv4 request: + // pass + // if it's not a request for our IPv4 address: + // drop + // pass + + // if it's not an ARP IPv4 request, pass + gen.addLoadImmediate(Register.R0, ARP_HEADER_OFFSET); + gen.addJumpIfBytesNotEqual(Register.R0, ARP_IPV4_REQUEST_HEADER, gen.PASS_LABEL); + // if it's not a request for our IPv4 address, drop + gen.addLoadImmediate(Register.R0, ARP_TARGET_IP_ADDRESS_OFFSET); + gen.addJumpIfBytesNotEqual(Register.R0, mIPv4Address, gen.DROP_LABEL); + + // Otherwise, pass + gen.addJump(gen.PASS_LABEL); + } + + /** * Generate filter code to process IPv4 packets. Execution of this code ends in either the * DROP_LABEL or PASS_LABEL and does not fall off the end. * Preconditions: @@ -566,7 +604,6 @@ public class ApfFilter { * DROP_LABEL or PASS_LABEL, or falls off the end for ICMPv6 packets. * Preconditions: * - Packet being filtered is IPv6 - * - R1 is initialized to 0 */ @GuardedBy("this") private void generateIPv6FilterLocked(ApfGenerator gen) throws IllegalInstructionException { @@ -598,6 +635,7 @@ public class ApfFilter { /** * Begin generating an APF program to: * <ul> + * <li>Drop ARP requests not for us, if mIPv4Address is set, * <li>Drop IPv4 broadcast packets, except DHCP destined to our MAC, * <li>Drop IPv4 multicast packets, if mMulticastFilter, * <li>Pass all other IPv4 packets, @@ -616,16 +654,31 @@ public class ApfFilter { // Here's a basic summary of what the initial program does: // + // if it's ARP: + // inesrt ARP filter to drop or pass these appropriately // if it's IPv4: // insert IPv4 filter to drop or pass these appropriately // if it's not IPv6: // pass // insert IPv6 filter to drop, pass, or fall off the end for ICMPv6 packets + gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET); + + if (mIPv4Address != null) { + // Add ARP filters: + String skipArpFiltersLabel = "skipArpFilters"; + // If not ARP, skip ARP filters + // NOTE: Relies on R0 containing ethertype. + gen.addJumpIfR0NotEquals(ETH_P_ARP, skipArpFiltersLabel); + generateArpFilterLocked(gen); + gen.defineLabel(skipArpFiltersLabel); + } + // Add IPv4 filters: String skipIPv4FiltersLabel = "skipIPv4Filters"; - // If not IPv4, skip IPv4 filters - gen.addLoad16(Register.R0, ETH_ETHERTYPE_OFFSET); + // NOTE: Relies on R0 containing ethertype. This is safe because if we got here, we did not + // execute the ARP filter, since that filter does not fall through, but either drops or + // passes. gen.addJumpIfR0NotEquals(ETH_P_IP, skipIPv4FiltersLabel); // NOTE: Relies on R1 being initialized to 0. generateIPv4FilterLocked(gen); @@ -634,8 +687,8 @@ public class ApfFilter { // Add IPv6 filters: // If not IPv6, pass // NOTE: Relies on R0 containing ethertype. This is safe because if we got here, we did not - // execute the IPv4 filter, since that filter does not fall through, but either drops or - // passes. + // execute the ARP or IPv4 filters, since those filters do not fall through, but either + // drop or pass. gen.addJumpIfR0NotEquals(ETH_P_IPV6, gen.PASS_LABEL); generateIPv6FilterLocked(gen); return gen; @@ -752,7 +805,8 @@ public class ApfFilter { * filtering using APF programs. */ public static ApfFilter maybeCreate(ApfCapabilities apfCapabilities, - NetworkInterface networkInterface, IpManager.Callback ipManagerCallback) { + NetworkInterface networkInterface, IpManager.Callback ipManagerCallback, + boolean multicastFilter) { if (apfCapabilities == null || networkInterface == null) return null; if (apfCapabilities.apfVersionSupported == 0) return null; if (apfCapabilities.maximumApfProgramSize < 512) { @@ -768,7 +822,7 @@ public class ApfFilter { Log.e(TAG, "Unsupported APF version: " + apfCapabilities.apfVersionSupported); return null; } - return new ApfFilter(apfCapabilities, networkInterface, ipManagerCallback); + return new ApfFilter(apfCapabilities, networkInterface, ipManagerCallback, multicastFilter); } public synchronized void shutdown() { @@ -787,10 +841,36 @@ public class ApfFilter { } } + // Find the single IPv4 address if there is one, otherwise return null. + private static byte[] findIPv4Address(LinkProperties lp) { + byte[] ipv4Address = null; + for (InetAddress inetAddr : lp.getAddresses()) { + byte[] addr = inetAddr.getAddress(); + if (addr.length != 4) continue; + // More than one IPv4 address, abort + if (ipv4Address != null && !Arrays.equals(ipv4Address, addr)) return null; + ipv4Address = addr; + } + return ipv4Address; + } + + public synchronized void setLinkProperties(LinkProperties lp) { + // NOTE: Do not keep a copy of LinkProperties as it would further duplicate state. + byte[] ipv4Address = findIPv4Address(lp); + // If ipv4Address is the same as mIPv4Address, then there's no change, just return. + if (Arrays.equals(ipv4Address, mIPv4Address)) return; + // Otherwise update mIPv4Address and install new program. + mIPv4Address = ipv4Address; + installNewProgramLocked(); + } + public synchronized void dump(IndentingPrintWriter pw) { - pw.println("APF version: " + mApfCapabilities.apfVersionSupported); - pw.println("Max program size: " + mApfCapabilities.maximumApfProgramSize); + pw.println("APF caps: " + mApfCapabilities); pw.println("Receive thread: " + (mReceiveThread != null ? "RUNNING" : "STOPPED")); + pw.println("Multicast filtering: " + mMulticastFilter); + try { + pw.println("IPv4 address: " + InetAddress.getByAddress(mIPv4Address)); + } catch (UnknownHostException|NullPointerException e) {} if (mLastTimeInstalledProgram == 0) { pw.println("No program installed."); return; diff --git a/services/net/java/android/net/ip/IpManager.java b/services/net/java/android/net/ip/IpManager.java index d10834ad9695..54aeb3db7319 100644 --- a/services/net/java/android/net/ip/IpManager.java +++ b/services/net/java/android/net/ip/IpManager.java @@ -100,10 +100,6 @@ public class IpManager extends StateMachine { public void onProvisioningSuccess(LinkProperties newLp) {} public void onProvisioningFailure(LinkProperties newLp) {} - // This is called whenever 464xlat is being enabled or disabled (i.e. - // started or stopped). - public void on464XlatChange(boolean enabled) {} - // Invoked on LinkProperties changes. public void onLinkPropertiesChange(LinkProperties newLp) {} @@ -116,6 +112,14 @@ public class IpManager extends StateMachine { // Install an APF program to filter incoming packets. public void installPacketFilter(byte[] filter) {} + + // If multicast filtering cannot be accomplished with APF, this function will be called to + // actuate multicast filtering using another means. + public void setFallbackMulticastFilter(boolean enabled) {} + + // Enabled/disable Neighbor Discover offload functionality. This is + // called, for example, whenever 464xlat is being started or stopped. + public void setNeighborDiscoveryOffload(boolean enable) {} } public static class WaitForProvisioningCallback extends Callback { @@ -222,6 +226,7 @@ public class IpManager extends StateMachine { private static final int EVENT_NETLINK_LINKPROPERTIES_CHANGED = 5; private static final int CMD_UPDATE_TCP_BUFFER_SIZES = 6; private static final int CMD_UPDATE_HTTP_PROXY = 7; + private static final int CMD_SET_MULTICAST_FILTER = 8; private static final int MAX_LOG_RECORDS = 1000; @@ -258,6 +263,7 @@ public class IpManager extends StateMachine { private String mTcpBufferSizes; private ProxyInfo mHttpProxy; private ApfFilter mApfFilter; + private boolean mMulticastFiltering; /** * Member variables accessed both from within the StateMachine thread @@ -296,15 +302,20 @@ public class IpManager extends StateMachine { }) { @Override public void interfaceAdded(String iface) { + super.interfaceAdded(iface); if (mClatInterfaceName.equals(iface)) { - mCallback.on464XlatChange(true); + mCallback.setNeighborDiscoveryOffload(false); } } @Override public void interfaceRemoved(String iface) { + super.interfaceRemoved(iface); if (mClatInterfaceName.equals(iface)) { - mCallback.on464XlatChange(false); + // TODO: consider sending a message to the IpManager main + // StateMachine thread, in case "NDO enabled" state becomes + // tied to more things that 464xlat operation. + mCallback.setNeighborDiscoveryOffload(true); } } }; @@ -390,6 +401,14 @@ public class IpManager extends StateMachine { sendMessage(CMD_UPDATE_HTTP_PROXY, proxyInfo); } + /** + * Enable or disable the multicast filter. Attempts to use APF to accomplish the filtering, + * if not, Callback.setFallbackMulticastFilter() is called. + */ + public void setMulticastFilter(boolean enabled) { + sendMessage(CMD_SET_MULTICAST_FILTER, enabled); + } + public LinkProperties getLinkProperties() { synchronized (mLock) { return new LinkProperties(mLinkProperties); @@ -519,6 +538,7 @@ public class IpManager extends StateMachine { } private void dispatchCallback(ProvisioningChange delta, LinkProperties newLp) { + if (mApfFilter != null) mApfFilter.setLinkProperties(newLp); switch (delta) { case GAINED_PROVISIONING: if (VDBG) { Log.d(mTag, "onProvisioningSuccess()"); } @@ -729,6 +749,10 @@ public class IpManager extends StateMachine { handleLinkPropertiesUpdate(NO_CALLBACKS); break; + case CMD_SET_MULTICAST_FILTER: + mMulticastFiltering = (boolean) msg.obj; + break; + case DhcpClient.CMD_ON_QUIT: // Everything is already stopped. Log.e(mTag, "Unexpected CMD_ON_QUIT (already stopped)."); @@ -769,7 +793,10 @@ public class IpManager extends StateMachine { @Override public void enter() { mApfFilter = ApfFilter.maybeCreate(mConfiguration.mApfCapabilities, mNetworkInterface, - mCallback); + mCallback, mMulticastFiltering); + // TODO: investigate the effects of any multicast filtering racing/interfering with the + // rest of this IP configuration startup. + if (mApfFilter == null) mCallback.setFallbackMulticastFilter(mMulticastFiltering); // Set privacy extensions. try { mNwService.setInterfaceIpv6PrivacyExtensions(mInterfaceName, true); @@ -882,6 +909,16 @@ public class IpManager extends StateMachine { handleLinkPropertiesUpdate(SEND_CALLBACKS); break; + case CMD_SET_MULTICAST_FILTER: { + mMulticastFiltering = (boolean) msg.obj; + if (mApfFilter != null) { + mApfFilter.setMulticastFilter(mMulticastFiltering); + } else { + mCallback.setFallbackMulticastFilter(mMulticastFiltering); + } + break; + } + case DhcpClient.CMD_PRE_DHCP_ACTION: if (VDBG) { Log.d(mTag, "onPreDhcpAction()"); } if (mConfiguration.mRequestedPreDhcpAction) { diff --git a/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java index 5b70c17ae28d..07280bc881d8 100644 --- a/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java +++ b/services/tests/servicestests/src/com/android/server/content/ObserverNodeTest.java @@ -62,7 +62,7 @@ public class ObserverNodeTest extends AndroidTestCase { ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>(); for (int i = nums.length - 1; i >=0; --i) { - root.collectObserversLocked(uris[i], 0, null, false, myUserHandle, calls); + root.collectObserversLocked(uris[i], 0, null, false, 0, myUserHandle, calls); assertEquals(nums[i], calls.size()); calls.clear(); } @@ -92,7 +92,7 @@ public class ObserverNodeTest extends AndroidTestCase { ArrayList<ObserverCall> calls = new ArrayList<ObserverCall>(); for (int i = uris.length - 1; i >=0; --i) { - root.collectObserversLocked(uris[i], 0, null, false, myUserHandle, calls); + root.collectObserversLocked(uris[i], 0, null, false, 0, myUserHandle, calls); assertEquals(nums[i], calls.size()); calls.clear(); } diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java index 0e2a80c8b302..baa5d361c1a1 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java @@ -16,8 +16,11 @@ package com.android.server.pm; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyList; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.spy; @@ -46,6 +49,7 @@ import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutManager; import android.content.pm.ShortcutServiceInternal; import android.content.pm.Signature; +import android.content.pm.UserInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; @@ -68,6 +72,7 @@ import android.test.mock.MockContext; import android.test.suitebuilder.annotation.SmallTest; import android.util.ArraySet; import android.util.Log; +import android.util.Pair; import android.util.SparseArray; import com.android.frameworks.servicestests.R; @@ -99,6 +104,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.BiPredicate; import java.util.function.Consumer; /** @@ -124,7 +130,7 @@ public class ShortcutManagerTest extends InstrumentationTestCase { */ private static final boolean ENABLE_DUMP = false; // DO NOT SUBMIT WITH true - private static final boolean DUMP_ON_TEARDOWN = false; // DO NOT SUBMIT WITH true + private static final boolean DUMP_IN_TEARDOWN = false; // DO NOT SUBMIT WITH true // public for mockito public class BaseContext extends MockContext { @@ -264,9 +270,7 @@ public class ShortcutManagerTest extends InstrumentationTestCase { @Override boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId) { - // Sort of hack; do a simpler check. - return LAUNCHER_1.equals(callingPackage) || LAUNCHER_2.equals(callingPackage) - || LAUNCHER_3.equals(callingPackage) || LAUNCHER_4.equals(callingPackage); + return mDefaultLauncherChecker.test(callingPackage, userId); } @Override @@ -284,12 +288,7 @@ public class ShortcutManagerTest extends InstrumentationTestCase { @Override void postToHandler(Runnable r) { final long token = mContext.injectClearCallingIdentity(); - super.postToHandler(r); - try { - runTestOnUiThread(() -> {}); - } catch (Throwable e) { - fail("runTestOnUiThread failed: " + e); - } + r.run(); mContext.injectRestoreCallingIdentity(token); } @@ -321,36 +320,11 @@ public class ShortcutManagerTest extends InstrumentationTestCase { } @Override - public void ensureInUserProfiles(UserHandle userToCheck, String message) { - if (getCallingUserId() == userToCheck.getIdentifier()) { - return; // okay - } - if (getCallingUserId() == USER_0 && userToCheck.getIdentifier() == USER_P0) { - return; // profile, okay. - } - if (getCallingUserId() == USER_P0 && userToCheck.getIdentifier() == USER_0) { - return; // profile, okay. - } - - if (mInjectedCallingUid != Process.SYSTEM_UID) { - throw new SecurityException("To access other users, you need to be SYSTEM" + - ", but current UID=" + mInjectedCallingUid); - } - } - - @Override public void verifyCallingPackage(String callingPackage) { // SKIP } @Override - boolean isEnabledProfileOf(UserHandle user, UserHandle listeningUser, String debugMsg) { - // This requires CROSS_USER - assertEquals(Process.SYSTEM_UID, mInjectedCallingUid); - return user.getIdentifier() == listeningUser.getIdentifier(); - } - - @Override void postToPackageMonitorHandler(Runnable r) { final long token = mContext.injectClearCallingIdentity(); r.run(); @@ -361,6 +335,18 @@ public class ShortcutManagerTest extends InstrumentationTestCase { int injectBinderCallingUid() { return mInjectedCallingUid; } + + @Override + long injectClearCallingIdentity() { + final int prevCallingUid = mInjectedCallingUid; + mInjectedCallingUid = Process.SYSTEM_UID; + return prevCallingUid; + } + + @Override + void injectRestoreCallingIdentity(long token) { + mInjectedCallingUid = (int) token; + } } private class LauncherAppsTestable extends LauncherApps { @@ -386,7 +372,11 @@ public class ShortcutManagerTest extends InstrumentationTestCase { private ShortcutServiceInternal mInternal; private LauncherAppImplTestable mLauncherAppImpl; - private LauncherAppsTestable mLauncherApps; + + // LauncherApps has per-instace state, so we need a differnt instance for each launcher. + private final Map<Pair<Integer, String>, LauncherAppsTestable> + mLauncherAppsMap = new HashMap<>(); + private LauncherAppsTestable mLauncherApps; // Current one private File mInjectedFilePathRoot; @@ -439,6 +429,24 @@ public class ShortcutManagerTest extends InstrumentationTestCase { private static final UserHandle HANDLE_USER_11 = UserHandle.of(USER_11); private static final UserHandle HANDLE_USER_P0 = UserHandle.of(USER_P0); + private static final UserInfo USER_INFO_0 = withProfileGroupId( + new UserInfo(USER_0, "user0", + UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED), 10); + + private static final UserInfo USER_INFO_10 = + new UserInfo(USER_10, "user10", UserInfo.FLAG_INITIALIZED); + + private static final UserInfo USER_INFO_11 = + new UserInfo(USER_11, "user11", UserInfo.FLAG_INITIALIZED); + + private static final UserInfo USER_INFO_P0 = withProfileGroupId( + new UserInfo(USER_P0, "userP0", + UserInfo.FLAG_MANAGED_PROFILE), 10); + + private BiPredicate<String, Integer> mDefaultLauncherChecker = + (callingPackage, userId) -> + LAUNCHER_1.equals(callingPackage) || LAUNCHER_2.equals(callingPackage) + || LAUNCHER_3.equals(callingPackage) || LAUNCHER_4.equals(callingPackage); private static final long START_TIME = 1440000000101L; @@ -494,20 +502,46 @@ public class ShortcutManagerTest extends InstrumentationTestCase { mInjectedFilePathRoot = new File(getTestContext().getCacheDir(), "test-files"); - // Empty the data directory. - if (mInjectedFilePathRoot.exists()) { - Assert.assertTrue("failed to delete dir", - FileUtils.deleteContents(mInjectedFilePathRoot)); - } - mInjectedFilePathRoot.mkdirs(); + deleteAllSavedFiles(); + + // Set up users. + doAnswer(inv -> { + assertSystem(); + return USER_INFO_0; + }).when(mMockUserManager).getUserInfo(eq(USER_0)); + + doAnswer(inv -> { + assertSystem(); + return USER_INFO_10; + }).when(mMockUserManager).getUserInfo(eq(USER_10)); + + doAnswer(inv -> { + assertSystem(); + return USER_INFO_11; + }).when(mMockUserManager).getUserInfo(eq(USER_11)); + + doAnswer(inv -> { + assertSystem(); + return USER_INFO_P0; + }).when(mMockUserManager).getUserInfo(eq(USER_P0)); + + // User 0 is always running. + when(mMockUserManager.isUserRunning(eq(USER_0))).thenReturn(true); initService(); setCaller(CALLING_PACKAGE_1); } + private static UserInfo withProfileGroupId(UserInfo in, int groupId) { + in.profileGroupId = groupId; + return in; + } + @Override protected void tearDown() throws Exception { - if (DUMP_ON_TEARDOWN) dumpsysOnLogcat("Teardown"); + if (DUMP_IN_TEARDOWN) dumpsysOnLogcat("Teardown"); + + shutdownServices(); super.tearDown(); } @@ -516,8 +550,19 @@ public class ShortcutManagerTest extends InstrumentationTestCase { return getInstrumentation().getContext(); } + private void deleteAllSavedFiles() { + // Empty the data directory. + if (mInjectedFilePathRoot.exists()) { + Assert.assertTrue("failed to delete dir", + FileUtils.deleteContents(mInjectedFilePathRoot)); + } + mInjectedFilePathRoot.mkdirs(); + } + /** (Re-) init the manager and the service. */ private void initService() { + shutdownServices(); + LocalServices.removeServiceForTest(ShortcutServiceInternal.class); // Instantiate targets. @@ -527,12 +572,28 @@ public class ShortcutManagerTest extends InstrumentationTestCase { mInternal = LocalServices.getService(ShortcutServiceInternal.class); mLauncherAppImpl = new LauncherAppImplTestable(mServiceContext); - mLauncherApps = new LauncherAppsTestable(mClientContext, mLauncherAppImpl); + mLauncherApps = null; + mLauncherAppsMap.clear(); // Load the setting file. mService.onBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); } + private void shutdownServices() { + if (mService != null) { + // Flush all the unsaved data from the previous instance. + mService.saveDirtyInfo(); + } + LocalServices.removeServiceForTest(ShortcutServiceInternal.class); + + mService = null; + mManager = null; + mInternal = null; + mLauncherAppImpl = null; + mLauncherApps = null; + mLauncherAppsMap.clear(); + } + private void addPackage(String packageName, int uid, int version) { addPackage(packageName, uid, version, packageName); } @@ -615,6 +676,13 @@ public class ShortcutManagerTest extends InstrumentationTestCase { mInjectedCallingUid = Preconditions.checkNotNull(getInjectedPackageInfo(packageName, userId, false), "Unknown package").applicationInfo.uid; + + // Set up LauncherApps for this caller. + final Pair<Integer, String> key = Pair.create(userId, packageName); + if (!mLauncherAppsMap.containsKey(key)) { + mLauncherAppsMap.put(key, new LauncherAppsTestable(mClientContext, mLauncherAppImpl)); + } + mLauncherApps = mLauncherAppsMap.get(key); } private void setCaller(String packageName) { @@ -625,6 +693,10 @@ public class ShortcutManagerTest extends InstrumentationTestCase { return mInjectedClientPackage; } + private void setDefaultLauncherChecker(BiPredicate<String, Integer> p) { + mDefaultLauncherChecker = p; + } + private void runWithCaller(String packageName, int userId, Runnable r) { final String previousPackage = mInjectedClientPackage; final int previousUserId = UserHandle.getUserId(mInjectedCallingUid); @@ -849,6 +921,12 @@ public class ShortcutManagerTest extends InstrumentationTestCase { return ret; } + private static void resetAll(Collection<?> mocks) { + for (Object o : mocks) { + reset(o); + } + } + @NonNull private ShortcutInfo findById(List<ShortcutInfo> list, String id) { for (ShortcutInfo s : list) { @@ -860,6 +938,10 @@ public class ShortcutManagerTest extends InstrumentationTestCase { return null; } + private void assertSystem() { + assertEquals("Caller must be system", Process.SYSTEM_UID, mInjectedCallingUid); + } + private void assertResetTimes(long expectedLastResetTime, long expectedNextResetTime) { assertEquals(expectedLastResetTime, mService.getLastResetTimeLocked()); assertEquals(expectedNextResetTime, mService.getNextResetTimeLocked()); @@ -948,7 +1030,7 @@ public class ShortcutManagerTest extends InstrumentationTestCase { private List<ShortcutInfo> assertAllHaveIcon( @NonNull List<ShortcutInfo> actualShortcuts) { for (ShortcutInfo s : actualShortcuts) { - assertTrue("ID " + s.getId(), s.hasIconFile() || s.hasIconResource()); + assertTrue("ID " + s.getId() + " has no icon ", s.hasIconFile() || s.hasIconResource()); } return actualShortcuts; } @@ -957,7 +1039,8 @@ public class ShortcutManagerTest extends InstrumentationTestCase { private List<ShortcutInfo> assertAllHaveFlags(@NonNull List<ShortcutInfo> actualShortcuts, int shortcutFlags) { for (ShortcutInfo s : actualShortcuts) { - assertTrue("ID " + s.getId(), s.hasFlags(shortcutFlags)); + assertTrue("ID " + s.getId() + " doesn't have flags " + shortcutFlags, + s.hasFlags(shortcutFlags)); } return actualShortcuts; } @@ -3008,12 +3091,6 @@ public class ShortcutManagerTest extends InstrumentationTestCase { } public void testLauncherCallback() throws Throwable { - - // TODO Add "multi" version -- run the test with two launchers and make sure the callback - // argument only contains the ones that are actually visible to each launcher. - - when(mMockUserManager.isUserRunning(eq(USER_0))).thenReturn(true); - LauncherApps.Callback c0 = mock(LauncherApps.Callback.class); // Set listeners @@ -3069,6 +3146,7 @@ public class ShortcutManagerTest extends InstrumentationTestCase { // Test for addDynamicShortcut. reset(c0); runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> { + dumpsysOnLogcat("before addDynamicShortcut"); assertTrue(mManager.addDynamicShortcut(makeShortcut("s4"))); }); @@ -3146,6 +3224,156 @@ public class ShortcutManagerTest extends InstrumentationTestCase { assertEquals(0, shortcuts.getValue().size()); } + private void assertCallbackNotReceived(LauncherApps.Callback mock) { + verify(mock, times(0)).onShortcutsChanged(anyString(), anyList(), + any(UserHandle.class)); + } + + private void assertCallbackReceived(LauncherApps.Callback mock, + UserHandle user, String packageName, String... ids) { + ArgumentCaptor<List> shortcutsCaptor = ArgumentCaptor.forClass(List.class); + + verify(mock, times(1)).onShortcutsChanged(eq(packageName), shortcutsCaptor.capture(), + eq(user)); + assertShortcutIds(shortcutsCaptor.getValue(), ids); + } + + public void testLauncherCallback_crossProfile() throws Throwable { + prepareCrossProfileDataSet(); + + final Handler h = new Handler(Looper.getMainLooper()); + + final LauncherApps.Callback c0_1 = mock(LauncherApps.Callback.class); + final LauncherApps.Callback c0_2 = mock(LauncherApps.Callback.class); + final LauncherApps.Callback c0_3 = mock(LauncherApps.Callback.class); + final LauncherApps.Callback c0_4 = mock(LauncherApps.Callback.class); + + final LauncherApps.Callback cP0_1 = mock(LauncherApps.Callback.class); + final LauncherApps.Callback c10_1 = mock(LauncherApps.Callback.class); + final LauncherApps.Callback c10_2 = mock(LauncherApps.Callback.class); + final LauncherApps.Callback c11_1 = mock(LauncherApps.Callback.class); + + final List<LauncherApps.Callback> all = + list(c0_1, c0_2, c0_3, c0_4, cP0_1, c10_1, c11_1); + + setDefaultLauncherChecker((pkg, userId) -> { + switch (userId) { + case USER_0: + return LAUNCHER_2.equals(pkg); + case USER_P0: + return LAUNCHER_1.equals(pkg); + case USER_10: + return LAUNCHER_1.equals(pkg); + case USER_11: + return LAUNCHER_1.equals(pkg); + default: + return false; + } + }); + + runWithCaller(LAUNCHER_1, USER_0, () -> mLauncherApps.registerCallback(c0_1, h)); + runWithCaller(LAUNCHER_2, USER_0, () -> mLauncherApps.registerCallback(c0_2, h)); + runWithCaller(LAUNCHER_3, USER_0, () -> mLauncherApps.registerCallback(c0_3, h)); + runWithCaller(LAUNCHER_4, USER_0, () -> mLauncherApps.registerCallback(c0_4, h)); + runWithCaller(LAUNCHER_1, USER_P0, () -> mLauncherApps.registerCallback(cP0_1, h)); + runWithCaller(LAUNCHER_1, USER_10, () -> mLauncherApps.registerCallback(c10_1, h)); + runWithCaller(LAUNCHER_2, USER_10, () -> mLauncherApps.registerCallback(c10_2, h)); + runWithCaller(LAUNCHER_1, USER_11, () -> mLauncherApps.registerCallback(c11_1, h)); + + // User 0. + + resetAll(all); + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + mManager.deleteDynamicShortcut("x"); + }); + waitOnMainThread(); + + assertCallbackNotReceived(c0_1); + assertCallbackNotReceived(c0_3); + assertCallbackNotReceived(c0_4); + assertCallbackNotReceived(c10_1); + assertCallbackNotReceived(c10_2); + assertCallbackNotReceived(c11_1); + assertCallbackReceived(c0_2, HANDLE_USER_0, CALLING_PACKAGE_1, "s1", "s2", "s3"); + assertCallbackReceived(cP0_1, HANDLE_USER_0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s4"); + + // User 0, different package. + + resetAll(all); + runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { + mManager.deleteDynamicShortcut("x"); + }); + waitOnMainThread(); + + assertCallbackNotReceived(c0_1); + assertCallbackNotReceived(c0_3); + assertCallbackNotReceived(c0_4); + assertCallbackNotReceived(c10_1); + assertCallbackNotReceived(c10_2); + assertCallbackNotReceived(c11_1); + assertCallbackReceived(c0_2, HANDLE_USER_0, CALLING_PACKAGE_3, "s1", "s2", "s3", "s4"); + assertCallbackReceived(cP0_1, HANDLE_USER_0, CALLING_PACKAGE_3, + "s1", "s2", "s3", "s4", "s5", "s6"); + + // Work profile, but not running, so don't send notifications. + + resetAll(all); + runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { + mManager.deleteDynamicShortcut("x"); + }); + waitOnMainThread(); + + assertCallbackNotReceived(c0_1); + assertCallbackNotReceived(c0_2); + assertCallbackNotReceived(c0_3); + assertCallbackNotReceived(c0_4); + assertCallbackNotReceived(cP0_1); + assertCallbackNotReceived(c10_1); + assertCallbackNotReceived(c10_2); + assertCallbackNotReceived(c11_1); + + // Work profile, now running. + + when(mMockUserManager.isUserRunning(anyInt())).thenReturn(false); + when(mMockUserManager.isUserRunning(eq(USER_P0))).thenReturn(true); + + resetAll(all); + runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { + mManager.deleteDynamicShortcut("x"); + }); + waitOnMainThread(); + + assertCallbackNotReceived(c0_1); + assertCallbackNotReceived(c0_3); + assertCallbackNotReceived(c0_4); + assertCallbackNotReceived(c10_1); + assertCallbackNotReceived(c10_2); + assertCallbackNotReceived(c11_1); + assertCallbackReceived(c0_2, HANDLE_USER_P0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s5"); + assertCallbackReceived(cP0_1, HANDLE_USER_P0, CALLING_PACKAGE_1, "s1", "s2", "s3", "s4"); + + // Normal secondary user. + + when(mMockUserManager.isUserRunning(anyInt())).thenReturn(false); + when(mMockUserManager.isUserRunning(eq(USER_10))).thenReturn(true); + + resetAll(all); + runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { + mManager.deleteDynamicShortcut("x"); + }); + waitOnMainThread(); + + assertCallbackNotReceived(c0_1); + assertCallbackNotReceived(c0_2); + assertCallbackNotReceived(c0_3); + assertCallbackNotReceived(c0_4); + assertCallbackNotReceived(cP0_1); + assertCallbackNotReceived(c10_2); + assertCallbackNotReceived(c11_1); + assertCallbackReceived(c10_1, HANDLE_USER_10, CALLING_PACKAGE_1, + "x1", "x2", "x3", "x4", "x5"); + } + // === Test for persisting === public void testSaveAndLoadUser_empty() { @@ -3979,6 +4207,10 @@ public class ShortcutManagerTest extends InstrumentationTestCase { } } + shutdownServices(); + + deleteAllSavedFiles(); + initService(); mService.applyRestore(payload, USER_0); @@ -4064,6 +4296,31 @@ public class ShortcutManagerTest extends InstrumentationTestCase { mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("x4", "x5", "x6", "x1"), HANDLE_USER_10); }); + + // Then remove some dynamic shortcuts. + runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(list( + makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3")))); + }); + runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(list( + makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3")))); + }); + runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(list( + makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3")))); + }); + runWithCaller(CALLING_PACKAGE_4, USER_0, () -> { + assertTrue(mManager.setDynamicShortcuts(list())); + }); + runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { + assertTrue(mManager.setDynamicShortcuts(list( + makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3")))); + }); + runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { + assertTrue(mManager.setDynamicShortcuts(list( + makeShortcut("x1"), makeShortcut("x2"), makeShortcut("x3")))); + }); } private void prepareForBackupTest() { @@ -4145,6 +4402,7 @@ public class ShortcutManagerTest extends InstrumentationTestCase { // Note doing a backup & restore again here shouldn't affect the result. backupAndRestore(); + // Change package signatures. addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 1, "sigx", CALLING_PACKAGE_1); addPackage(LAUNCHER_1, LAUNCHER_UID_1, 4, LAUNCHER_1, "sigy"); @@ -4618,19 +4876,19 @@ public class ShortcutManagerTest extends InstrumentationTestCase { runWithCaller(CALLING_PACKAGE_1, USER_0, () -> { assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), - "s1", "s2", "s3", "s4", "s5", "s6"); + "s1", "s2", "s3"); assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2", "s3", "s4"); }); runWithCaller(CALLING_PACKAGE_2, USER_0, () -> { assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), - "s1", "s2", "s3", "s4", "s5", "s6"); + "s1", "s2", "s3"); assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2", "s3", "s4", "s5"); }); runWithCaller(CALLING_PACKAGE_3, USER_0, () -> { assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), - "s1", "s2", "s3", "s4", "s5", "s6"); + "s1", "s2", "s3"); assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2", "s3", "s4", "s5", "s6"); }); @@ -4642,7 +4900,7 @@ public class ShortcutManagerTest extends InstrumentationTestCase { }); runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> { assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), - "s1", "s2", "s3", "s4", "s5", "s6"); + "s1", "s2", "s3"); assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "s1", "s2", "s3", "s4", "s5", "s6"); }); @@ -4654,7 +4912,7 @@ public class ShortcutManagerTest extends InstrumentationTestCase { }); runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { assertShortcutIds(assertAllDynamic(mManager.getDynamicShortcuts()), - "x1", "x2", "x3", "x4", "x5", "x6"); + "x1", "x2", "x3"); assertShortcutIds(assertAllPinned(mManager.getPinnedShortcuts()), "x4", "x5"); }); @@ -4757,7 +5015,7 @@ public class ShortcutManagerTest extends InstrumentationTestCase { mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_1), HANDLE_USER_P0), "s1", "s4"); TestUtils.assertExpectException( - SecurityException.class, "you need to be SYSTEM", () -> { + SecurityException.class, "unrelated profile", () -> { mLauncherApps.getShortcuts( buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_10); }); @@ -4773,12 +5031,12 @@ public class ShortcutManagerTest extends InstrumentationTestCase { mLauncherApps.getShortcuts(buildPinnedQuery(CALLING_PACKAGE_3), HANDLE_USER_10) /* empty */); TestUtils.assertExpectException( - SecurityException.class, "you need to be SYSTEM", () -> { + SecurityException.class, "unrelated profile", () -> { mLauncherApps.getShortcuts( buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0); }); TestUtils.assertExpectException( - SecurityException.class, "you need to be SYSTEM", () -> { + SecurityException.class, "unrelated profile", () -> { mLauncherApps.getShortcuts( buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_P0); }); diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index beec40f8b0fa..0aeb96f52181 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -144,6 +144,7 @@ public class UsageStatsService extends SystemService implements private long mLastAppIdleParoledTime; private volatile boolean mPendingOneTimeCheckIdleStates; + private boolean mSystemServicesReady = false; @GuardedBy("mLock") private AppIdleHistory mAppIdleHistory; @@ -232,6 +233,8 @@ public class UsageStatsService extends SystemService implements if (mPendingOneTimeCheckIdleStates) { postOneTimeCheckIdleStates(); } + + mSystemServicesReady = true; } else if (phase == PHASE_BOOT_COMPLETED) { setAppIdleParoled(getContext().getSystemService(BatteryManager.class).isCharging()); } @@ -810,28 +813,30 @@ public class UsageStatsService extends SystemService implements // retain this for safety). return false; } - try { - // We allow all whitelisted apps, including those that don't want to be whitelisted - // for idle mode, because app idle (aka app standby) is really not as big an issue - // for controlling who participates vs. doze mode. - if (mDeviceIdleController.isPowerSaveWhitelistExceptIdleApp(packageName)) { - return false; + if (mSystemServicesReady) { + try { + // We allow all whitelisted apps, including those that don't want to be whitelisted + // for idle mode, because app idle (aka app standby) is really not as big an issue + // for controlling who participates vs. doze mode. + if (mDeviceIdleController.isPowerSaveWhitelistExceptIdleApp(packageName)) { + return false; + } + } catch (RemoteException re) { + throw re.rethrowFromSystemServer(); } - } catch (RemoteException re) { - throw re.rethrowFromSystemServer(); - } - if (isActiveDeviceAdmin(packageName, userId)) { - return false; - } + if (isActiveDeviceAdmin(packageName, userId)) { + return false; + } - if (isActiveNetworkScorer(packageName)) { - return false; - } + if (isActiveNetworkScorer(packageName)) { + return false; + } - if (mAppWidgetManager != null - && mAppWidgetManager.isBoundWidgetPackage(packageName, userId)) { - return false; + if (mAppWidgetManager != null + && mAppWidgetManager.isBoundWidgetPackage(packageName, userId)) { + return false; + } } if (!isAppIdleUnfiltered(packageName, userId, elapsedRealtime)) { diff --git a/services/usb/java/com/android/server/usb/UsbMidiDevice.java b/services/usb/java/com/android/server/usb/UsbMidiDevice.java index 38ede87d2b85..46ce7a0a1aaf 100644 --- a/services/usb/java/com/android/server/usb/UsbMidiDevice.java +++ b/services/usb/java/com/android/server/usb/UsbMidiDevice.java @@ -127,6 +127,14 @@ public final class UsbMidiDevice implements Closeable { public void setReceiver(MidiReceiver receiver) { mReceiver = receiver; } + + @Override + public void onFlush() throws IOException { + MidiReceiver receiver = mReceiver; + if (receiver != null) { + receiver.flush(); + } + } } public static UsbMidiDevice create(Context context, Bundle properties, int card, int device) { diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 4fa8fe96a6a9..6eafb90fbfdb 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -1433,25 +1433,6 @@ public class TelecomManager { } /** - * Launches the {@link android.app.Activity} to manage blocked numbers. - * <p> This method displays the UI to manage blocked numbers only if - * {@link android.provider.BlockedNumberContract#canCurrentUserBlockNumbers(Context)} returns - * {@code true} for the current user. - * @deprecated Use {@link #createManageBlockedNumbersIntent()} instead. - */ - // TODO: Delete this. - public void launchManageBlockedNumbersActivity() { - ITelecomService service = getTelecomService(); - if (service != null) { - try { - service.launchManageBlockedNumbersActivity(mContext.getPackageName()); - } catch (RemoteException e) { - Log.e(TAG, "Error calling ITelecomService#manageBlockedNumbers", e); - } - } - } - - /** * Creates the {@link Intent} which can be used with {@link Context#startActivity(Intent)} to * launch the activity to manage blocked numbers. * <p> The activity will display the UI to manage blocked numbers only if diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl index 3c250f1b54fd..871565de33c9 100644 --- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl +++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl @@ -246,12 +246,6 @@ interface ITelecomService { boolean setDefaultDialer(in String packageName); /** - * @see TelecomServiceImpl#launchManageBlockedNumbersActivity - **/ - // TODO: Delete this. - void launchManageBlockedNumbersActivity(in String callingPackageName); - - /** * @see TelecomServiceImpl#createManageBlockedNumbersIntent **/ Intent createManageBlockedNumbersIntent(); diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index b482811a18f2..865af7821ac2 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -3550,7 +3550,7 @@ public class TelephonyManager { * @return the response of ISIM Authetification, or null if not available * @hide * @deprecated - * @see getIccSimChallengeResponse with appType=PhoneConstants.APPTYPE_ISIM + * @see getIccAuthentication with appType=PhoneConstants.APPTYPE_ISIM */ public String getIsimChallengeResponse(String nonce){ try { @@ -3566,21 +3566,60 @@ public class TelephonyManager { } } + // ICC SIM Application Types + public static final int APPTYPE_SIM = PhoneConstants.APPTYPE_SIM; + public static final int APPTYPE_USIM = PhoneConstants.APPTYPE_USIM; + public static final int APPTYPE_RUIM = PhoneConstants.APPTYPE_RUIM; + public static final int APPTYPE_CSIM = PhoneConstants.APPTYPE_CSIM; + public static final int APPTYPE_ISIM = PhoneConstants.APPTYPE_ISIM; + // authContext (parameter P2) when doing SIM challenge, + // per 3GPP TS 31.102 (Section 7.1.2) + public static final int AUTHTYPE_EAP_SIM = PhoneConstants.AUTH_CONTEXT_EAP_SIM; + public static final int AUTHTYPE_EAP_AKA = PhoneConstants.AUTH_CONTEXT_EAP_AKA; + /** - * Returns the response of SIM Authentication through RIL. - * Returns null if the Authentication hasn't been successful - * @param subId subscription ID to be queried - * @param appType ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx) - * @param data authentication challenge data - * @return the response of SIM Authentication, or null if not available - * @hide + * Returns the response of authentication for the default subscription. + * Returns null if the authentication hasn't been successful + * + * <p>Requires that the calling app has carrier privileges or READ_PRIVILEGED_PHONE_STATE + * permission. + * + * @param appType the icc application type, like {@link #APPTYPE_USIM} + * @param authType the authentication type, {@link #AUTHTYPE_EAP_AKA} or + * {@link #AUTHTYPE_EAP_SIM} + * @param data authentication challenge data, base64 encoded. + * See 3GPP TS 31.102 7.1.2 for more details. + * @return the response of authentication, or null if not available + * + * @see #hasCarrierPrivileges */ - public String getIccSimChallengeResponse(int subId, int appType, String data) { + public String getIccAuthentication(int appType, int authType, String data) { + return getIccAuthentication(getDefaultSubscription(), appType, authType, data); + } + + /** + * Returns the response of USIM Authentication for specified subId. + * Returns null if the authentication hasn't been successful + * + * <p>Requires that the calling app has carrier privileges. + * + * @param subId subscription ID used for authentication + * @param appType the icc application type, like {@link #APPTYPE_USIM} + * @param authType the authentication type, {@link #AUTHTYPE_EAP_AKA} or + * {@link #AUTHTYPE_EAP_SIM} + * @param data authentication challenge data, base64 encoded. + * See 3GPP TS 31.102 7.1.2 for more details. + * @return the response of authentication, or null if not available + * + * @see #hasCarrierPrivileges + */ + + public String getIccAuthentication(int subId, int appType, int authType, String data) { try { IPhoneSubInfo info = getSubscriberInfo(); if (info == null) return null; - return info.getIccSimChallengeResponse(subId, appType, data); + return info.getIccSimChallengeResponse(subId, appType, authType, data); } catch (RemoteException ex) { return null; } catch (NullPointerException ex) { @@ -3599,9 +3638,10 @@ public class TelephonyManager { * @param appType ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx) * @param data authentication challenge data * @return the response of SIM Authentication, or null if not available + * @hide */ public String getIccSimChallengeResponse(int appType, String data) { - return getIccSimChallengeResponse(getDefaultSubscription(), appType, data); + return getIccAuthentication(getDefaultSubscription(), appType, AUTHTYPE_EAP_SIM, data); } /** diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl index dc2b297f6dbe..02baa3454536 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl @@ -196,8 +196,9 @@ interface IPhoneSubInfo { * * @param subId subscription ID to be queried * @param appType ICC application type (@see com.android.internal.telephony.PhoneConstants#APPTYPE_xxx) + * @param authType Authentication type, see PhoneConstants#AUTHTYPE_xxx * @param data authentication challenge data * @return challenge response */ - String getIccSimChallengeResponse(int subId, int appType, String data); + String getIccSimChallengeResponse(int subId, int appType, int authType, String data); } diff --git a/telephony/java/com/android/internal/telephony/PhoneConstants.java b/telephony/java/com/android/internal/telephony/PhoneConstants.java index ecd89eda4577..1680fe33ead7 100644 --- a/telephony/java/com/android/internal/telephony/PhoneConstants.java +++ b/telephony/java/com/android/internal/telephony/PhoneConstants.java @@ -202,4 +202,10 @@ public class PhoneConstants { public static final int AUDIO_OUTPUT_ENABLE_SPEAKER = 0; public static final int AUDIO_OUTPUT_DISABLE_SPEAKER = 1; public static final int AUDIO_OUTPUT_DEFAULT = AUDIO_OUTPUT_ENABLE_SPEAKER; + + // authContext (parameter P2) when doing SIM challenge, + // per 3GPP TS 31.102 (Section 7.1.2) + public static final int AUTH_CONTEXT_EAP_SIM = 128; + public static final int AUTH_CONTEXT_EAP_AKA = 129; + public static final int AUTH_CONTEXT_UNDEFINED = -1; } diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp index 641c34bd2dda..d631f3531127 100644 --- a/tools/aapt/Package.cpp +++ b/tools/aapt/Package.cpp @@ -33,7 +33,7 @@ static const char* kNoCompressExt[] = { ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet", ".rtttl", ".imy", ".xmf", ".mp4", ".m4a", ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2", - ".amr", ".awb", ".wma", ".wmv", ".webm" + ".amr", ".awb", ".wma", ".wmv", ".webm", ".mkv" }; /* fwd decls, so I can write this downward */ diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk index 876a422a2678..ef11d662b2ce 100644 --- a/tools/aapt2/Android.mk +++ b/tools/aapt2/Android.mk @@ -66,6 +66,7 @@ sources := \ ResourceValues.cpp \ SdkConstants.cpp \ StringPool.cpp \ + xml/XmlActionExecutor.cpp \ xml/XmlDom.cpp \ xml/XmlPullParser.cpp \ xml/XmlUtil.cpp @@ -107,6 +108,7 @@ testSources := \ SdkConstants_test.cpp \ StringPool_test.cpp \ ValueVisitor_test.cpp \ + xml/XmlActionExecutor_test.cpp \ xml/XmlDom_test.cpp \ xml/XmlPullParser_test.cpp \ xml/XmlUtil_test.cpp @@ -140,7 +142,7 @@ else endif cFlags := -Wall -Werror -Wno-unused-parameter -UNDEBUG -cppFlags := -std=c++11 -Wno-missing-field-initializers -fno-exceptions -fno-rtti +cppFlags := -std=c++14 -Wno-missing-field-initializers -fno-exceptions -fno-rtti protoIncludes := $(call generated-sources-dir-for,STATIC_LIBRARIES,libaapt2,HOST) # ========================================================== diff --git a/tools/aapt2/Diagnostics.h b/tools/aapt2/Diagnostics.h index ab4d284516e1..e86f2a8830e8 100644 --- a/tools/aapt2/Diagnostics.h +++ b/tools/aapt2/Diagnostics.h @@ -21,6 +21,7 @@ #include "util/StringPiece.h" #include "util/Util.h" +#include <android-base/macros.h> #include <iostream> #include <sstream> #include <string> @@ -46,7 +47,11 @@ public: DiagMessage(const Source& src) : mSource(src) { } - template <typename T> DiagMessage& operator<<(const T& value) { + DiagMessage(size_t line) : mSource(Source().withLine(line)) { + } + + template <typename T> + DiagMessage& operator<<(const T& value) { mMessage << value; return *this; } @@ -59,36 +64,82 @@ public: struct IDiagnostics { virtual ~IDiagnostics() = default; - virtual void error(const DiagMessage& message) = 0; - virtual void warn(const DiagMessage& message) = 0; - virtual void note(const DiagMessage& message) = 0; -}; + enum class Level { + Note, + Warn, + Error + }; -struct StdErrDiagnostics : public IDiagnostics { - size_t mNumErrors = 0; + virtual void log(Level level, DiagMessageActual& actualMsg) = 0; - void emit(const DiagMessage& msg, const char* tag) { - DiagMessageActual actual = msg.build(); - if (!actual.source.path.empty()) { - std::cerr << actual.source << ": "; - } - std::cerr << tag << actual.message << "." << std::endl; + virtual void error(const DiagMessage& message) { + DiagMessageActual actual = message.build(); + log(Level::Error, actual); + } + + virtual void warn(const DiagMessage& message) { + DiagMessageActual actual = message.build(); + log(Level::Warn, actual); + } + + virtual void note(const DiagMessage& message) { + DiagMessageActual actual = message.build(); + log(Level::Note, actual); } +}; - void error(const DiagMessage& msg) override { - if (mNumErrors < 20) { - emit(msg, "error: "); +class StdErrDiagnostics : public IDiagnostics { +public: + StdErrDiagnostics() = default; + + void log(Level level, DiagMessageActual& actualMsg) override { + const char* tag; + + switch (level) { + case Level::Error: + mNumErrors++; + if (mNumErrors > 20) { + return; + } + tag = "error"; + break; + + case Level::Warn: + tag = "warn"; + break; + + case Level::Note: + tag = "note"; + break; } - mNumErrors++; + + if (!actualMsg.source.path.empty()) { + std::cerr << actualMsg.source << ": "; + } + std::cerr << tag << ": " << actualMsg.message << "." << std::endl; } - void warn(const DiagMessage& msg) override { - emit(msg, "warn: "); +private: + size_t mNumErrors = 0; + + DISALLOW_COPY_AND_ASSIGN(StdErrDiagnostics); +}; + +class SourcePathDiagnostics : public IDiagnostics { +public: + SourcePathDiagnostics(const Source& src, IDiagnostics* diag) : mSource(src), mDiag(diag) { } - void note(const DiagMessage& msg) override { - emit(msg, "note: "); + void log(Level level, DiagMessageActual& actualMsg) override { + actualMsg.source.path = mSource.path; + mDiag->log(level, actualMsg); } + +private: + Source mSource; + IDiagnostics* mDiag; + + DISALLOW_COPY_AND_ASSIGN(SourcePathDiagnostics); }; } // namespace aapt diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp index 180bd11275df..d6c52ab83d93 100644 --- a/tools/aapt2/ResourceTable_test.cpp +++ b/tools/aapt2/ResourceTable_test.cpp @@ -28,33 +28,23 @@ namespace aapt { -struct ResourceTableTest : public ::testing::Test { - struct EmptyDiagnostics : public IDiagnostics { - void error(const DiagMessage& msg) override {} - void warn(const DiagMessage& msg) override {} - void note(const DiagMessage& msg) override {} - }; - - EmptyDiagnostics mDiagnostics; -}; - -TEST_F(ResourceTableTest, FailToAddResourceWithBadName) { +TEST(ResourceTableTest, FailToAddResourceWithBadName) { ResourceTable table; EXPECT_FALSE(table.addResource( ResourceNameRef(u"android", ResourceType::kId, u"hey,there"), ConfigDescription{}, "", test::ValueBuilder<Id>().setSource("test.xml", 21u).build(), - &mDiagnostics)); + test::getDiagnostics())); EXPECT_FALSE(table.addResource( ResourceNameRef(u"android", ResourceType::kId, u"hey:there"), ConfigDescription{}, "", test::ValueBuilder<Id>().setSource("test.xml", 21u).build(), - &mDiagnostics)); + test::getDiagnostics())); } -TEST_F(ResourceTableTest, AddOneResource) { +TEST(ResourceTableTest, AddOneResource) { ResourceTable table; EXPECT_TRUE(table.addResource(test::parseNameOrDie(u"@android:attr/id"), @@ -62,12 +52,12 @@ TEST_F(ResourceTableTest, AddOneResource) { "", test::ValueBuilder<Id>() .setSource("test/path/file.xml", 23u).build(), - &mDiagnostics)); + test::getDiagnostics())); ASSERT_NE(nullptr, test::getValue<Id>(&table, u"@android:attr/id")); } -TEST_F(ResourceTableTest, AddMultipleResources) { +TEST(ResourceTableTest, AddMultipleResources) { ResourceTable table; ConfigDescription config; @@ -79,21 +69,21 @@ TEST_F(ResourceTableTest, AddMultipleResources) { config, "", test::ValueBuilder<Id>().setSource("test/path/file.xml", 10u).build(), - &mDiagnostics)); + test::getDiagnostics())); EXPECT_TRUE(table.addResource( test::parseNameOrDie(u"@android:attr/id"), config, "", test::ValueBuilder<Id>().setSource("test/path/file.xml", 12u).build(), - &mDiagnostics)); + test::getDiagnostics())); EXPECT_TRUE(table.addResource( test::parseNameOrDie(u"@android:string/ok"), config, "", test::ValueBuilder<Id>().setSource("test/path/file.xml", 14u).build(), - &mDiagnostics)); + test::getDiagnostics())); EXPECT_TRUE(table.addResource( test::parseNameOrDie(u"@android:string/ok"), @@ -102,7 +92,7 @@ TEST_F(ResourceTableTest, AddMultipleResources) { test::ValueBuilder<BinaryPrimitive>(android::Res_value{}) .setSource("test/path/file.xml", 20u) .build(), - &mDiagnostics)); + test::getDiagnostics())); ASSERT_NE(nullptr, test::getValue<Id>(&table, u"@android:attr/layout_width")); ASSERT_NE(nullptr, test::getValue<Id>(&table, u"@android:attr/id")); @@ -111,37 +101,37 @@ TEST_F(ResourceTableTest, AddMultipleResources) { languageConfig)); } -TEST_F(ResourceTableTest, OverrideWeakResourceValue) { +TEST(ResourceTableTest, OverrideWeakResourceValue) { ResourceTable table; ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:attr/foo"), ConfigDescription{}, - "", util::make_unique<Attribute>(true), &mDiagnostics)); + "", util::make_unique<Attribute>(true), test::getDiagnostics())); Attribute* attr = test::getValue<Attribute>(&table, u"@android:attr/foo"); ASSERT_NE(nullptr, attr); EXPECT_TRUE(attr->isWeak()); ASSERT_TRUE(table.addResource(test::parseNameOrDie(u"@android:attr/foo"), ConfigDescription{}, - "", util::make_unique<Attribute>(false), &mDiagnostics)); + "", util::make_unique<Attribute>(false), test::getDiagnostics())); attr = test::getValue<Attribute>(&table, u"@android:attr/foo"); ASSERT_NE(nullptr, attr); EXPECT_FALSE(attr->isWeak()); } -TEST_F(ResourceTableTest, ProductVaryingValues) { +TEST(ResourceTableTest, ProductVaryingValues) { ResourceTable table; EXPECT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/foo"), test::parseConfigOrDie("land"), "tablet", util::make_unique<Id>(), - &mDiagnostics)); + test::getDiagnostics())); EXPECT_TRUE(table.addResource(test::parseNameOrDie(u"@android:string/foo"), test::parseConfigOrDie("land"), "phone", util::make_unique<Id>(), - &mDiagnostics)); + test::getDiagnostics())); EXPECT_NE(nullptr, test::getValueForConfigAndProduct<Id>(&table, u"@android:string/foo", test::parseConfigOrDie("land"), diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp index 2d076c2d5a66..092bab241bba 100644 --- a/tools/aapt2/java/JavaClassGenerator.cpp +++ b/tools/aapt2/java/JavaClassGenerator.cpp @@ -437,6 +437,15 @@ bool JavaClassGenerator::generate(const StringPiece16& packageNameToGenerate, st return generate(packageNameToGenerate, packageNameToGenerate, out); } +static void appendJavaDocAnnotations(const std::vector<std::string>& annotations, + AnnotationProcessor* processor) { + for (const std::string& annotation : annotations) { + std::string properAnnotation = "@"; + properAnnotation += annotation; + processor->appendComment(properAnnotation); + } +} + bool JavaClassGenerator::generate(const StringPiece16& packageNameToGenerate, const StringPiece16& outPackageName, std::ostream* out) { @@ -477,14 +486,17 @@ bool JavaClassGenerator::generate(const StringPiece16& packageNameToGenerate, mOptions.types == JavaClassGeneratorOptions::SymbolTypes::kPublic) { // When generating a public R class, we don't want Styleable to be part of the API. // It is only emitted for documentation purposes. - AnnotationProcessor* processor = classDef->getCommentBuilder(); - processor->appendComment("@doconly"); + classDef->getCommentBuilder()->appendComment("@doconly"); } + appendJavaDocAnnotations(mOptions.javadocAnnotations, classDef->getCommentBuilder()); + rClass.addMember(std::move(classDef)); } } + appendJavaDocAnnotations(mOptions.javadocAnnotations, rClass.getCommentBuilder()); + if (!ClassDefinition::writeJavaFile(&rClass, util::utf16ToUtf8(outPackageName), mOptions.useFinal, out)) { return false; @@ -494,6 +506,4 @@ bool JavaClassGenerator::generate(const StringPiece16& packageNameToGenerate, return true; } - - } // namespace aapt diff --git a/tools/aapt2/java/JavaClassGenerator.h b/tools/aapt2/java/JavaClassGenerator.h index b594a88728f4..77e0ed76143a 100644 --- a/tools/aapt2/java/JavaClassGenerator.h +++ b/tools/aapt2/java/JavaClassGenerator.h @@ -44,6 +44,11 @@ struct JavaClassGeneratorOptions { }; SymbolTypes types = SymbolTypes::kAll; + + /** + * A list of JavaDoc annotations to add to the comments of all generated classes. + */ + std::vector<std::string> javadocAnnotations; }; /* diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp index 8c10fbb6e38a..8c8bffafdc45 100644 --- a/tools/aapt2/link/Link.cpp +++ b/tools/aapt2/link/Link.cpp @@ -66,6 +66,7 @@ struct LinkOptions { bool staticLib = false; bool noStaticLibPackages = false; bool generateNonFinalIds = false; + std::vector<std::string> javadocAnnotations; bool outputToDirectory = false; bool autoAddOverlay = false; bool doNotCompressAnything = false; @@ -775,6 +776,13 @@ public: return true; } + // Add any JavaDoc annotations to the generated class. + for (const std::string& annotation : mOptions.javadocAnnotations) { + std::string properAnnotation = "@"; + properAnnotation += annotation; + manifestClass->getCommentBuilder()->appendComment(properAnnotation); + } + const std::string packageUtf8 = util::utf16ToUtf8(mContext->getCompilationPackage()); std::string outPath = mOptions.generateJavaClassPath.value(); @@ -1292,6 +1300,7 @@ public: if (mOptions.generateJavaClassPath) { JavaClassGeneratorOptions options; options.types = JavaClassGeneratorOptions::SymbolTypes::kAll; + options.javadocAnnotations = mOptions.javadocAnnotations; if (mOptions.staticLib || mOptions.generateNonFinalIds) { options.useFinal = false; @@ -1432,6 +1441,8 @@ int link(const std::vector<StringPiece>& args) { &customJavaPackage) .optionalFlagList("--extra-packages", "Generate the same R.java but with different " "package names", &extraJavaPackages) + .optionalFlagList("--add-javadoc-annotation", "Adds a JavaDoc annotation to all " + "generated Java classes", &options.javadocAnnotations) .optionalSwitch("--auto-add-overlay", "Allows the addition of new resources in " "overlays without <add-resource> tags", &options.autoAddOverlay) .optionalFlag("--rename-manifest-package", "Renames the package in AndroidManifest.xml", diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp index 9baf1d86795c..3779638590be 100644 --- a/tools/aapt2/link/ManifestFixer.cpp +++ b/tools/aapt2/link/ManifestFixer.cpp @@ -17,66 +17,199 @@ #include "ResourceUtils.h" #include "link/ManifestFixer.h" #include "util/Util.h" +#include "xml/XmlActionExecutor.h" #include "xml/XmlDom.h" namespace aapt { -static bool verifyManifest(IAaptContext* context, const Source& source, xml::Element* manifestEl) { - xml::Attribute* attr = manifestEl->findAttribute({}, u"package"); - if (!attr) { - context->getDiagnostics()->error(DiagMessage(source.withLine(manifestEl->lineNumber)) - << "missing 'package' attribute"); - } else if (ResourceUtils::isReference(attr->value)) { - context->getDiagnostics()->error(DiagMessage(source.withLine(manifestEl->lineNumber)) - << "value for attribute 'package' must not be a " - "reference"); - } else if (!util::isJavaPackageName(attr->value)) { - context->getDiagnostics()->error(DiagMessage(source.withLine(manifestEl->lineNumber)) - << "invalid package name '" << attr->value << "'"); - } else { - return true; +/** + * This is how PackageManager builds class names from AndroidManifest.xml entries. + */ +static bool nameIsJavaClassName(xml::Element* el, xml::Attribute* attr, + SourcePathDiagnostics* diag) { + std::u16string className = attr->value; + if (className.find(u'.') == std::u16string::npos) { + // There is no '.', so add one to the beginning. + className = u"."; + className += attr->value; } - return false; -} -static bool includeVersionName(IAaptContext* context, const Source& source, - const StringPiece16& versionName, xml::Element* manifestEl) { - if (manifestEl->findAttribute(xml::kSchemaAndroid, u"versionName")) { - return true; + // We allow unqualified class names (ie: .HelloActivity) + // Since we don't know the package name, we can just make a fake one here and + // the test will be identical as long as the real package name is valid too. + Maybe<std::u16string> fullyQualifiedClassName = + util::getFullyQualifiedClassName(u"a", className); + + StringPiece16 qualifiedClassName = fullyQualifiedClassName + ? fullyQualifiedClassName.value() : className; + if (!util::isJavaClassName(qualifiedClassName)) { + diag->error(DiagMessage(el->lineNumber) + << "attribute 'android:name' in <" + << el->name << "> tag must be a valid Java class name"); + return false; } + return true; +} - manifestEl->attributes.push_back(xml::Attribute{ - xml::kSchemaAndroid, u"versionName", versionName.toString() }); +static bool optionalNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) { + if (xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, u"name")) { + return nameIsJavaClassName(el, attr, diag); + } return true; } -static bool includeVersionCode(IAaptContext* context, const Source& source, - const StringPiece16& versionCode, xml::Element* manifestEl) { - if (manifestEl->findAttribute(xml::kSchemaAndroid, u"versionCode")) { - return true; +static bool requiredNameIsJavaClassName(xml::Element* el, SourcePathDiagnostics* diag) { + if (xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, u"name")) { + return nameIsJavaClassName(el, attr, diag); } + diag->error(DiagMessage(el->lineNumber) + << "<" << el->name << "> is missing attribute 'android:name'"); + return false; +} - manifestEl->attributes.push_back(xml::Attribute{ - xml::kSchemaAndroid, u"versionCode", versionCode.toString() }); +static bool verifyManifest(xml::Element* el, SourcePathDiagnostics* diag) { + xml::Attribute* attr = el->findAttribute({}, u"package"); + if (!attr) { + diag->error(DiagMessage(el->lineNumber) << "<manifest> tag is missing 'package' attribute"); + return false; + } else if (ResourceUtils::isReference(attr->value)) { + diag->error(DiagMessage(el->lineNumber) + << "attribute 'package' in <manifest> tag must not be a reference"); + return false; + } else if (!util::isJavaPackageName(attr->value)) { + diag->error(DiagMessage(el->lineNumber) + << "attribute 'package' in <manifest> tag is not a valid Java package name: '" + << attr->value << "'"); + return false; + } return true; } -static bool fixUsesSdk(IAaptContext* context, const Source& source, xml::Element* el, - const ManifestFixerOptions& options) { - if (options.minSdkVersionDefault && - el->findAttribute(xml::kSchemaAndroid, u"minSdkVersion") == nullptr) { - // There was no minSdkVersion defined and we have a default to assign. - el->attributes.push_back(xml::Attribute{ - xml::kSchemaAndroid, u"minSdkVersion", options.minSdkVersionDefault.value() }); +bool ManifestFixer::buildRules(xml::XmlActionExecutor* executor, IDiagnostics* diag) { + // First verify some options. + if (mOptions.renameManifestPackage) { + if (!util::isJavaPackageName(mOptions.renameManifestPackage.value())) { + diag->error(DiagMessage() << "invalid manifest package override '" + << mOptions.renameManifestPackage.value() << "'"); + return false; + } } - if (options.targetSdkVersionDefault && - el->findAttribute(xml::kSchemaAndroid, u"targetSdkVersion") == nullptr) { - // There was no targetSdkVersion defined and we have a default to assign. - el->attributes.push_back(xml::Attribute{ - xml::kSchemaAndroid, u"targetSdkVersion", - options.targetSdkVersionDefault.value() }); + if (mOptions.renameInstrumentationTargetPackage) { + if (!util::isJavaPackageName(mOptions.renameInstrumentationTargetPackage.value())) { + diag->error(DiagMessage() << "invalid instrumentation target package override '" + << mOptions.renameInstrumentationTargetPackage.value() << "'"); + return false; + } } + + // Common intent-filter actions. + xml::XmlNodeAction intentFilterAction; + intentFilterAction[u"action"]; + intentFilterAction[u"category"]; + intentFilterAction[u"data"]; + + // Common meta-data actions. + xml::XmlNodeAction metaDataAction; + + // Manifest actions. + xml::XmlNodeAction& manifestAction = (*executor)[u"manifest"]; + manifestAction.action(verifyManifest); + manifestAction.action([&](xml::Element* el) -> bool { + if (mOptions.versionNameDefault) { + if (el->findAttribute(xml::kSchemaAndroid, u"versionName") == nullptr) { + el->attributes.push_back(xml::Attribute{ + xml::kSchemaAndroid, + u"versionName", + mOptions.versionNameDefault.value() }); + } + } + + if (mOptions.versionCodeDefault) { + if (el->findAttribute(xml::kSchemaAndroid, u"versionCode") == nullptr) { + el->attributes.push_back(xml::Attribute{ + xml::kSchemaAndroid, + u"versionCode", + mOptions.versionCodeDefault.value() }); + } + } + return true; + }); + + // Uses-sdk actions. + manifestAction[u"uses-sdk"].action([&](xml::Element* el) -> bool { + if (mOptions.minSdkVersionDefault && + el->findAttribute(xml::kSchemaAndroid, u"minSdkVersion") == nullptr) { + // There was no minSdkVersion defined and we have a default to assign. + el->attributes.push_back(xml::Attribute{ + xml::kSchemaAndroid, u"minSdkVersion", + mOptions.minSdkVersionDefault.value() }); + } + + if (mOptions.targetSdkVersionDefault && + el->findAttribute(xml::kSchemaAndroid, u"targetSdkVersion") == nullptr) { + // There was no targetSdkVersion defined and we have a default to assign. + el->attributes.push_back(xml::Attribute{ + xml::kSchemaAndroid, u"targetSdkVersion", + mOptions.targetSdkVersionDefault.value() }); + } + return true; + }); + + // Instrumentation actions. + manifestAction[u"instrumentation"].action([&](xml::Element* el) -> bool { + if (!mOptions.renameInstrumentationTargetPackage) { + return true; + } + + if (xml::Attribute* attr = el->findAttribute(xml::kSchemaAndroid, u"targetPackage")) { + attr->value = mOptions.renameInstrumentationTargetPackage.value(); + } + return true; + }); + + manifestAction[u"eat-comment"]; + manifestAction[u"protected-broadcast"]; + manifestAction[u"uses-permission"]; + manifestAction[u"permission"]; + manifestAction[u"permission-tree"]; + manifestAction[u"permission-group"]; + + manifestAction[u"uses-configuration"]; + manifestAction[u"uses-feature"]; + manifestAction[u"uses-library"]; + manifestAction[u"supports-screens"]; + manifestAction[u"compatible-screens"]; + manifestAction[u"supports-gl-texture"]; + + // Application actions. + xml::XmlNodeAction& applicationAction = (*executor)[u"manifest"][u"application"]; + applicationAction.action(optionalNameIsJavaClassName); + + // Activity actions. + applicationAction[u"activity"].action(requiredNameIsJavaClassName); + applicationAction[u"activity"][u"intent-filter"] = intentFilterAction; + applicationAction[u"activity"][u"meta-data"] = metaDataAction; + + // Activity alias actions. + applicationAction[u"activity-alias"][u"intent-filter"] = intentFilterAction; + applicationAction[u"activity-alias"][u"meta-data"] = metaDataAction; + + // Service actions. + applicationAction[u"service"].action(requiredNameIsJavaClassName); + applicationAction[u"service"][u"intent-filter"] = intentFilterAction; + applicationAction[u"service"][u"meta-data"] = metaDataAction; + + // Receiver actions. + applicationAction[u"receiver"].action(requiredNameIsJavaClassName); + applicationAction[u"receiver"][u"intent-filter"] = intentFilterAction; + applicationAction[u"receiver"][u"meta-data"] = metaDataAction; + + // Provider actions. + applicationAction[u"provider"].action(requiredNameIsJavaClassName); + applicationAction[u"provider"][u"grant-uri-permissions"]; + applicationAction[u"provider"][u"meta-data"] = metaDataAction; + applicationAction[u"provider"][u"path-permissions"]; return true; } @@ -103,14 +236,7 @@ private: StringPiece16 mPackage; }; -static bool renameManifestPackage(IAaptContext* context, const Source& source, - const StringPiece16& packageOverride, xml::Element* manifestEl) { - if (!util::isJavaPackageName(packageOverride)) { - context->getDiagnostics()->error(DiagMessage() << "invalid manifest package override '" - << packageOverride << "'"); - return false; - } - +static bool renameManifestPackage(const StringPiece16& packageOverride, xml::Element* manifestEl) { xml::Attribute* attr = manifestEl->findAttribute({}, u"package"); // We've already verified that the manifest element is present, with a package name specified. @@ -124,32 +250,6 @@ static bool renameManifestPackage(IAaptContext* context, const Source& source, return true; } -static bool renameInstrumentationTargetPackage(IAaptContext* context, const Source& source, - const StringPiece16& packageOverride, - xml::Element* manifestEl) { - if (!util::isJavaPackageName(packageOverride)) { - context->getDiagnostics()->error(DiagMessage() - << "invalid instrumentation target package override '" - << packageOverride << "'"); - return false; - } - - xml::Element* instrumentationEl = manifestEl->findChild({}, u"instrumentation"); - if (!instrumentationEl) { - // No error if there is no work to be done. - return true; - } - - xml::Attribute* attr = instrumentationEl->findAttribute(xml::kSchemaAndroid, u"targetPackage"); - if (!attr) { - // No error if there is no work to be done. - return true; - } - - attr->value = packageOverride.toString(); - return true; -} - bool ManifestFixer::consume(IAaptContext* context, xml::XmlResource* doc) { xml::Element* root = xml::findRootElement(doc->root.get()); if (!root || !root->namespaceUri.empty() || root->name != u"manifest") { @@ -158,59 +258,31 @@ bool ManifestFixer::consume(IAaptContext* context, xml::XmlResource* doc) { return false; } - if (!verifyManifest(context, doc->file.source, root)) { - return false; + if ((mOptions.minSdkVersionDefault || mOptions.targetSdkVersionDefault) + && root->findChild({}, u"uses-sdk") == nullptr) { + // Auto insert a <uses-sdk> element. + std::unique_ptr<xml::Element> usesSdk = util::make_unique<xml::Element>(); + usesSdk->name = u"uses-sdk"; + root->addChild(std::move(usesSdk)); } - if (mOptions.versionCodeDefault) { - if (!includeVersionCode(context, doc->file.source, mOptions.versionCodeDefault.value(), - root)) { - return false; - } + xml::XmlActionExecutor executor; + if (!buildRules(&executor, context->getDiagnostics())) { + return false; } - if (mOptions.versionNameDefault) { - if (!includeVersionName(context, doc->file.source, mOptions.versionNameDefault.value(), - root)) { - return false; - } + if (!executor.execute(xml::XmlActionExecutorPolicy::Whitelist, context->getDiagnostics(), + doc)) { + return false; } if (mOptions.renameManifestPackage) { - // Rename manifest package. - if (!renameManifestPackage(context, doc->file.source, - mOptions.renameManifestPackage.value(), root)) { - return false; - } - } - - if (mOptions.renameInstrumentationTargetPackage) { - if (!renameInstrumentationTargetPackage(context, doc->file.source, - mOptions.renameInstrumentationTargetPackage.value(), - root)) { + // Rename manifest package outside of the XmlActionExecutor. + // We need to extract the old package name and FullyQualify all class names. + if (!renameManifestPackage(mOptions.renameManifestPackage.value(), root)) { return false; } } - - bool foundUsesSdk = false; - for (xml::Element* el : root->getChildElements()) { - if (!el->namespaceUri.empty()) { - continue; - } - - if (el->name == u"uses-sdk") { - foundUsesSdk = true; - fixUsesSdk(context, doc->file.source, el, mOptions); - } - } - - if (!foundUsesSdk && (mOptions.minSdkVersionDefault || mOptions.targetSdkVersionDefault)) { - std::unique_ptr<xml::Element> usesSdk = util::make_unique<xml::Element>(); - usesSdk->name = u"uses-sdk"; - fixUsesSdk(context, doc->file.source, usesSdk.get(), mOptions); - root->addChild(std::move(usesSdk)); - } - return true; } diff --git a/tools/aapt2/link/ManifestFixer.h b/tools/aapt2/link/ManifestFixer.h index b8d9c833ff05..4d9356a933c2 100644 --- a/tools/aapt2/link/ManifestFixer.h +++ b/tools/aapt2/link/ManifestFixer.h @@ -19,6 +19,7 @@ #include "process/IResourceTableConsumer.h" #include "util/Maybe.h" +#include "xml/XmlActionExecutor.h" #include "xml/XmlDom.h" #include <string> @@ -38,13 +39,17 @@ struct ManifestFixerOptions { * Verifies that the manifest is correctly formed and inserts defaults * where specified with ManifestFixerOptions. */ -struct ManifestFixer : public IXmlResourceConsumer { - ManifestFixerOptions mOptions; - +class ManifestFixer : public IXmlResourceConsumer { +public: ManifestFixer(const ManifestFixerOptions& options) : mOptions(options) { } bool consume(IAaptContext* context, xml::XmlResource* doc) override; + +private: + bool buildRules(xml::XmlActionExecutor* executor, IDiagnostics* diag); + + ManifestFixerOptions mOptions; }; } // namespace aapt diff --git a/tools/aapt2/link/ManifestFixer_test.cpp b/tools/aapt2/link/ManifestFixer_test.cpp index 18c47dff33ec..f993720b9566 100644 --- a/tools/aapt2/link/ManifestFixer_test.cpp +++ b/tools/aapt2/link/ManifestFixer_test.cpp @@ -166,9 +166,9 @@ TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) { std::unique_ptr<xml::XmlResource> doc = verifyWithOptions(R"EOF( <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="android"> - <application name=".MainApplication" text="hello"> - <activity name=".activity.Start" /> - <receiver name="com.google.android.Receiver" /> + <application android:name=".MainApplication" text="hello"> + <activity android:name=".activity.Start" /> + <receiver android:name="com.google.android.Receiver" /> </application> </manifest>)EOF", options); ASSERT_NE(nullptr, doc); @@ -185,7 +185,7 @@ TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) { xml::Element* applicationEl = manifestEl->findChild({}, u"application"); ASSERT_NE(nullptr, applicationEl); - attr = applicationEl->findAttribute({}, u"name"); + attr = applicationEl->findAttribute(xml::kSchemaAndroid, u"name"); ASSERT_NE(nullptr, attr); EXPECT_EQ(std::u16string(u"android.MainApplication"), attr->value); @@ -197,14 +197,14 @@ TEST_F(ManifestFixerTest, RenameManifestPackageAndFullyQualifyClasses) { el = applicationEl->findChild({}, u"activity"); ASSERT_NE(nullptr, el); - attr = el->findAttribute({}, u"name"); + attr = el->findAttribute(xml::kSchemaAndroid, u"name"); ASSERT_NE(nullptr, el); EXPECT_EQ(std::u16string(u"android.activity.Start"), attr->value); el = applicationEl->findChild({}, u"receiver"); ASSERT_NE(nullptr, el); - attr = el->findAttribute({}, u"name"); + attr = el->findAttribute(xml::kSchemaAndroid, u"name"); ASSERT_NE(nullptr, el); EXPECT_EQ(std::u16string(u"com.google.android.Receiver"), attr->value); } diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h index 8c56ebc67b32..8eb4bc88168d 100644 --- a/tools/aapt2/test/Builders.h +++ b/tools/aapt2/test/Builders.h @@ -238,7 +238,7 @@ inline std::unique_ptr<xml::XmlResource> buildXmlDom(const StringPiece& str) { std::stringstream in; in << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" << str; StdErrDiagnostics diag; - std::unique_ptr<xml::XmlResource> doc = xml::inflate(&in, &diag, {}); + std::unique_ptr<xml::XmlResource> doc = xml::inflate(&in, &diag, Source("test.xml")); assert(doc); return doc; } diff --git a/tools/aapt2/test/Common.h b/tools/aapt2/test/Common.h index 348c32a04e88..faccd47783ff 100644 --- a/tools/aapt2/test/Common.h +++ b/tools/aapt2/test/Common.h @@ -41,15 +41,20 @@ namespace aapt { namespace test { struct DummyDiagnosticsImpl : public IDiagnostics { - void error(const DiagMessage& message) override { - DiagMessageActual actual = message.build(); - std::cerr << actual.source << ": error: " << actual.message << "." << std::endl; - } - void warn(const DiagMessage& message) override { - DiagMessageActual actual = message.build(); - std::cerr << actual.source << ": warn: " << actual.message << "." << std::endl; + void log(Level level, DiagMessageActual& actualMsg) override { + switch (level) { + case Level::Note: + return; + + case Level::Warn: + std::cerr << actualMsg.source << ": warn: " << actualMsg.message << "." << std::endl; + break; + + case Level::Error: + std::cerr << actualMsg.source << ": error: " << actualMsg.message << "." << std::endl; + break; + } } - void note(const DiagMessage& message) override {} }; inline IDiagnostics* getDiagnostics() { diff --git a/tools/aapt2/xml/XmlActionExecutor.cpp b/tools/aapt2/xml/XmlActionExecutor.cpp new file mode 100644 index 000000000000..0ef67eaf3dc5 --- /dev/null +++ b/tools/aapt2/xml/XmlActionExecutor.cpp @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "xml/XmlActionExecutor.h" + +namespace aapt { +namespace xml { + +static bool wrapperOne(XmlNodeAction::ActionFunc& f, Element* el, SourcePathDiagnostics*) { + return f(el); +} + +static bool wrapperTwo(XmlNodeAction::ActionFuncWithDiag& f, Element* el, + SourcePathDiagnostics* diag) { + return f(el, diag); +} + +void XmlNodeAction::action(XmlNodeAction::ActionFunc f) { + mActions.emplace_back(std::bind(wrapperOne, std::move(f), + std::placeholders::_1, + std::placeholders::_2)); +} + +void XmlNodeAction::action(XmlNodeAction::ActionFuncWithDiag f) { + mActions.emplace_back(std::bind(wrapperTwo, std::move(f), + std::placeholders::_1, + std::placeholders::_2)); +} + +static void printElementToDiagMessage(const Element* el, DiagMessage* msg) { + *msg << "<"; + if (!el->namespaceUri.empty()) { + *msg << el->namespaceUri << ":"; + } + *msg << el->name << ">"; +} + +bool XmlNodeAction::execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag, + Element* el) const { + bool error = false; + for (const ActionFuncWithDiag& action : mActions) { + error |= !action(el, diag); + } + + for (Element* childEl : el->getChildElements()) { + if (childEl->namespaceUri.empty()) { + std::map<std::u16string, XmlNodeAction>::const_iterator iter = + mMap.find(childEl->name); + if (iter != mMap.end()) { + error |= !iter->second.execute(policy, diag, childEl); + continue; + } + } + + if (policy == XmlActionExecutorPolicy::Whitelist) { + DiagMessage errorMsg(childEl->lineNumber); + errorMsg << "unknown element "; + printElementToDiagMessage(childEl, &errorMsg); + errorMsg << " found"; + diag->error(errorMsg); + error = true; + } + } + return !error; +} + +bool XmlActionExecutor::execute(XmlActionExecutorPolicy policy, IDiagnostics* diag, + XmlResource* doc) const { + SourcePathDiagnostics sourceDiag(doc->file.source, diag); + + Element* el = findRootElement(doc); + if (!el) { + if (policy == XmlActionExecutorPolicy::Whitelist) { + sourceDiag.error(DiagMessage() << "no root XML tag found"); + return false; + } + return true; + } + + if (el->namespaceUri.empty()) { + std::map<std::u16string, XmlNodeAction>::const_iterator iter = mMap.find(el->name); + if (iter != mMap.end()) { + return iter->second.execute(policy, &sourceDiag, el); + } + } + + if (policy == XmlActionExecutorPolicy::Whitelist) { + DiagMessage errorMsg(el->lineNumber); + errorMsg << "unknown element "; + printElementToDiagMessage(el, &errorMsg); + errorMsg << " found"; + sourceDiag.error(errorMsg); + return false; + } + return true; +} + +} // namespace xml +} // namespace aapt diff --git a/tools/aapt2/xml/XmlActionExecutor.h b/tools/aapt2/xml/XmlActionExecutor.h new file mode 100644 index 000000000000..36b94dbfde05 --- /dev/null +++ b/tools/aapt2/xml/XmlActionExecutor.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef AAPT_XML_XMLPATTERN_H +#define AAPT_XML_XMLPATTERN_H + +#include "Diagnostics.h" +#include "xml/XmlDom.h" + +#include <android-base/macros.h> +#include <functional> +#include <map> +#include <string> +#include <vector> + +namespace aapt { +namespace xml { + +enum class XmlActionExecutorPolicy { + /** + * Actions on run if elements are matched, errors occur only when actions return false. + */ + None, + + /** + * The actions defined must match and run. If an element is found that does not match + * an action, an error occurs. + */ + Whitelist, +}; + +/** + * Contains the actions to perform at this XML node. This is a recursive data structure that + * holds XmlNodeActions for child XML nodes. + */ +class XmlNodeAction { +public: + using ActionFuncWithDiag = std::function<bool(Element*, SourcePathDiagnostics*)>; + using ActionFunc = std::function<bool(Element*)>; + + /** + * Find or create a child XmlNodeAction that will be performed for the child element + * with the name `name`. + */ + XmlNodeAction& operator[](const std::u16string& name) { + return mMap[name]; + } + + /** + * Add an action to be performed at this XmlNodeAction. + */ + void action(ActionFunc f); + void action(ActionFuncWithDiag); + +private: + friend class XmlActionExecutor; + + bool execute(XmlActionExecutorPolicy policy, SourcePathDiagnostics* diag, Element* el) const; + + std::map<std::u16string, XmlNodeAction> mMap; + std::vector<ActionFuncWithDiag> mActions; +}; + +/** + * Allows the definition of actions to execute at specific XML elements defined by their + * hierarchy. + */ +class XmlActionExecutor { +public: + XmlActionExecutor() = default; + + /** + * Find or create a root XmlNodeAction that will be performed for the root XML element + * with the name `name`. + */ + XmlNodeAction& operator[](const std::u16string& name) { + return mMap[name]; + } + + /** + * Execute the defined actions for this XmlResource. + * Returns true if all actions return true, otherwise returns false. + */ + bool execute(XmlActionExecutorPolicy policy, IDiagnostics* diag, XmlResource* doc) const; + +private: + std::map<std::u16string, XmlNodeAction> mMap; + + DISALLOW_COPY_AND_ASSIGN(XmlActionExecutor); +}; + +} // namespace xml +} // namespace aapt + +#endif /* AAPT_XML_XMLPATTERN_H */ diff --git a/tools/aapt2/xml/XmlActionExecutor_test.cpp b/tools/aapt2/xml/XmlActionExecutor_test.cpp new file mode 100644 index 000000000000..ebf287a251f2 --- /dev/null +++ b/tools/aapt2/xml/XmlActionExecutor_test.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test/Test.h" +#include "xml/XmlActionExecutor.h" + +namespace aapt { +namespace xml { + +TEST(XmlActionExecutorTest, BuildsAccessibleNestedPattern) { + XmlActionExecutor executor; + XmlNodeAction& manifestAction = executor[u"manifest"]; + XmlNodeAction& applicationAction = manifestAction[u"application"]; + + Element* manifestEl = nullptr; + manifestAction.action([&](Element* manifest) -> bool { + manifestEl = manifest; + return true; + }); + + Element* applicationEl = nullptr; + applicationAction.action([&](Element* application) -> bool { + applicationEl = application; + return true; + }); + + std::unique_ptr<XmlResource> doc = test::buildXmlDom("<manifest><application /></manifest>"); + + StdErrDiagnostics diag; + ASSERT_TRUE(executor.execute(XmlActionExecutorPolicy::None, &diag, doc.get())); + ASSERT_NE(nullptr, manifestEl); + EXPECT_EQ(std::u16string(u"manifest"), manifestEl->name); + + ASSERT_NE(nullptr, applicationEl); + EXPECT_EQ(std::u16string(u"application"), applicationEl->name); +} + +TEST(XmlActionExecutorTest, FailsWhenUndefinedHierarchyExists) { + XmlActionExecutor executor; + executor[u"manifest"][u"application"]; + + std::unique_ptr<XmlResource> doc = test::buildXmlDom( + "<manifest><application /><activity /></manifest>"); + StdErrDiagnostics diag; + ASSERT_FALSE(executor.execute(XmlActionExecutorPolicy::Whitelist, &diag, doc.get())); +} + +} // namespace xml +} // namespace aapt diff --git a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java index f5938cfa37a5..265ebd1755e3 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Path_Delegate.java @@ -423,21 +423,13 @@ public final class Path_Delegate { } @LayoutlibDelegate - /*package*/ static void native_offset(long nPath, float dx, float dy, long dst_path) { + /*package*/ static void native_offset(long nPath, float dx, float dy) { Path_Delegate pathDelegate = sManager.getDelegate(nPath); if (pathDelegate == null) { return; } - // could be null if the int is 0; - Path_Delegate dstDelegate = sManager.getDelegate(dst_path); - - pathDelegate.offset(dx, dy, dstDelegate); - } - - @LayoutlibDelegate - /*package*/ static void native_offset(long nPath, float dx, float dy) { - native_offset(nPath, dx, dy, 0); + pathDelegate.offset(dx, dy); } @LayoutlibDelegate @@ -860,21 +852,14 @@ public final class Path_Delegate { * * @param dx The amount in the X direction to offset the entire path * @param dy The amount in the Y direction to offset the entire path - * @param dst The translated path is written here. If this is null, then - * the original path is modified. */ - public void offset(float dx, float dy, Path_Delegate dst) { + public void offset(float dx, float dy) { GeneralPath newPath = new GeneralPath(); PathIterator iterator = mPath.getPathIterator(new AffineTransform(0, 0, dx, 0, 0, dy)); newPath.append(iterator, false /*connect*/); - - if (dst != null) { - dst.mPath = newPath; - } else { - mPath = newPath; - } + mPath = newPath; } /** diff --git a/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java b/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java index 01af669e39d3..381eb1f50973 100644 --- a/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java +++ b/tools/layoutlib/bridge/src/android/view/Choreographer_Delegate.java @@ -15,8 +15,11 @@ */ package android.view; +import com.android.ide.common.rendering.api.LayoutLog; +import com.android.layoutlib.bridge.Bridge; import com.android.tools.layoutlib.annotations.LayoutlibDelegate; +import java.lang.reflect.Field; import java.util.concurrent.atomic.AtomicReference; /** @@ -64,4 +67,18 @@ public class Choreographer_Delegate { thisChoreographer.doCallbacks(Choreographer.CALLBACK_COMMIT, frameTimeNanos); } + + public static void dispose() { + try { + Field threadInstanceField = Choreographer.class.getDeclaredField("sThreadInstance"); + threadInstanceField.setAccessible(true); + @SuppressWarnings("unchecked") ThreadLocal<Choreographer> threadInstance = + (ThreadLocal<Choreographer>) threadInstanceField.get(null); + threadInstance.remove(); + } catch (ReflectiveOperationException e) { + assert false; + Bridge.getLog().error(LayoutLog.TAG_BROKEN, + "Unable to clear Choreographer memory.", e, null); + } + } } diff --git a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java index 30512aad4509..ea9a255e8561 100644 --- a/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java +++ b/tools/layoutlib/bridge/src/android/view/RectShadowPainter.java @@ -44,6 +44,11 @@ public class RectShadowPainter { private static final float PERPENDICULAR_ANGLE = 90f; public static void paintShadow(Outline viewOutline, float elevation, Canvas canvas) { + Rect outline = new Rect(); + if (!viewOutline.getRect(outline)) { + throw new IllegalArgumentException("Outline is not a rect shadow"); + } + float shadowSize = elevationToShadow(elevation); int saved = modifyCanvas(canvas, shadowSize); if (saved == -1) { @@ -54,8 +59,7 @@ public class RectShadowPainter { cornerPaint.setStyle(Style.FILL); Paint edgePaint = new Paint(cornerPaint); edgePaint.setAntiAlias(false); - Rect outline = viewOutline.mRect; - float radius = viewOutline.mRadius; + float radius = viewOutline.getRadius(); float outerArcRadius = radius + shadowSize; int[] colors = {START_COLOR, START_COLOR, END_COLOR}; cornerPaint.setShader(new RadialGradient(0, 0, outerArcRadius, colors, diff --git a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java index 1465f5089599..24f788766cc9 100644 --- a/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java +++ b/tools/layoutlib/bridge/src/android/view/RenderNode_Delegate.java @@ -55,7 +55,7 @@ public class RenderNode_Delegate { private String mName; @LayoutlibDelegate - /*package*/ static long nCreate(String name) { + /*package*/ static long nCreate(RenderNode thisRenderNode, String name) { RenderNode_Delegate renderNodeDelegate = new RenderNode_Delegate(); renderNodeDelegate.mName = name; return sManager.addNewDelegate(renderNodeDelegate); diff --git a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java index 51d32e351eb8..23caaf85eb8e 100644 --- a/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java +++ b/tools/layoutlib/bridge/src/android/view/ViewGroup_Delegate.java @@ -64,7 +64,7 @@ public class ViewGroup_Delegate { private static void drawShadow(ViewGroup parent, Canvas canvas, View child, Outline outline) { float elevation = getElevation(child, parent); - if(outline.mRect != null) { + if(outline.mMode == Outline.MODE_ROUND_RECT && outline.mRect != null) { RectShadowPainter.paintShadow(outline, elevation, canvas); return; } 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 c8e3d03169e8..9e50ee898769 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -24,6 +24,7 @@ import com.android.ide.common.rendering.api.RenderSession; import com.android.ide.common.rendering.api.Result; import com.android.ide.common.rendering.api.Result.Status; import com.android.ide.common.rendering.api.SessionParams; +import com.android.layoutlib.bridge.android.RenderParamsFlags; import com.android.layoutlib.bridge.impl.RenderDrawable; import com.android.layoutlib.bridge.impl.RenderSessionImpl; import com.android.layoutlib.bridge.util.DynamicIdMap; @@ -408,7 +409,9 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { /** * Starts a layout session by inflating and rendering it. The method returns a * {@link RenderSession} on which further actions can be taken. - * + * <p/> + * If {@link SessionParams} includes the {@link RenderParamsFlags#FLAG_DO_NOT_RENDER_ON_CREATE}, + * this method will only inflate the layout but will NOT render it. * @param params the {@link SessionParams} object with all the information necessary to create * the scene. * @return a new {@link RenderSession} object that contains the result of the layout. @@ -424,7 +427,10 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { lastResult = scene.init(params.getTimeout()); if (lastResult.isSuccess()) { lastResult = scene.inflate(); - if (lastResult.isSuccess()) { + + boolean doNotRenderOnCreate = Boolean.TRUE.equals( + params.getFlag(RenderParamsFlags.FLAG_DO_NOT_RENDER_ON_CREATE)); + if (lastResult.isSuccess() && !doNotRenderOnCreate) { lastResult = scene.render(true /*freshRender*/); } } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java index 4161307aa8f3..2399b3a2345e 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java @@ -110,13 +110,13 @@ import static com.android.layoutlib.bridge.android.RenderParamsFlags.FLAG_KEY_AP public final class BridgeContext extends Context { /** The map adds cookies to each view so that IDE can link xml tags to views. */ - private final HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>(); + private final HashMap<View, Object> mViewKeyMap = new HashMap<>(); /** * In some cases, when inflating an xml, some objects are created. Then later, the objects are * converted to views. This map stores the mapping from objects to cookies which can then be * used to populate the mViewKeyMap. */ - private final HashMap<Object, Object> mViewKeyHelpMap = new HashMap<Object, Object>(); + private final HashMap<Object, Object> mViewKeyHelpMap = new HashMap<>(); private final BridgeAssetManager mAssets; private Resources mSystemResources; private final Object mProjectKey; @@ -132,8 +132,7 @@ public final class BridgeContext extends Context { private Resources.Theme mTheme; - private final Map<Object, Map<String, String>> mDefaultPropMaps = - new IdentityHashMap<Object, Map<String,String>>(); + private final Map<Object, PropertiesMap> mDefaultPropMaps = new IdentityHashMap<>(); // maps for dynamically generated id representing style objects (StyleResourceValue) @Nullable @@ -142,13 +141,12 @@ public final class BridgeContext extends Context { private int mDynamicIdGenerator = 0x02030000; // Base id for R.style in custom namespace // cache for TypedArray generated from StyleResourceValue object - private Map<int[], Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>> - mTypedArrayCache; + private TypedArrayCache mTypedArrayCache; private BridgeInflater mBridgeInflater; private BridgeContentResolver mContentResolver; - private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<BridgeXmlBlockParser>(); + private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<>(); private SharedPreferences mSharedPreferences; private ClassLoader mClassLoader; private IBinder mBinder; @@ -162,7 +160,7 @@ public final class BridgeContext extends Context { * This a map from value to attribute name. Warning for missing references shouldn't be logged * if value and attr name pair is the same as an entry in this map. */ - private static Map<String, String> RTL_ATTRS = new HashMap<String, String>(10); + private static Map<String, String> RTL_ATTRS = new HashMap<>(10); static { RTL_ATTRS.put("?android:attr/paddingLeft", "paddingStart"); @@ -325,11 +323,11 @@ public final class BridgeContext extends Context { return mParserStack.get(mParserStack.size() - 2); } - public boolean resolveThemeAttribute(int resid, TypedValue outValue, boolean resolveRefs) { - Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resid); + public boolean resolveThemeAttribute(int resId, TypedValue outValue, boolean resolveRefs) { + Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(resId); boolean isFrameworkRes = true; if (resourceInfo == null) { - resourceInfo = mLayoutlibCallback.resolveResourceId(resid); + resourceInfo = mLayoutlibCallback.resolveResourceId(resId); isFrameworkRes = false; } @@ -602,23 +600,20 @@ public final class BridgeContext extends Context { @Override public final BridgeTypedArray obtainStyledAttributes(int[] attrs) { - // No style is specified here, so create the typed array based on the default theme - // and the styles already applied to it. A null value of style indicates that the default - // theme should be used. - return createStyleBasedTypedArray(null, attrs); + return obtainStyledAttributes(0, attrs); } @Override - public final BridgeTypedArray obtainStyledAttributes(int resid, int[] attrs) + public final BridgeTypedArray obtainStyledAttributes(int resId, int[] attrs) throws Resources.NotFoundException { StyleResourceValue style = null; // get the StyleResourceValue based on the resId; - if (resid != 0) { - style = getStyleByDynamicId(resid); + if (resId != 0) { + style = getStyleByDynamicId(resId); if (style == null) { // In some cases, style may not be a dynamic id, so we do a full search. - ResourceReference ref = resolveId(resid); + ResourceReference ref = resolveId(resId); if (ref != null) { style = mRenderResources.getStyle(ref.getName(), ref.isFramework()); } @@ -629,41 +624,33 @@ public final class BridgeContext extends Context { } } - // The map is from - // attrs (int[]) -> context's current themes (List<StyleRV>) -> resid (int) -> typed array. if (mTypedArrayCache == null) { - mTypedArrayCache = new IdentityHashMap<int[], - Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>>(); + mTypedArrayCache = new TypedArrayCache(); } - // get the 2nd map - Map<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>> map2 = - mTypedArrayCache.get(attrs); - if (map2 == null) { - map2 = new HashMap<List<StyleResourceValue>, Map<Integer, BridgeTypedArray>>(); - mTypedArrayCache.put(attrs, map2); - } - - // get the 3rd map List<StyleResourceValue> currentThemes = mRenderResources.getAllThemes(); - Map<Integer, BridgeTypedArray> map3 = map2.get(currentThemes); - if (map3 == null) { - map3 = new HashMap<Integer, BridgeTypedArray>(); - // Create a copy of the list before adding it to the map. This allows reusing the - // existing list. - currentThemes = new ArrayList<StyleResourceValue>(currentThemes); - map2.put(currentThemes, map3); - } - // get the array from the 3rd map - BridgeTypedArray ta = map3.get(resid); + Pair<BridgeTypedArray, PropertiesMap> typeArrayAndPropertiesPair = + mTypedArrayCache.get(attrs, currentThemes, resId); - if (ta == null) { - ta = createStyleBasedTypedArray(style, attrs); - map3.put(resid, ta); + if (typeArrayAndPropertiesPair == null) { + typeArrayAndPropertiesPair = createStyleBasedTypedArray(style, attrs); + mTypedArrayCache.put(attrs, currentThemes, resId, typeArrayAndPropertiesPair); } - - return ta; + // Add value to defaultPropsMap if needed + if (typeArrayAndPropertiesPair.getSecond() != null) { + Object key = getCurrentParser().getViewCookie(); + if (key != null) { + PropertiesMap defaultPropMap = mDefaultPropMaps.get(key); + if (defaultPropMap == null) { + defaultPropMap = typeArrayAndPropertiesPair.getSecond(); + mDefaultPropMaps.put(key, defaultPropMap); + } else { + defaultPropMap.putAll(typeArrayAndPropertiesPair.getSecond()); + } + } + } + return typeArrayAndPropertiesPair.getFirst(); } @Override @@ -675,7 +662,7 @@ public final class BridgeContext extends Context { public BridgeTypedArray obtainStyledAttributes(AttributeSet set, int[] attrs, int defStyleAttr, int defStyleRes) { - Map<String, String> defaultPropMap = null; + PropertiesMap defaultPropMap = null; boolean isPlatformFile = true; // Hint: for XmlPullParser, attach source //DEVICE_SRC/dalvik/libcore/xml/src/java @@ -689,7 +676,7 @@ public final class BridgeContext extends Context { if (key != null) { defaultPropMap = mDefaultPropMaps.get(key); if (defaultPropMap == null) { - defaultPropMap = new HashMap<String, String>(); + defaultPropMap = new PropertiesMap(); mDefaultPropMaps.put(key, defaultPropMap); } } @@ -937,32 +924,33 @@ public final class BridgeContext extends Context { * * @see #obtainStyledAttributes(int, int[]) */ - private BridgeTypedArray createStyleBasedTypedArray(@Nullable StyleResourceValue style, - int[] attrs) throws Resources.NotFoundException { - + private Pair<BridgeTypedArray, PropertiesMap> createStyleBasedTypedArray( + @Nullable StyleResourceValue style, int[] attrs) throws Resources.NotFoundException { List<Pair<String, Boolean>> attributes = searchAttrs(attrs); - BridgeTypedArray ta = Resources_Delegate.newTypeArray(mSystemResources, attrs.length, - false); + BridgeTypedArray ta = Resources_Delegate.newTypeArray(mSystemResources, attrs.length, false); + PropertiesMap defaultPropMap = new PropertiesMap(); // for each attribute, get its name so that we can search it in the style - for (int i = 0 ; i < attrs.length ; i++) { + for (int i = 0; i < attrs.length; i++) { Pair<String, Boolean> attribute = attributes.get(i); if (attribute != null) { // look for the value in the given style ResourceValue resValue; + String attrName = attribute.getFirst(); if (style != null) { - resValue = mRenderResources.findItemInStyle(style, attribute.getFirst(), + resValue = mRenderResources.findItemInStyle(style, attrName, attribute.getSecond()); } else { - resValue = mRenderResources.findItemInTheme(attribute.getFirst(), - attribute.getSecond()); + resValue = mRenderResources.findItemInTheme(attrName, attribute.getSecond()); } if (resValue != null) { + // Add it to defaultPropMap before resolving + defaultPropMap.put(attrName, resValue.getValue()); // resolve it to make sure there are no references left. - ta.bridgeSetValue(i, attribute.getFirst(), attribute.getSecond(), + ta.bridgeSetValue(i, attrName, attribute.getSecond(), mRenderResources.resolveResValue(resValue)); } } @@ -970,7 +958,7 @@ public final class BridgeContext extends Context { ta.sealArray(); - return ta; + return Pair.of(ta, defaultPropMap); } /** @@ -982,7 +970,7 @@ public final class BridgeContext extends Context { * @return List of attribute information. */ private List<Pair<String, Boolean>> searchAttrs(int[] attrs) { - List<Pair<String, Boolean>> results = new ArrayList<Pair<String, Boolean>>(attrs.length); + List<Pair<String, Boolean>> results = new ArrayList<>(attrs.length); // for each attribute, get its name so that we can search it in the style for (int attr : attrs) { @@ -1011,7 +999,7 @@ public final class BridgeContext extends Context { * @return A (name, isFramework) pair describing the attribute if found. Returns null * if nothing is found. */ - public Pair<String, Boolean> searchAttr(int attr) { + private Pair<String, Boolean> searchAttr(int attr) { Pair<ResourceType, String> info = Bridge.resolveResourceId(attr); if (info != null) { return Pair.of(info.getSecond(), Boolean.TRUE); @@ -1028,8 +1016,8 @@ public final class BridgeContext extends Context { public int getDynamicIdByStyle(StyleResourceValue resValue) { if (mDynamicIdToStyleMap == null) { // create the maps. - mDynamicIdToStyleMap = new HashMap<Integer, StyleResourceValue>(); - mStyleToDynamicIdMap = new HashMap<StyleResourceValue, Integer>(); + mDynamicIdToStyleMap = new HashMap<>(); + mStyleToDynamicIdMap = new HashMap<>(); } // look for an existing id @@ -1868,4 +1856,69 @@ public final class BridgeContext extends Context { public boolean isCredentialProtectedStorage() { return false; } + + + /** + * The cached value depends on + * <ol> + * <li>{@code int[]}: the attributes for which TypedArray is created </li> + * <li>{@code List<StyleResourceValue>}: the themes set on the context at the time of + * creation of the TypedArray</li> + * <li>{@code Integer}: the default style used at the time of creation</li> + * </ol> + * + * The class is created by using nested maps resolving one dependency at a time. + * <p/> + * The final value of the nested maps is a pair of the typed array and a map of properties + * that should be added to {@link #mDefaultPropMaps}, if needed. + */ + private static class TypedArrayCache { + + private Map<int[], + Map<List<StyleResourceValue>, + Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>>> mCache; + + public TypedArrayCache() { + mCache = new IdentityHashMap<>(); + } + + public Pair<BridgeTypedArray, PropertiesMap> get(int[] attrs, + List<StyleResourceValue> themes, int resId) { + Map<List<StyleResourceValue>, Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>> + cacheFromThemes = mCache.get(attrs); + if (cacheFromThemes != null) { + Map<Integer, Pair<BridgeTypedArray, PropertiesMap>> cacheFromResId = + cacheFromThemes.get(themes); + if (cacheFromResId != null) { + return cacheFromResId.get(resId); + } + } + return null; + } + + public void put(int[] attrs, List<StyleResourceValue> themes, int resId, + Pair<BridgeTypedArray, PropertiesMap> value) { + Map<List<StyleResourceValue>, Map<Integer, Pair<BridgeTypedArray, PropertiesMap>>> + cacheFromThemes = mCache.get(attrs); + if (cacheFromThemes == null) { + cacheFromThemes = new HashMap<>(); + mCache.put(attrs, cacheFromThemes); + } + Map<Integer, Pair<BridgeTypedArray, PropertiesMap>> cacheFromResId = + cacheFromThemes.get(themes); + if (cacheFromResId == null) { + cacheFromResId = new HashMap<>(); + cacheFromThemes.put(themes, cacheFromResId); + } + cacheFromResId.put(resId, value); + } + + } + + /** + * An alias used for the value in {@code {@link #mDefaultPropMaps}} + */ + private static class PropertiesMap extends HashMap<String, String> { + } + } diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java index bd17a2fe6ca2..051de9055042 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/RenderParamsFlags.java @@ -53,6 +53,12 @@ public final class RenderParamsFlags { */ public static final Key<Boolean> FLAG_KEY_XML_FILE_PARSER_SUPPORT = new Key<Boolean>("xmlFileParser", Boolean.class); + /** + * To tell LayoutLib to not render when creating a new session. This allows controlling when the first + * layout rendering will happen. + */ + public static final Key<Boolean> FLAG_DO_NOT_RENDER_ON_CREATE = + new Key<Boolean>("doNotRenderOnCreate", Boolean.class); // Disallow instances. private RenderParamsFlags() {} diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java index 016825ae66e2..866b2480b828 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java @@ -267,6 +267,34 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } /** + * Renders the given view hierarchy to the passed canvas and returns the result of the render + * operation. + * @param canvas an optional canvas to render the views to. If null, only the measure and + * layout steps will be executed. + */ + private static Result render(@NonNull BridgeContext context, @NonNull ViewGroup viewRoot, + @Nullable Canvas canvas, int width, int height) { + // measure again with the size we need + // This must always be done before the call to layout + measureView(viewRoot, null /*measuredView*/, + width, MeasureSpec.EXACTLY, + height, MeasureSpec.EXACTLY); + + // now do the layout. + viewRoot.layout(0, 0, width, height); + handleScrolling(context, viewRoot); + + if (canvas == null) { + return SUCCESS.createResult(); + } + + AttachInfo_Accessor.dispatchOnPreDraw(viewRoot); + viewRoot.draw(canvas); + + return SUCCESS.createResult(); + } + + /** * Renders the scene. * <p> * {@link #acquire(long)} must have been called before this. @@ -367,24 +395,12 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } } - // measure again with the size we need - // This must always be done before the call to layout - measureView(mViewRoot, null /*measuredView*/, - mMeasuredScreenWidth, MeasureSpec.EXACTLY, - mMeasuredScreenHeight, MeasureSpec.EXACTLY); - - // now do the layout. - mViewRoot.layout(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight); - - handleScrolling(mViewRoot); - + Result renderResult = SUCCESS.createResult(); if (params.isLayoutOnly()) { // delete the canvas and image to reset them on the next full rendering mImage = null; mCanvas = null; } else { - AttachInfo_Accessor.dispatchOnPreDraw(mViewRoot); - // draw the views // create the BufferedImage into which the layout will be rendered. boolean newImage = false; @@ -446,6 +462,9 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { if (mElapsedFrameTimeNanos >= 0) { long initialTime = System_Delegate.nanoTime(); if (!mFirstFrameExecuted) { + // We need to run an initial draw call to initialize the animations + render(getContext(), mViewRoot, mCanvas, 0, 0); + // The first frame will initialize the animations Choreographer_Delegate.doFrame(initialTime); mFirstFrameExecuted = true; @@ -453,14 +472,15 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { // Second frame will move the animations Choreographer_Delegate.doFrame(initialTime + mElapsedFrameTimeNanos); } - mViewRoot.draw(mCanvas); + renderResult = render(getContext(), mViewRoot, mCanvas, mMeasuredScreenWidth, + mMeasuredScreenHeight); } mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(), false); // success! - return SUCCESS.createResult(); + return renderResult; } catch (Throwable e) { // get the real cause of the exception. Throwable t = e; @@ -488,7 +508,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { * @return the measured width/height if measuredView is non-null, null otherwise. */ @SuppressWarnings("deprecation") // For the use of Pair - private Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView, + private static Pair<Integer, Integer> measureView(ViewGroup viewToMeasure, View measuredView, int width, int widthMode, int height, int heightMode) { int w_spec = MeasureSpec.makeMeasureSpec(width, widthMode); int h_spec = MeasureSpec.makeMeasureSpec(height, heightMode); @@ -1061,8 +1081,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { * the component supports nested scrolling attempt that first, then use the unconsumed scroll * part to scroll the content in the component. */ - private void handleScrolling(View view) { - BridgeContext context = getContext(); + private static void handleScrolling(BridgeContext context, View view) { int scrollPosX = context.getScrollXPos(view); int scrollPosY = context.getScrollYPos(view); if (scrollPosX != 0 || scrollPosY != 0) { @@ -1080,7 +1099,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { } } if (scrollPosX != 0 || scrollPosY != 0) { - view.scrollBy(scrollPosX, scrollPosY); + view.scrollTo(scrollPosX, scrollPosY); } } @@ -1090,7 +1109,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { ViewGroup group = (ViewGroup) view; for (int i = 0; i < group.getChildCount(); i++) { View child = group.getChildAt(i); - handleScrolling(child); + handleScrolling(context, child); } } @@ -1434,6 +1453,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> { if (createdLooper) { Bridge.cleanupThread(); + Choreographer_Delegate.dispose(); } } } diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png Binary files differindex d8ead233b4ec..0e788e0c8264 100644 --- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets.png diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png Binary files differindex 65d1dc5b1edb..bad296bf4a66 100644 --- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/golden/allwidgets_tab.png diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml index 2da2cb983a6c..adb58a322abb 100644 --- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/allwidgets.xml @@ -197,6 +197,14 @@ android:inputType="numberPassword" android:text="numeric password" /> + <ToggleButton + android:id="@+id/toggleButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignTop="@id/editText4" + android:layout_toEndOf="@id/editText4" + android:text="New ToggleButton" /> + <EditText android:id="@id/editText5" android:layout_width="wrap_content" diff --git a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml index a5ebc2e20847..a07498cd07b1 100644 --- a/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml +++ b/tools/layoutlib/bridge/tests/res/testApp/MyApplication/src/main/res/layout/scrolled.xml @@ -2,8 +2,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:scrollX="10px" - android:scrollY="30px"> + android:scrollX="30px" + android:scrollY="90px"> <LinearLayout android:layout_width="60dp" android:layout_height="60dp" @@ -29,8 +29,8 @@ android:layout_width="200dp" android:layout_height="400dp" android:orientation="vertical" - android:scrollX="-30px" - android:scrollY="150px"> + android:scrollX="-90px" + android:scrollY="450px"> <LinearLayout android:layout_width="fill_parent" android:layout_height="60dp" diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java index 09dd5f078b9a..8f570aee96b7 100644 --- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java +++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/intensive/Main.java @@ -30,8 +30,9 @@ import com.android.ide.common.resources.configuration.FolderConfiguration; import com.android.io.FolderWrapper; import com.android.layoutlib.bridge.Bridge; import com.android.layoutlib.bridge.android.BridgeContext; -import com.android.layoutlib.bridge.impl.RenderAction; +import com.android.layoutlib.bridge.android.RenderParamsFlags; import com.android.layoutlib.bridge.impl.DelegateManager; +import com.android.layoutlib.bridge.impl.RenderAction; import com.android.layoutlib.bridge.intensive.setup.ConfigGenerator; import com.android.layoutlib.bridge.intensive.setup.LayoutLibTestCallback; import com.android.layoutlib.bridge.intensive.setup.LayoutPullParser; @@ -41,8 +42,12 @@ import com.android.resources.ResourceType; import com.android.utils.ILogger; import org.junit.AfterClass; +import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; import android.annotation.NonNull; import android.annotation.Nullable; @@ -55,9 +60,12 @@ import java.io.File; import java.io.IOException; import java.lang.ref.WeakReference; import java.net.URL; +import java.util.ArrayList; import java.util.Arrays; import java.util.concurrent.TimeUnit; +import com.google.android.collect.Lists; + import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -104,6 +112,21 @@ public class Main { private static ILogger sLogger; private static Bridge sBridge; + /** List of log messages generated by a render call. It can be used to find specific errors */ + private static ArrayList<String> sRenderMessages = Lists.newArrayList(); + + @Rule + public static TestWatcher sRenderMessageWatcher = new TestWatcher() { + @Override + protected void succeeded(Description description) { + // We only check error messages if the rest of the test case was successful. + if (!sRenderMessages.isEmpty()) { + fail(description.getMethodName() + " render error message: " + sRenderMessages.get + (0)); + } + } + }; + static { // Test that System Properties are properly set. PLATFORM_DIR = getPlatformDir(); @@ -278,6 +301,11 @@ public class Main { ConfigGenerator.getEnumMap(attrs), getLayoutLog()); } + @Before + public void beforeTestCase() { + sRenderMessages.clear(); + } + /** Test activity.xml */ @Test public void testActivity() throws ClassNotFoundException { @@ -288,6 +316,9 @@ public class Main { @Test public void testAllWidgets() throws ClassNotFoundException { renderAndVerify("allwidgets.xml", "allwidgets.png"); + + // We expect fidelity warnings for Path.isConvex. Fail for anything else. + sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported.")); } @Test @@ -298,6 +329,9 @@ public class Main { @Test public void testAllWidgetsTablet() throws ClassNotFoundException { renderAndVerify("allwidgets.xml", "allwidgets_tab.png", ConfigGenerator.NEXUS_7_2012); + + // We expect fidelity warnings for Path.isConvex. Fail for anything else. + sRenderMessages.removeIf(message -> message.equals("Path.isConvex is not supported.")); } private static void gc() { @@ -564,7 +598,7 @@ public class Main { sFrameworkRepo.getConfiguredResources(config), themeName, isProjectTheme); - return new SessionParams( + SessionParams sessionParams = new SessionParams( layoutParser, renderingMode, null /*used for caching*/, @@ -574,6 +608,8 @@ public class Main { 0, targetSdk, getLayoutLog()); + sessionParams.setFlag(RenderParamsFlags.FLAG_DO_NOT_RENDER_ON_CREATE, true); + return sessionParams; } private static LayoutLog getLayoutLog() { @@ -646,6 +682,6 @@ public class Main { } private static void failWithMsg(@NonNull String msgFormat, Object... args) { - fail(args == null ? "" : String.format(msgFormat, args)); + sRenderMessages.add(args == null ? msgFormat : String.format(msgFormat, args)); } } diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl index 1c7a308746b0..6ca4393a232a 100644 --- a/wifi/java/android/net/wifi/IWifiManager.aidl +++ b/wifi/java/android/net/wifi/IWifiManager.aidl @@ -149,9 +149,6 @@ interface IWifiManager void setAllowScansWithTraffic(int enabled); int getAllowScansWithTraffic(); - void setHalBasedAutojoinOffload(int enabled); - int getHalBasedAutojoinOffload(); - boolean enableAutoJoinWhenAssociated(boolean enabled); boolean getEnableAutoJoinWhenAssociated(); diff --git a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java index 9e15d6009e72..394934f59f51 100644 --- a/wifi/java/android/net/wifi/WifiEnterpriseConfig.java +++ b/wifi/java/android/net/wifi/WifiEnterpriseConfig.java @@ -719,7 +719,7 @@ public class WifiEnterpriseConfig implements Parcelable { * Get CA certificates. */ @Nullable public X509Certificate[] getCaCertificates() { - if (mCaCerts != null || mCaCerts.length > 0) { + if (mCaCerts != null && mCaCerts.length > 0) { return mCaCerts; } else { return null; diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 8c1fbc3a6def..6653a8dd6e07 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -28,7 +28,6 @@ import android.net.NetworkRequest; import android.os.Binder; import android.os.Build; import android.os.Handler; -import android.os.HandlerThread; import android.os.IBinder; import android.os.Looper; import android.os.Message; @@ -43,7 +42,6 @@ import com.android.internal.util.Protocol; import com.android.server.net.NetworkPinner; import java.net.InetAddress; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; @@ -2721,27 +2719,4 @@ public class WifiManager { throw e.rethrowFromSystemServer(); } } - /** - * Set setting for enabling autojoin Offload thru Wifi HAL layer - * @hide - */ - public void setHalBasedAutojoinOffload(int enabled) { - try { - mService.setHalBasedAutojoinOffload(enabled); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } - - /** - * Get setting for enabling autojoin Offload thru Wifi HAL layer - * @hide - */ - public int getHalBasedAutojoinOffload() { - try { - return mService.getHalBasedAutojoinOffload(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } - } } |