diff options
549 files changed, 14684 insertions, 5188 deletions
diff --git a/Android.mk b/Android.mk index 22cc27b6be87..b77c2edc15b9 100644 --- a/Android.mk +++ b/Android.mk @@ -737,7 +737,8 @@ sample_groups := -samplegroup Background \ -samplegroup Sensors \ -samplegroup Testing \ -samplegroup UI \ - -samplegroup Views + -samplegroup Views \ + -samplegroup Wearable ## SDK version identifiers used in the published docs # major[.minor] version for current SDK. (full releases only) diff --git a/api/current.txt b/api/current.txt index 5d134fdb7235..f7c47ff20ca4 100644 --- a/api/current.txt +++ b/api/current.txt @@ -113,6 +113,8 @@ package android { field public static final java.lang.String RECEIVE_SMS = "android.permission.RECEIVE_SMS"; field public static final java.lang.String RECEIVE_WAP_PUSH = "android.permission.RECEIVE_WAP_PUSH"; field public static final java.lang.String RECORD_AUDIO = "android.permission.RECORD_AUDIO"; + field public static final java.lang.String REGISTER_CONNECTION_MANAGER = "android.permission.REGISTER_CONNECTION_MANAGER"; + field public static final java.lang.String REGISTER_PROVIDER_OR_SUBSCRIPTION = "android.permission.REGISTER_PROVIDER_OR_SUBSCRIPTION"; field public static final java.lang.String REORDER_TASKS = "android.permission.REORDER_TASKS"; field public static final deprecated java.lang.String RESTART_PACKAGES = "android.permission.RESTART_PACKAGES"; field public static final java.lang.String SEND_RESPOND_VIA_MESSAGE = "android.permission.SEND_RESPOND_VIA_MESSAGE"; @@ -1002,6 +1004,7 @@ package android { field public static final int requiredForAllUsers = 16843728; // 0x10103d0 field public static final int requiresFadingEdge = 16843685; // 0x10103a5 field public static final int requiresSmallestWidthDp = 16843620; // 0x1010364 + field public static final int resizeClip = 16844033; // 0x1010501 field public static final int resizeMode = 16843619; // 0x1010363 field public static final int resizeable = 16843405; // 0x101028d field public static final int resource = 16842789; // 0x1010025 @@ -3052,9 +3055,10 @@ package android.animation { method public android.graphics.Rect evaluate(float, android.graphics.Rect, android.graphics.Rect); } - public class StateListAnimator { + public class StateListAnimator implements java.lang.Cloneable { ctor public StateListAnimator(); method public void addState(int[], android.animation.Animator); + method public android.animation.StateListAnimator clone(); method public void jumpToCurrentState(); } @@ -4402,6 +4406,7 @@ package android.app { method public android.content.Intent createConfirmDeviceCredentialIntent(java.lang.CharSequence, java.lang.CharSequence); method public deprecated void exitKeyguardSecurely(android.app.KeyguardManager.OnKeyguardExitResult); method public boolean inKeyguardRestrictedInputMode(); + method public boolean isKeyguardInTrustedState(); method public boolean isKeyguardLocked(); method public boolean isKeyguardSecure(); method public deprecated android.app.KeyguardManager.KeyguardLock newKeyguardLock(java.lang.String); @@ -7432,6 +7437,7 @@ package android.content { method public java.lang.Object clone(); method public android.content.Intent cloneFilter(); method public static android.content.Intent createChooser(android.content.Intent, java.lang.CharSequence); + method public static android.content.Intent createChooser(android.content.Intent, java.lang.CharSequence, android.content.IntentSender); method public int describeContents(); method public int fillIn(android.content.Intent, int); method public boolean filterEquals(android.content.Intent); @@ -7707,6 +7713,8 @@ package android.content { field public static final java.lang.String EXTRA_CHANGED_COMPONENT_NAME_LIST = "android.intent.extra.changed_component_name_list"; field public static final java.lang.String EXTRA_CHANGED_PACKAGE_LIST = "android.intent.extra.changed_package_list"; field public static final java.lang.String EXTRA_CHANGED_UID_LIST = "android.intent.extra.changed_uid_list"; + field public static final java.lang.String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT"; + field public static final java.lang.String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER"; field public static final java.lang.String EXTRA_DATA_REMOVED = "android.intent.extra.DATA_REMOVED"; field public static final java.lang.String EXTRA_DOCK_STATE = "android.intent.extra.DOCK_STATE"; field public static final int EXTRA_DOCK_STATE_CAR = 2; // 0x2 @@ -16543,15 +16551,21 @@ package android.media.tv { method public static java.lang.String[] decode(java.lang.String); method public static java.lang.String encode(java.lang.String...); field public static final java.lang.String ANIMAL_WILDLIFE = "ANIMAL_WILDLIFE"; + field public static final java.lang.String ARTS = "ARTS"; field public static final java.lang.String COMEDY = "COMEDY"; field public static final java.lang.String DRAMA = "DRAMA"; field public static final java.lang.String EDUCATION = "EDUCATION"; + field public static final java.lang.String ENTERTAINMENT = "ENTERTAINMENT"; field public static final java.lang.String FAMILY_KIDS = "FAMILY_KIDS"; field public static final java.lang.String GAMING = "GAMING"; + field public static final java.lang.String LIFE_STYLE = "LIFE_STYLE"; field public static final java.lang.String MOVIES = "MOVIES"; + field public static final java.lang.String MUSIC = "MUSIC"; field public static final java.lang.String NEWS = "NEWS"; + field public static final java.lang.String PREMIER = "PREMIER"; field public static final java.lang.String SHOPPING = "SHOPPING"; field public static final java.lang.String SPORTS = "SPORTS"; + field public static final java.lang.String TECH_SCIENCE = "TECH_SCIENCE"; field public static final java.lang.String TRAVEL = "TRAVEL"; } @@ -17031,6 +17045,7 @@ package android.net { } public class Network implements android.os.Parcelable { + method public void bindSocket(java.net.DatagramSocket) throws java.io.IOException; method public void bindSocket(java.net.Socket) throws java.io.IOException; method public int describeContents(); method public java.net.InetAddress[] getAllByName(java.lang.String) throws java.net.UnknownHostException; @@ -17150,7 +17165,7 @@ package android.net { field public static final java.lang.String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE"; } - public class ProxyInfo implements android.os.Parcelable { + public deprecated class ProxyInfo implements android.os.Parcelable { method public static android.net.ProxyInfo buildDirectProxy(java.lang.String, int); method public static android.net.ProxyInfo buildDirectProxy(java.lang.String, int, java.util.List<java.lang.String>); method public static android.net.ProxyInfo buildPacProxy(android.net.Uri); @@ -17197,7 +17212,7 @@ package android.net { method public static javax.net.SocketFactory getDefault(int); method public static javax.net.ssl.SSLSocketFactory getDefault(int, android.net.SSLSessionCache); method public java.lang.String[] getDefaultCipherSuites(); - method public static org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache); + method public static deprecated org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory(int, android.net.SSLSessionCache); method public static javax.net.ssl.SSLSocketFactory getInsecure(int, android.net.SSLSessionCache); method public byte[] getNpnSelectedProtocol(java.net.Socket); method public java.lang.String[] getSupportedCipherSuites(); @@ -17415,7 +17430,7 @@ package android.net { package android.net.http { - public final class AndroidHttpClient implements org.apache.http.client.HttpClient { + public final deprecated class AndroidHttpClient implements org.apache.http.client.HttpClient { method public void close(); method public void disableCurlLogging(); method public void enableCurlLogging(java.lang.String, int); @@ -17433,8 +17448,8 @@ package android.net.http { method public org.apache.http.params.HttpParams getParams(); method public static java.io.InputStream getUngzippedContent(org.apache.http.HttpEntity) throws java.io.IOException; method public static void modifyRequestToAcceptGzipResponse(org.apache.http.HttpRequest); - method public static android.net.http.AndroidHttpClient newInstance(java.lang.String, android.content.Context); - method public static android.net.http.AndroidHttpClient newInstance(java.lang.String); + method public static deprecated android.net.http.AndroidHttpClient newInstance(java.lang.String, android.content.Context); + method public static deprecated android.net.http.AndroidHttpClient newInstance(java.lang.String); method public static long parseDate(java.lang.String); field public static long DEFAULT_SYNC_MIN_GZIP_BYTES; } @@ -28216,6 +28231,7 @@ package android.telecom { method public android.telecom.PhoneAccountHandle getAccountHandle(); method public android.net.Uri getAddress(); method public int getCapabilities(); + method public int getColor(); method public android.graphics.drawable.Drawable getIcon(android.content.Context); method public int getIconResId(); method public java.lang.CharSequence getLabel(); @@ -28229,6 +28245,7 @@ package android.telecom { field public static final int CAPABILITY_PLACE_EMERGENCY_CALLS = 16; // 0x10 field public static final int CAPABILITY_SIM_SUBSCRIPTION = 4; // 0x4 field public static final android.os.Parcelable.Creator CREATOR; + field public static final int NO_COLOR = -1; // 0xffffffff field public static final java.lang.String SCHEME_SIP = "sip"; field public static final java.lang.String SCHEME_TEL = "tel"; field public static final java.lang.String SCHEME_VOICEMAIL = "voicemail"; @@ -28240,6 +28257,7 @@ package android.telecom { method public android.telecom.PhoneAccount build(); method public android.telecom.PhoneAccount.Builder setAddress(android.net.Uri); method public android.telecom.PhoneAccount.Builder setCapabilities(int); + method public android.telecom.PhoneAccount.Builder setColor(int); method public android.telecom.PhoneAccount.Builder setIconResId(int); method public android.telecom.PhoneAccount.Builder setShortDescription(java.lang.CharSequence); method public android.telecom.PhoneAccount.Builder setSubscriptionAddress(android.net.Uri); @@ -28697,8 +28715,8 @@ package android.telephony { method public void downloadMultimediaMessage(android.content.Context, java.lang.String, android.net.Uri, android.os.Bundle, android.app.PendingIntent); method public android.os.Bundle getCarrierConfigValues(); method public static android.telephony.SmsManager getDefault(); - method public static android.telephony.SmsManager getSmsManagerForSubscriber(long); - method public long getSubId(); + method public static android.telephony.SmsManager getSmsManagerForSubscriber(int); + method public int getSubId(); method public void injectSmsPdu(byte[], java.lang.String, android.app.PendingIntent); method public void sendDataMessage(java.lang.String, java.lang.String, short, byte[], android.app.PendingIntent, android.app.PendingIntent); method public void sendMultimediaMessage(android.content.Context, android.net.Uri, java.lang.String, android.os.Bundle, android.app.PendingIntent); @@ -28708,6 +28726,7 @@ package android.telephony { method public void updateMmsSendStatus(android.content.Context, int, byte[], int, android.net.Uri); method public void updateSmsSendStatus(int, boolean); field public static final java.lang.String EXTRA_MMS_DATA = "android.telephony.extra.MMS_DATA"; + field public static final java.lang.String EXTRA_MMS_HTTP_STATUS = "android.telephony.extra.MMS_HTTP_STATUS"; field public static final java.lang.String MMS_CONFIG_ALIAS_ENABLED = "aliasEnabled"; field public static final java.lang.String MMS_CONFIG_ALIAS_MAX_CHARS = "aliasMaxChars"; field public static final java.lang.String MMS_CONFIG_ALIAS_MIN_CHARS = "aliasMinChars"; @@ -28815,8 +28834,11 @@ package android.telephony { public class SubInfoRecord implements android.os.Parcelable { ctor public SubInfoRecord(); - ctor public SubInfoRecord(long, java.lang.String, int, java.lang.String, int, int, java.lang.String, int, int, int[], int, int); + ctor public SubInfoRecord(int, java.lang.String, int, java.lang.String, int, int, java.lang.String, int, int, int[], int, int); method public int describeContents(); + method public int getColor(); + method public android.graphics.drawable.BitmapDrawable getIconDrawable(); + method public java.lang.String getLabel(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; field public int color; @@ -28830,22 +28852,22 @@ package android.telephony { field public java.lang.String number; field public int[] simIconRes; field public int slotId; - field public long subId; + field public int subId; } public class SubscriptionManager implements android.provider.BaseColumns { method public static java.util.List<android.telephony.SubInfoRecord> getActiveSubInfoList(); - method public static long getDefaultSmsSubId(); - method public static int getSlotId(long); - method public static android.telephony.SubInfoRecord getSubInfoForSubscriber(long); + method public static int getDefaultSmsSubId(); + method public static int getSlotId(int); + method public static android.telephony.SubInfoRecord getSubInfoForSubscriber(int); method public static java.util.List<android.telephony.SubInfoRecord> getSubInfoUsingSlotId(int); - method public static boolean isValidSubId(long); - field public static final long ASK_USER_SUB_ID = -1001L; // 0xfffffffffffffc17L + method public static boolean isValidSubId(int); + field public static final int ASK_USER_SUB_ID = -1001; // 0xfffffc17 field public static final int DEFAULT_PHONE_ID = 2147483647; // 0x7fffffff - field public static final long DEFAULT_SUB_ID = 9223372036854775807L; // 0x7fffffffffffffffL + field public static final int DEFAULT_SUB_ID = 2147483647; // 0x7fffffff field public static final int INVALID_PHONE_ID = -1000; // 0xfffffc18 field public static final int INVALID_SLOT_ID = -1000; // 0xfffffc18 - field public static final long INVALID_SUB_ID = -1000L; // 0xfffffffffffffc18L + field public static final int INVALID_SUB_ID = -1000; // 0xfffffc18 field public static final java.lang.String MCC = "mcc"; field public static final java.lang.String MNC = "mnc"; field public static final int SIM_NOT_INSERTED = -1; // 0xffffffff @@ -30327,7 +30349,7 @@ package android.text.format { method public static java.lang.String formatShortFileSize(android.content.Context, long); } - public class Time { + public deprecated class Time { ctor public Time(java.lang.String); ctor public Time(); ctor public Time(android.text.format.Time); @@ -31297,6 +31319,7 @@ package android.transition { ctor public ChangeBounds(android.content.Context, android.util.AttributeSet); method public void captureEndValues(android.transition.TransitionValues); method public void captureStartValues(android.transition.TransitionValues); + method public boolean getResizeClip(); method public deprecated void setReparent(boolean); method public void setResizeClip(boolean); } @@ -31698,7 +31721,7 @@ package android.util { field public final int mTag; } - public class FloatMath { + public deprecated class FloatMath { method public static float ceil(float); method public static float cos(float); method public static float exp(float); @@ -33370,6 +33393,7 @@ package android.view { method public int describeContents(); method public boolean isValid(); method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException; + method public android.graphics.Canvas lockHardwareCanvas(); method public void readFromParcel(android.os.Parcel); method public void release(); method public deprecated void unlockCanvas(android.graphics.Canvas); @@ -34904,6 +34928,7 @@ package android.view { field public static final int FLAG_HARDWARE_ACCELERATED = 16777216; // 0x1000000 field public static final int FLAG_IGNORE_CHEEK_PRESSES = 32768; // 0x8000 field public static final int FLAG_KEEP_SCREEN_ON = 128; // 0x80 + field public static final int FLAG_LAYOUT_ATTACHED_IN_DECOR = 1073741824; // 0x40000000 field public static final int FLAG_LAYOUT_INSET_DECOR = 65536; // 0x10000 field public static final int FLAG_LAYOUT_IN_OVERSCAN = 33554432; // 0x2000000 field public static final int FLAG_LAYOUT_IN_SCREEN = 256; // 0x100 @@ -34953,6 +34978,7 @@ package android.view { field public static final int SOFT_INPUT_STATE_UNSPECIFIED = 0; // 0x0 field public static final int SOFT_INPUT_STATE_VISIBLE = 4; // 0x4 field public static final int TITLE_CHANGED = 64; // 0x40 + field public static final int TYPE_ACCESSIBILITY_OVERLAY = 2032; // 0x7f0 field public static final int TYPE_APPLICATION = 2; // 0x2 field public static final int TYPE_APPLICATION_ATTACHED_DIALOG = 1003; // 0x3eb field public static final int TYPE_APPLICATION_MEDIA = 1001; // 0x3e9 @@ -35372,6 +35398,7 @@ package android.view.accessibility { method public void recycle(); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; + field public static final int TYPE_ACCESSIBILITY_OVERLAY = 4; // 0x4 field public static final int TYPE_APPLICATION = 1; // 0x1 field public static final int TYPE_INPUT_METHOD = 2; // 0x2 field public static final int TYPE_SYSTEM = 3; // 0x3 @@ -35418,13 +35445,13 @@ package android.view.accessibility { package android.view.animation { - public class AccelerateDecelerateInterpolator implements android.view.animation.Interpolator { + public class AccelerateDecelerateInterpolator extends android.view.animation.BaseInterpolator { ctor public AccelerateDecelerateInterpolator(); ctor public AccelerateDecelerateInterpolator(android.content.Context, android.util.AttributeSet); method public float getInterpolation(float); } - public class AccelerateInterpolator implements android.view.animation.Interpolator { + public class AccelerateInterpolator extends android.view.animation.BaseInterpolator { ctor public AccelerateInterpolator(); ctor public AccelerateInterpolator(float); ctor public AccelerateInterpolator(android.content.Context, android.util.AttributeSet); @@ -35526,14 +35553,14 @@ package android.view.animation { method public static android.view.animation.Animation makeOutAnimation(android.content.Context, boolean); } - public class AnticipateInterpolator implements android.view.animation.Interpolator { + public class AnticipateInterpolator extends android.view.animation.BaseInterpolator { ctor public AnticipateInterpolator(); ctor public AnticipateInterpolator(float); ctor public AnticipateInterpolator(android.content.Context, android.util.AttributeSet); method public float getInterpolation(float); } - public class AnticipateOvershootInterpolator implements android.view.animation.Interpolator { + public class AnticipateOvershootInterpolator extends android.view.animation.BaseInterpolator { ctor public AnticipateOvershootInterpolator(); ctor public AnticipateOvershootInterpolator(float); ctor public AnticipateOvershootInterpolator(float, float); @@ -35541,19 +35568,23 @@ package android.view.animation { method public float getInterpolation(float); } - public class BounceInterpolator implements android.view.animation.Interpolator { + public abstract class BaseInterpolator implements android.view.animation.Interpolator { + ctor public BaseInterpolator(); + } + + public class BounceInterpolator extends android.view.animation.BaseInterpolator { ctor public BounceInterpolator(); ctor public BounceInterpolator(android.content.Context, android.util.AttributeSet); method public float getInterpolation(float); } - public class CycleInterpolator implements android.view.animation.Interpolator { + public class CycleInterpolator extends android.view.animation.BaseInterpolator { ctor public CycleInterpolator(float); ctor public CycleInterpolator(android.content.Context, android.util.AttributeSet); method public float getInterpolation(float); } - public class DecelerateInterpolator implements android.view.animation.Interpolator { + public class DecelerateInterpolator extends android.view.animation.BaseInterpolator { ctor public DecelerateInterpolator(); ctor public DecelerateInterpolator(float); ctor public DecelerateInterpolator(android.content.Context, android.util.AttributeSet); @@ -35628,20 +35659,20 @@ package android.view.animation { field public int index; } - public class LinearInterpolator implements android.view.animation.Interpolator { + public class LinearInterpolator extends android.view.animation.BaseInterpolator { ctor public LinearInterpolator(); ctor public LinearInterpolator(android.content.Context, android.util.AttributeSet); method public float getInterpolation(float); } - public class OvershootInterpolator implements android.view.animation.Interpolator { + public class OvershootInterpolator extends android.view.animation.BaseInterpolator { ctor public OvershootInterpolator(); ctor public OvershootInterpolator(float); ctor public OvershootInterpolator(android.content.Context, android.util.AttributeSet); method public float getInterpolation(float); } - public class PathInterpolator implements android.view.animation.Interpolator { + public class PathInterpolator extends android.view.animation.BaseInterpolator { ctor public PathInterpolator(android.graphics.Path); ctor public PathInterpolator(float, float); ctor public PathInterpolator(float, float, float, float); @@ -38167,6 +38198,7 @@ package android.widget { method public int getSoftInputMode(); method public int getWidth(); method public boolean isAboveAnchor(); + method public boolean isAttachedInDecor(); method public boolean isClippingEnabled(); method public boolean isFocusable(); method public boolean isOutsideTouchable(); @@ -38174,6 +38206,7 @@ package android.widget { method public boolean isSplitTouchEnabled(); method public boolean isTouchable(); method public void setAnimationStyle(int); + method public void setAttachedInDecor(boolean); method public void setBackgroundDrawable(android.graphics.drawable.Drawable); method public void setClippingEnabled(boolean); method public void setContentView(android.view.View); @@ -54377,7 +54410,7 @@ package junit.runner { package org.apache.commons.logging { - public abstract interface Log { + public abstract deprecated interface Log { method public abstract void debug(java.lang.Object); method public abstract void debug(java.lang.Object, java.lang.Throwable); method public abstract void error(java.lang.Object); @@ -54402,26 +54435,26 @@ package org.apache.commons.logging { package org.apache.http { - public class ConnectionClosedException extends java.io.IOException { + public deprecated class ConnectionClosedException extends java.io.IOException { ctor public ConnectionClosedException(java.lang.String); } - public abstract interface ConnectionReuseStrategy { + public abstract deprecated interface ConnectionReuseStrategy { method public abstract boolean keepAlive(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext); } - public abstract interface FormattedHeader implements org.apache.http.Header { + public abstract deprecated interface FormattedHeader implements org.apache.http.Header { method public abstract org.apache.http.util.CharArrayBuffer getBuffer(); method public abstract int getValuePos(); } - public abstract interface Header { + public abstract deprecated interface Header { method public abstract org.apache.http.HeaderElement[] getElements() throws org.apache.http.ParseException; method public abstract java.lang.String getName(); method public abstract java.lang.String getValue(); } - public abstract interface HeaderElement { + public abstract deprecated interface HeaderElement { method public abstract java.lang.String getName(); method public abstract org.apache.http.NameValuePair getParameter(int); method public abstract org.apache.http.NameValuePair getParameterByName(java.lang.String); @@ -54430,17 +54463,17 @@ package org.apache.http { method public abstract java.lang.String getValue(); } - public abstract interface HeaderElementIterator implements java.util.Iterator { + public abstract deprecated interface HeaderElementIterator implements java.util.Iterator { method public abstract boolean hasNext(); method public abstract org.apache.http.HeaderElement nextElement(); } - public abstract interface HeaderIterator implements java.util.Iterator { + public abstract deprecated interface HeaderIterator implements java.util.Iterator { method public abstract boolean hasNext(); method public abstract org.apache.http.Header nextHeader(); } - public abstract interface HttpClientConnection implements org.apache.http.HttpConnection { + public abstract deprecated interface HttpClientConnection implements org.apache.http.HttpConnection { method public abstract void flush() throws java.io.IOException; method public abstract boolean isResponseAvailable(int) throws java.io.IOException; method public abstract void receiveResponseEntity(org.apache.http.HttpResponse) throws org.apache.http.HttpException, java.io.IOException; @@ -54449,7 +54482,7 @@ package org.apache.http { method public abstract void sendRequestHeader(org.apache.http.HttpRequest) throws org.apache.http.HttpException, java.io.IOException; } - public abstract interface HttpConnection { + public abstract deprecated interface HttpConnection { method public abstract void close() throws java.io.IOException; method public abstract org.apache.http.HttpConnectionMetrics getMetrics(); method public abstract int getSocketTimeout(); @@ -54459,7 +54492,7 @@ package org.apache.http { method public abstract void shutdown() throws java.io.IOException; } - public abstract interface HttpConnectionMetrics { + public abstract deprecated interface HttpConnectionMetrics { method public abstract java.lang.Object getMetric(java.lang.String); method public abstract long getReceivedBytesCount(); method public abstract long getRequestCount(); @@ -54468,7 +54501,7 @@ package org.apache.http { method public abstract void reset(); } - public abstract interface HttpEntity { + public abstract deprecated interface HttpEntity { method public abstract void consumeContent() throws java.io.IOException; method public abstract java.io.InputStream getContent() throws java.io.IOException, java.lang.IllegalStateException; method public abstract org.apache.http.Header getContentEncoding(); @@ -54480,19 +54513,19 @@ package org.apache.http { method public abstract void writeTo(java.io.OutputStream) throws java.io.IOException; } - public abstract interface HttpEntityEnclosingRequest implements org.apache.http.HttpRequest { + public abstract deprecated interface HttpEntityEnclosingRequest implements org.apache.http.HttpRequest { method public abstract boolean expectContinue(); method public abstract org.apache.http.HttpEntity getEntity(); method public abstract void setEntity(org.apache.http.HttpEntity); } - public class HttpException extends java.lang.Exception { + public deprecated class HttpException extends java.lang.Exception { ctor public HttpException(); ctor public HttpException(java.lang.String); ctor public HttpException(java.lang.String, java.lang.Throwable); } - public final class HttpHost implements java.lang.Cloneable { + public final deprecated class HttpHost implements java.lang.Cloneable { ctor public HttpHost(java.lang.String, int, java.lang.String); ctor public HttpHost(java.lang.String, int); ctor public HttpHost(java.lang.String); @@ -54510,14 +54543,14 @@ package org.apache.http { field protected final java.lang.String schemeName; } - public abstract interface HttpInetConnection implements org.apache.http.HttpConnection { + public abstract deprecated interface HttpInetConnection implements org.apache.http.HttpConnection { method public abstract java.net.InetAddress getLocalAddress(); method public abstract int getLocalPort(); method public abstract java.net.InetAddress getRemoteAddress(); method public abstract int getRemotePort(); } - public abstract interface HttpMessage { + public abstract deprecated interface HttpMessage { method public abstract void addHeader(org.apache.http.Header); method public abstract void addHeader(java.lang.String, java.lang.String); method public abstract boolean containsHeader(java.lang.String); @@ -54537,20 +54570,20 @@ package org.apache.http { method public abstract void setParams(org.apache.http.params.HttpParams); } - public abstract interface HttpRequest implements org.apache.http.HttpMessage { + public abstract deprecated interface HttpRequest implements org.apache.http.HttpMessage { method public abstract org.apache.http.RequestLine getRequestLine(); } - public abstract interface HttpRequestFactory { + public abstract deprecated interface HttpRequestFactory { method public abstract org.apache.http.HttpRequest newHttpRequest(org.apache.http.RequestLine) throws org.apache.http.MethodNotSupportedException; method public abstract org.apache.http.HttpRequest newHttpRequest(java.lang.String, java.lang.String) throws org.apache.http.MethodNotSupportedException; } - public abstract interface HttpRequestInterceptor { + public abstract deprecated interface HttpRequestInterceptor { method public abstract void process(org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public abstract interface HttpResponse implements org.apache.http.HttpMessage { + public abstract deprecated interface HttpResponse implements org.apache.http.HttpMessage { method public abstract org.apache.http.HttpEntity getEntity(); method public abstract java.util.Locale getLocale(); method public abstract org.apache.http.StatusLine getStatusLine(); @@ -54563,16 +54596,16 @@ package org.apache.http { method public abstract void setStatusLine(org.apache.http.ProtocolVersion, int, java.lang.String); } - public abstract interface HttpResponseFactory { + public abstract deprecated interface HttpResponseFactory { method public abstract org.apache.http.HttpResponse newHttpResponse(org.apache.http.ProtocolVersion, int, org.apache.http.protocol.HttpContext); method public abstract org.apache.http.HttpResponse newHttpResponse(org.apache.http.StatusLine, org.apache.http.protocol.HttpContext); } - public abstract interface HttpResponseInterceptor { + public abstract deprecated interface HttpResponseInterceptor { method public abstract void process(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public abstract interface HttpServerConnection implements org.apache.http.HttpConnection { + public abstract deprecated interface HttpServerConnection implements org.apache.http.HttpConnection { method public abstract void flush() throws java.io.IOException; method public abstract void receiveRequestEntity(org.apache.http.HttpEntityEnclosingRequest) throws org.apache.http.HttpException, java.io.IOException; method public abstract org.apache.http.HttpRequest receiveRequestHeader() throws org.apache.http.HttpException, java.io.IOException; @@ -54580,7 +54613,7 @@ package org.apache.http { method public abstract void sendResponseHeader(org.apache.http.HttpResponse) throws org.apache.http.HttpException, java.io.IOException; } - public abstract interface HttpStatus { + public abstract deprecated interface HttpStatus { field public static final int SC_ACCEPTED = 202; // 0xca field public static final int SC_BAD_GATEWAY = 502; // 0x1f6 field public static final int SC_BAD_REQUEST = 400; // 0x190 @@ -54631,7 +54664,7 @@ package org.apache.http { field public static final int SC_USE_PROXY = 305; // 0x131 } - public final class HttpVersion extends org.apache.http.ProtocolVersion implements java.io.Serializable { + public final deprecated class HttpVersion extends org.apache.http.ProtocolVersion implements java.io.Serializable { ctor public HttpVersion(int, int); field public static final java.lang.String HTTP = "HTTP"; field public static final org.apache.http.HttpVersion HTTP_0_9; @@ -54639,37 +54672,37 @@ package org.apache.http { field public static final org.apache.http.HttpVersion HTTP_1_1; } - public class MalformedChunkCodingException extends java.io.IOException { + public deprecated class MalformedChunkCodingException extends java.io.IOException { ctor public MalformedChunkCodingException(); ctor public MalformedChunkCodingException(java.lang.String); } - public class MethodNotSupportedException extends org.apache.http.HttpException { + public deprecated class MethodNotSupportedException extends org.apache.http.HttpException { ctor public MethodNotSupportedException(java.lang.String); ctor public MethodNotSupportedException(java.lang.String, java.lang.Throwable); } - public abstract interface NameValuePair { + public abstract deprecated interface NameValuePair { method public abstract java.lang.String getName(); method public abstract java.lang.String getValue(); } - public class NoHttpResponseException extends java.io.IOException { + public deprecated class NoHttpResponseException extends java.io.IOException { ctor public NoHttpResponseException(java.lang.String); } - public class ParseException extends java.lang.RuntimeException { + public deprecated class ParseException extends java.lang.RuntimeException { ctor public ParseException(); ctor public ParseException(java.lang.String); } - public class ProtocolException extends org.apache.http.HttpException { + public deprecated class ProtocolException extends org.apache.http.HttpException { ctor public ProtocolException(); ctor public ProtocolException(java.lang.String); ctor public ProtocolException(java.lang.String, java.lang.Throwable); } - public class ProtocolVersion implements java.lang.Cloneable java.io.Serializable { + public deprecated class ProtocolVersion implements java.lang.Cloneable java.io.Serializable { ctor public ProtocolVersion(java.lang.String, int, int); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; method public int compareToVersion(org.apache.http.ProtocolVersion); @@ -54687,28 +54720,28 @@ package org.apache.http { field protected final java.lang.String protocol; } - public abstract interface ReasonPhraseCatalog { + public abstract deprecated interface ReasonPhraseCatalog { method public abstract java.lang.String getReason(int, java.util.Locale); } - public abstract interface RequestLine { + public abstract deprecated interface RequestLine { method public abstract java.lang.String getMethod(); method public abstract org.apache.http.ProtocolVersion getProtocolVersion(); method public abstract java.lang.String getUri(); } - public abstract interface StatusLine { + public abstract deprecated interface StatusLine { method public abstract org.apache.http.ProtocolVersion getProtocolVersion(); method public abstract java.lang.String getReasonPhrase(); method public abstract int getStatusCode(); } - public abstract interface TokenIterator implements java.util.Iterator { + public abstract deprecated interface TokenIterator implements java.util.Iterator { method public abstract boolean hasNext(); method public abstract java.lang.String nextToken(); } - public class UnsupportedHttpVersionException extends org.apache.http.ProtocolException { + public deprecated class UnsupportedHttpVersionException extends org.apache.http.ProtocolException { ctor public UnsupportedHttpVersionException(); ctor public UnsupportedHttpVersionException(java.lang.String); } @@ -54717,14 +54750,14 @@ package org.apache.http { package org.apache.http.auth { - public final class AUTH { + public final deprecated class AUTH { field public static final java.lang.String PROXY_AUTH = "Proxy-Authenticate"; field public static final java.lang.String PROXY_AUTH_RESP = "Proxy-Authorization"; field public static final java.lang.String WWW_AUTH = "WWW-Authenticate"; field public static final java.lang.String WWW_AUTH_RESP = "Authorization"; } - public abstract interface AuthScheme { + public abstract deprecated interface AuthScheme { method public abstract org.apache.http.Header authenticate(org.apache.http.auth.Credentials, org.apache.http.HttpRequest) throws org.apache.http.auth.AuthenticationException; method public abstract java.lang.String getParameter(java.lang.String); method public abstract java.lang.String getRealm(); @@ -54734,11 +54767,11 @@ package org.apache.http.auth { method public abstract void processChallenge(org.apache.http.Header) throws org.apache.http.auth.MalformedChallengeException; } - public abstract interface AuthSchemeFactory { + public abstract deprecated interface AuthSchemeFactory { method public abstract org.apache.http.auth.AuthScheme newInstance(org.apache.http.params.HttpParams); } - public final class AuthSchemeRegistry { + public final deprecated class AuthSchemeRegistry { ctor public AuthSchemeRegistry(); method public synchronized org.apache.http.auth.AuthScheme getAuthScheme(java.lang.String, org.apache.http.params.HttpParams) throws java.lang.IllegalStateException; method public synchronized java.util.List<java.lang.String> getSchemeNames(); @@ -54747,7 +54780,7 @@ package org.apache.http.auth { method public synchronized void unregister(java.lang.String); } - public class AuthScope { + public deprecated class AuthScope { ctor public AuthScope(java.lang.String, int, java.lang.String, java.lang.String); ctor public AuthScope(java.lang.String, int, java.lang.String); ctor public AuthScope(java.lang.String, int); @@ -54764,7 +54797,7 @@ package org.apache.http.auth { field public static final java.lang.String ANY_SCHEME; } - public class AuthState { + public deprecated class AuthState { ctor public AuthState(); method public org.apache.http.auth.AuthScheme getAuthScheme(); method public org.apache.http.auth.AuthScope getAuthScope(); @@ -54776,35 +54809,35 @@ package org.apache.http.auth { method public void setCredentials(org.apache.http.auth.Credentials); } - public class AuthenticationException extends org.apache.http.ProtocolException { + public deprecated class AuthenticationException extends org.apache.http.ProtocolException { ctor public AuthenticationException(); ctor public AuthenticationException(java.lang.String); ctor public AuthenticationException(java.lang.String, java.lang.Throwable); } - public final class BasicUserPrincipal implements java.security.Principal { + public final deprecated class BasicUserPrincipal implements java.security.Principal { ctor public BasicUserPrincipal(java.lang.String); method public java.lang.String getName(); } - public abstract interface Credentials { + public abstract deprecated interface Credentials { method public abstract java.lang.String getPassword(); method public abstract java.security.Principal getUserPrincipal(); } - public class InvalidCredentialsException extends org.apache.http.auth.AuthenticationException { + public deprecated class InvalidCredentialsException extends org.apache.http.auth.AuthenticationException { ctor public InvalidCredentialsException(); ctor public InvalidCredentialsException(java.lang.String); ctor public InvalidCredentialsException(java.lang.String, java.lang.Throwable); } - public class MalformedChallengeException extends org.apache.http.ProtocolException { + public deprecated class MalformedChallengeException extends org.apache.http.ProtocolException { ctor public MalformedChallengeException(); ctor public MalformedChallengeException(java.lang.String); ctor public MalformedChallengeException(java.lang.String, java.lang.Throwable); } - public class NTCredentials implements org.apache.http.auth.Credentials { + public deprecated class NTCredentials implements org.apache.http.auth.Credentials { ctor public NTCredentials(java.lang.String); ctor public NTCredentials(java.lang.String, java.lang.String, java.lang.String, java.lang.String); method public java.lang.String getDomain(); @@ -54814,14 +54847,14 @@ package org.apache.http.auth { method public java.lang.String getWorkstation(); } - public class NTUserPrincipal implements java.security.Principal { + public deprecated class NTUserPrincipal implements java.security.Principal { ctor public NTUserPrincipal(java.lang.String, java.lang.String); method public java.lang.String getDomain(); method public java.lang.String getName(); method public java.lang.String getUsername(); } - public class UsernamePasswordCredentials implements org.apache.http.auth.Credentials { + public deprecated class UsernamePasswordCredentials implements org.apache.http.auth.Credentials { ctor public UsernamePasswordCredentials(java.lang.String); ctor public UsernamePasswordCredentials(java.lang.String, java.lang.String); method public java.lang.String getPassword(); @@ -54833,16 +54866,16 @@ package org.apache.http.auth { package org.apache.http.auth.params { - public abstract interface AuthPNames { + public abstract deprecated interface AuthPNames { field public static final java.lang.String CREDENTIAL_CHARSET = "http.auth.credential-charset"; } - public class AuthParamBean extends org.apache.http.params.HttpAbstractParamBean { + public deprecated class AuthParamBean extends org.apache.http.params.HttpAbstractParamBean { ctor public AuthParamBean(org.apache.http.params.HttpParams); method public void setCredentialCharset(java.lang.String); } - public final class AuthParams { + public final deprecated class AuthParams { method public static java.lang.String getCredentialCharset(org.apache.http.params.HttpParams); method public static void setCredentialCharset(org.apache.http.params.HttpParams, java.lang.String); } @@ -54851,39 +54884,39 @@ package org.apache.http.auth.params { package org.apache.http.client { - public abstract interface AuthenticationHandler { + public abstract deprecated interface AuthenticationHandler { method public abstract java.util.Map<java.lang.String, org.apache.http.Header> getChallenges(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.auth.MalformedChallengeException; method public abstract boolean isAuthenticationRequested(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext); method public abstract org.apache.http.auth.AuthScheme selectScheme(java.util.Map<java.lang.String, org.apache.http.Header>, org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.auth.AuthenticationException; } - public class CircularRedirectException extends org.apache.http.client.RedirectException { + public deprecated class CircularRedirectException extends org.apache.http.client.RedirectException { ctor public CircularRedirectException(); ctor public CircularRedirectException(java.lang.String); ctor public CircularRedirectException(java.lang.String, java.lang.Throwable); } - public class ClientProtocolException extends java.io.IOException { + public deprecated class ClientProtocolException extends java.io.IOException { ctor public ClientProtocolException(); ctor public ClientProtocolException(java.lang.String); ctor public ClientProtocolException(java.lang.Throwable); ctor public ClientProtocolException(java.lang.String, java.lang.Throwable); } - public abstract interface CookieStore { + public abstract deprecated interface CookieStore { method public abstract void addCookie(org.apache.http.cookie.Cookie); method public abstract void clear(); method public abstract boolean clearExpired(java.util.Date); method public abstract java.util.List<org.apache.http.cookie.Cookie> getCookies(); } - public abstract interface CredentialsProvider { + public abstract deprecated interface CredentialsProvider { method public abstract void clear(); method public abstract org.apache.http.auth.Credentials getCredentials(org.apache.http.auth.AuthScope); method public abstract void setCredentials(org.apache.http.auth.AuthScope, org.apache.http.auth.Credentials); } - public abstract interface HttpClient { + public abstract deprecated interface HttpClient { method public abstract org.apache.http.HttpResponse execute(org.apache.http.client.methods.HttpUriRequest) throws org.apache.http.client.ClientProtocolException, java.io.IOException; method public abstract org.apache.http.HttpResponse execute(org.apache.http.client.methods.HttpUriRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.client.ClientProtocolException, java.io.IOException; method public abstract org.apache.http.HttpResponse execute(org.apache.http.HttpHost, org.apache.http.HttpRequest) throws org.apache.http.client.ClientProtocolException, java.io.IOException; @@ -54896,40 +54929,40 @@ package org.apache.http.client { method public abstract org.apache.http.params.HttpParams getParams(); } - public abstract interface HttpRequestRetryHandler { + public abstract deprecated interface HttpRequestRetryHandler { method public abstract boolean retryRequest(java.io.IOException, int, org.apache.http.protocol.HttpContext); } - public class HttpResponseException extends org.apache.http.client.ClientProtocolException { + public deprecated class HttpResponseException extends org.apache.http.client.ClientProtocolException { ctor public HttpResponseException(int, java.lang.String); method public int getStatusCode(); } - public class NonRepeatableRequestException extends org.apache.http.ProtocolException { + public deprecated class NonRepeatableRequestException extends org.apache.http.ProtocolException { ctor public NonRepeatableRequestException(); ctor public NonRepeatableRequestException(java.lang.String); } - public class RedirectException extends org.apache.http.ProtocolException { + public deprecated class RedirectException extends org.apache.http.ProtocolException { ctor public RedirectException(); ctor public RedirectException(java.lang.String); ctor public RedirectException(java.lang.String, java.lang.Throwable); } - public abstract interface RedirectHandler { + public abstract deprecated interface RedirectHandler { method public abstract java.net.URI getLocationURI(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.ProtocolException; method public abstract boolean isRedirectRequested(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext); } - public abstract interface RequestDirector { + public abstract deprecated interface RequestDirector { method public abstract org.apache.http.HttpResponse execute(org.apache.http.HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public abstract interface ResponseHandler { + public abstract deprecated interface ResponseHandler { method public abstract T handleResponse(org.apache.http.HttpResponse) throws org.apache.http.client.ClientProtocolException, java.io.IOException; } - public abstract interface UserTokenHandler { + public abstract deprecated interface UserTokenHandler { method public abstract java.lang.Object getUserToken(org.apache.http.protocol.HttpContext); } @@ -54937,7 +54970,7 @@ package org.apache.http.client { package org.apache.http.client.entity { - public class UrlEncodedFormEntity extends org.apache.http.entity.StringEntity { + public deprecated class UrlEncodedFormEntity extends org.apache.http.entity.StringEntity { ctor public UrlEncodedFormEntity(java.util.List<? extends org.apache.http.NameValuePair>, java.lang.String) throws java.io.UnsupportedEncodingException; ctor public UrlEncodedFormEntity(java.util.List<? extends org.apache.http.NameValuePair>) throws java.io.UnsupportedEncodingException; } @@ -54946,13 +54979,13 @@ package org.apache.http.client.entity { package org.apache.http.client.methods { - public abstract interface AbortableHttpRequest { + public abstract deprecated interface AbortableHttpRequest { method public abstract void abort(); method public abstract void setConnectionRequest(org.apache.http.conn.ClientConnectionRequest) throws java.io.IOException; method public abstract void setReleaseTrigger(org.apache.http.conn.ConnectionReleaseTrigger) throws java.io.IOException; } - public class HttpDelete extends org.apache.http.client.methods.HttpRequestBase { + public deprecated class HttpDelete extends org.apache.http.client.methods.HttpRequestBase { ctor public HttpDelete(); ctor public HttpDelete(java.net.URI); ctor public HttpDelete(java.lang.String); @@ -54960,14 +54993,14 @@ package org.apache.http.client.methods { field public static final java.lang.String METHOD_NAME = "DELETE"; } - public abstract class HttpEntityEnclosingRequestBase extends org.apache.http.client.methods.HttpRequestBase implements org.apache.http.HttpEntityEnclosingRequest { + public abstract deprecated class HttpEntityEnclosingRequestBase extends org.apache.http.client.methods.HttpRequestBase implements org.apache.http.HttpEntityEnclosingRequest { ctor public HttpEntityEnclosingRequestBase(); method public boolean expectContinue(); method public org.apache.http.HttpEntity getEntity(); method public void setEntity(org.apache.http.HttpEntity); } - public class HttpGet extends org.apache.http.client.methods.HttpRequestBase { + public deprecated class HttpGet extends org.apache.http.client.methods.HttpRequestBase { ctor public HttpGet(); ctor public HttpGet(java.net.URI); ctor public HttpGet(java.lang.String); @@ -54975,7 +55008,7 @@ package org.apache.http.client.methods { field public static final java.lang.String METHOD_NAME = "GET"; } - public class HttpHead extends org.apache.http.client.methods.HttpRequestBase { + public deprecated class HttpHead extends org.apache.http.client.methods.HttpRequestBase { ctor public HttpHead(); ctor public HttpHead(java.net.URI); ctor public HttpHead(java.lang.String); @@ -54983,7 +55016,7 @@ package org.apache.http.client.methods { field public static final java.lang.String METHOD_NAME = "HEAD"; } - public class HttpOptions extends org.apache.http.client.methods.HttpRequestBase { + public deprecated class HttpOptions extends org.apache.http.client.methods.HttpRequestBase { ctor public HttpOptions(); ctor public HttpOptions(java.net.URI); ctor public HttpOptions(java.lang.String); @@ -54992,7 +55025,7 @@ package org.apache.http.client.methods { field public static final java.lang.String METHOD_NAME = "OPTIONS"; } - public class HttpPost extends org.apache.http.client.methods.HttpEntityEnclosingRequestBase { + public deprecated class HttpPost extends org.apache.http.client.methods.HttpEntityEnclosingRequestBase { ctor public HttpPost(); ctor public HttpPost(java.net.URI); ctor public HttpPost(java.lang.String); @@ -55000,7 +55033,7 @@ package org.apache.http.client.methods { field public static final java.lang.String METHOD_NAME = "POST"; } - public class HttpPut extends org.apache.http.client.methods.HttpEntityEnclosingRequestBase { + public deprecated class HttpPut extends org.apache.http.client.methods.HttpEntityEnclosingRequestBase { ctor public HttpPut(); ctor public HttpPut(java.net.URI); ctor public HttpPut(java.lang.String); @@ -55008,7 +55041,7 @@ package org.apache.http.client.methods { field public static final java.lang.String METHOD_NAME = "PUT"; } - public abstract class HttpRequestBase extends org.apache.http.message.AbstractHttpMessage implements org.apache.http.client.methods.AbortableHttpRequest java.lang.Cloneable org.apache.http.client.methods.HttpUriRequest { + public abstract deprecated class HttpRequestBase extends org.apache.http.message.AbstractHttpMessage implements org.apache.http.client.methods.AbortableHttpRequest java.lang.Cloneable org.apache.http.client.methods.HttpUriRequest { ctor public HttpRequestBase(); method public void abort(); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; @@ -55022,7 +55055,7 @@ package org.apache.http.client.methods { method public void setURI(java.net.URI); } - public class HttpTrace extends org.apache.http.client.methods.HttpRequestBase { + public deprecated class HttpTrace extends org.apache.http.client.methods.HttpRequestBase { ctor public HttpTrace(); ctor public HttpTrace(java.net.URI); ctor public HttpTrace(java.lang.String); @@ -55030,7 +55063,7 @@ package org.apache.http.client.methods { field public static final java.lang.String METHOD_NAME = "TRACE"; } - public abstract interface HttpUriRequest implements org.apache.http.HttpRequest { + public abstract deprecated interface HttpUriRequest implements org.apache.http.HttpRequest { method public abstract void abort() throws java.lang.UnsupportedOperationException; method public abstract java.lang.String getMethod(); method public abstract java.net.URI getURI(); @@ -55041,16 +55074,16 @@ package org.apache.http.client.methods { package org.apache.http.client.params { - public abstract interface AllClientPNames implements org.apache.http.auth.params.AuthPNames org.apache.http.client.params.ClientPNames org.apache.http.conn.params.ConnConnectionPNames org.apache.http.conn.params.ConnManagerPNames org.apache.http.conn.params.ConnRoutePNames org.apache.http.cookie.params.CookieSpecPNames org.apache.http.params.CoreConnectionPNames org.apache.http.params.CoreProtocolPNames { + public abstract deprecated interface AllClientPNames implements org.apache.http.auth.params.AuthPNames org.apache.http.client.params.ClientPNames org.apache.http.conn.params.ConnConnectionPNames org.apache.http.conn.params.ConnManagerPNames org.apache.http.conn.params.ConnRoutePNames org.apache.http.cookie.params.CookieSpecPNames org.apache.http.params.CoreConnectionPNames org.apache.http.params.CoreProtocolPNames { } - public final class AuthPolicy { + public final deprecated class AuthPolicy { field public static final java.lang.String BASIC = "Basic"; field public static final java.lang.String DIGEST = "Digest"; field public static final java.lang.String NTLM = "NTLM"; } - public abstract interface ClientPNames { + public abstract deprecated interface ClientPNames { field public static final java.lang.String ALLOW_CIRCULAR_REDIRECTS = "http.protocol.allow-circular-redirects"; field public static final java.lang.String CONNECTION_MANAGER_FACTORY = "http.connection-manager.factory-object"; field public static final java.lang.String CONNECTION_MANAGER_FACTORY_CLASS_NAME = "http.connection-manager.factory-class-name"; @@ -55064,7 +55097,7 @@ package org.apache.http.client.params { field public static final java.lang.String VIRTUAL_HOST = "http.virtual-host"; } - public class ClientParamBean extends org.apache.http.params.HttpAbstractParamBean { + public deprecated class ClientParamBean extends org.apache.http.params.HttpAbstractParamBean { ctor public ClientParamBean(org.apache.http.params.HttpParams); method public void setAllowCircularRedirects(boolean); method public void setConnectionManagerFactory(org.apache.http.conn.ClientConnectionManagerFactory); @@ -55079,7 +55112,7 @@ package org.apache.http.client.params { method public void setVirtualHost(org.apache.http.HttpHost); } - public final class CookiePolicy { + public final deprecated class CookiePolicy { field public static final java.lang.String BEST_MATCH = "best-match"; field public static final java.lang.String BROWSER_COMPATIBILITY = "compatibility"; field public static final java.lang.String NETSCAPE = "netscape"; @@ -55087,7 +55120,7 @@ package org.apache.http.client.params { field public static final java.lang.String RFC_2965 = "rfc2965"; } - public class HttpClientParams { + public deprecated class HttpClientParams { method public static java.lang.String getCookiePolicy(org.apache.http.params.HttpParams); method public static boolean isAuthenticating(org.apache.http.params.HttpParams); method public static boolean isRedirecting(org.apache.http.params.HttpParams); @@ -55100,7 +55133,7 @@ package org.apache.http.client.params { package org.apache.http.client.protocol { - public abstract interface ClientContext { + public abstract deprecated interface ClientContext { field public static final java.lang.String AUTHSCHEME_REGISTRY = "http.authscheme-registry"; field public static final java.lang.String AUTH_SCHEME_PREF = "http.auth.scheme-pref"; field public static final java.lang.String COOKIESPEC_REGISTRY = "http.cookiespec-registry"; @@ -55113,7 +55146,7 @@ package org.apache.http.client.protocol { field public static final java.lang.String USER_TOKEN = "http.user-token"; } - public class ClientContextConfigurer implements org.apache.http.client.protocol.ClientContext { + public deprecated class ClientContextConfigurer implements org.apache.http.client.protocol.ClientContext { ctor public ClientContextConfigurer(org.apache.http.protocol.HttpContext); method public void setAuthSchemePref(java.util.List<java.lang.String>); method public void setAuthSchemeRegistry(org.apache.http.auth.AuthSchemeRegistry); @@ -55122,27 +55155,27 @@ package org.apache.http.client.protocol { method public void setCredentialsProvider(org.apache.http.client.CredentialsProvider); } - public class RequestAddCookies implements org.apache.http.HttpRequestInterceptor { + public deprecated class RequestAddCookies implements org.apache.http.HttpRequestInterceptor { ctor public RequestAddCookies(); method public void process(org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class RequestDefaultHeaders implements org.apache.http.HttpRequestInterceptor { + public deprecated class RequestDefaultHeaders implements org.apache.http.HttpRequestInterceptor { ctor public RequestDefaultHeaders(); method public void process(org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class RequestProxyAuthentication implements org.apache.http.HttpRequestInterceptor { + public deprecated class RequestProxyAuthentication implements org.apache.http.HttpRequestInterceptor { ctor public RequestProxyAuthentication(); method public void process(org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class RequestTargetAuthentication implements org.apache.http.HttpRequestInterceptor { + public deprecated class RequestTargetAuthentication implements org.apache.http.HttpRequestInterceptor { ctor public RequestTargetAuthentication(); method public void process(org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class ResponseProcessCookies implements org.apache.http.HttpResponseInterceptor { + public deprecated class ResponseProcessCookies implements org.apache.http.HttpResponseInterceptor { ctor public ResponseProcessCookies(); method public void process(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } @@ -55151,11 +55184,11 @@ package org.apache.http.client.protocol { package org.apache.http.client.utils { - public class CloneUtils { + public deprecated class CloneUtils { method public static java.lang.Object clone(java.lang.Object) throws java.lang.CloneNotSupportedException; } - public class URIUtils { + public deprecated class URIUtils { method public static java.net.URI createURI(java.lang.String, java.lang.String, int, java.lang.String, java.lang.String, java.lang.String) throws java.net.URISyntaxException; method public static java.net.URI resolve(java.net.URI, java.lang.String); method public static java.net.URI resolve(java.net.URI, java.net.URI); @@ -55163,7 +55196,7 @@ package org.apache.http.client.utils { method public static java.net.URI rewriteURI(java.net.URI, org.apache.http.HttpHost) throws java.net.URISyntaxException; } - public class URLEncodedUtils { + public deprecated class URLEncodedUtils { ctor public URLEncodedUtils(); method public static java.lang.String format(java.util.List<? extends org.apache.http.NameValuePair>, java.lang.String); method public static boolean isEncoded(org.apache.http.HttpEntity); @@ -55177,7 +55210,7 @@ package org.apache.http.client.utils { package org.apache.http.conn { - public class BasicEofSensorWatcher implements org.apache.http.conn.EofSensorWatcher { + public deprecated class BasicEofSensorWatcher implements org.apache.http.conn.EofSensorWatcher { ctor public BasicEofSensorWatcher(org.apache.http.conn.ManagedClientConnection, boolean); method public boolean eofDetected(java.io.InputStream) throws java.io.IOException; method public boolean streamAbort(java.io.InputStream) throws java.io.IOException; @@ -55186,7 +55219,7 @@ package org.apache.http.conn { field protected org.apache.http.conn.ManagedClientConnection managedConn; } - public class BasicManagedEntity extends org.apache.http.entity.HttpEntityWrapper implements org.apache.http.conn.ConnectionReleaseTrigger org.apache.http.conn.EofSensorWatcher { + public deprecated class BasicManagedEntity extends org.apache.http.entity.HttpEntityWrapper implements org.apache.http.conn.ConnectionReleaseTrigger org.apache.http.conn.EofSensorWatcher { ctor public BasicManagedEntity(org.apache.http.HttpEntity, org.apache.http.conn.ManagedClientConnection, boolean); method public void abortConnection() throws java.io.IOException; method public boolean eofDetected(java.io.InputStream) throws java.io.IOException; @@ -55198,7 +55231,7 @@ package org.apache.http.conn { field protected org.apache.http.conn.ManagedClientConnection managedConn; } - public abstract interface ClientConnectionManager { + public abstract deprecated interface ClientConnectionManager { method public abstract void closeExpiredConnections(); method public abstract void closeIdleConnections(long, java.util.concurrent.TimeUnit); method public abstract org.apache.http.conn.scheme.SchemeRegistry getSchemeRegistry(); @@ -55207,41 +55240,41 @@ package org.apache.http.conn { method public abstract void shutdown(); } - public abstract interface ClientConnectionManagerFactory { + public abstract deprecated interface ClientConnectionManagerFactory { method public abstract org.apache.http.conn.ClientConnectionManager newInstance(org.apache.http.params.HttpParams, org.apache.http.conn.scheme.SchemeRegistry); } - public abstract interface ClientConnectionOperator { + public abstract deprecated interface ClientConnectionOperator { method public abstract org.apache.http.conn.OperatedClientConnection createConnection(); method public abstract void openConnection(org.apache.http.conn.OperatedClientConnection, org.apache.http.HttpHost, java.net.InetAddress, org.apache.http.protocol.HttpContext, org.apache.http.params.HttpParams) throws java.io.IOException; method public abstract void updateSecureConnection(org.apache.http.conn.OperatedClientConnection, org.apache.http.HttpHost, org.apache.http.protocol.HttpContext, org.apache.http.params.HttpParams) throws java.io.IOException; } - public abstract interface ClientConnectionRequest { + public abstract deprecated interface ClientConnectionRequest { method public abstract void abortRequest(); method public abstract org.apache.http.conn.ManagedClientConnection getConnection(long, java.util.concurrent.TimeUnit) throws org.apache.http.conn.ConnectionPoolTimeoutException, java.lang.InterruptedException; } - public class ConnectTimeoutException extends java.io.InterruptedIOException { + public deprecated class ConnectTimeoutException extends java.io.InterruptedIOException { ctor public ConnectTimeoutException(); ctor public ConnectTimeoutException(java.lang.String); } - public abstract interface ConnectionKeepAliveStrategy { + public abstract deprecated interface ConnectionKeepAliveStrategy { method public abstract long getKeepAliveDuration(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext); } - public class ConnectionPoolTimeoutException extends org.apache.http.conn.ConnectTimeoutException { + public deprecated class ConnectionPoolTimeoutException extends org.apache.http.conn.ConnectTimeoutException { ctor public ConnectionPoolTimeoutException(); ctor public ConnectionPoolTimeoutException(java.lang.String); } - public abstract interface ConnectionReleaseTrigger { + public abstract deprecated interface ConnectionReleaseTrigger { method public abstract void abortConnection() throws java.io.IOException; method public abstract void releaseConnection() throws java.io.IOException; } - public class EofSensorInputStream extends java.io.InputStream implements org.apache.http.conn.ConnectionReleaseTrigger { + public deprecated class EofSensorInputStream extends java.io.InputStream implements org.apache.http.conn.ConnectionReleaseTrigger { ctor public EofSensorInputStream(java.io.InputStream, org.apache.http.conn.EofSensorWatcher); method public void abortConnection() throws java.io.IOException; method protected void checkAbort() throws java.io.IOException; @@ -55253,18 +55286,18 @@ package org.apache.http.conn { field protected java.io.InputStream wrappedStream; } - public abstract interface EofSensorWatcher { + public abstract deprecated interface EofSensorWatcher { method public abstract boolean eofDetected(java.io.InputStream) throws java.io.IOException; method public abstract boolean streamAbort(java.io.InputStream) throws java.io.IOException; method public abstract boolean streamClosed(java.io.InputStream) throws java.io.IOException; } - public class HttpHostConnectException extends java.net.ConnectException { + public deprecated class HttpHostConnectException extends java.net.ConnectException { ctor public HttpHostConnectException(org.apache.http.HttpHost, java.net.ConnectException); method public org.apache.http.HttpHost getHost(); } - public abstract interface ManagedClientConnection implements org.apache.http.conn.ConnectionReleaseTrigger org.apache.http.HttpClientConnection org.apache.http.HttpInetConnection { + public abstract deprecated interface ManagedClientConnection implements org.apache.http.conn.ConnectionReleaseTrigger org.apache.http.HttpClientConnection org.apache.http.HttpInetConnection { method public abstract org.apache.http.conn.routing.HttpRoute getRoute(); method public abstract javax.net.ssl.SSLSession getSSLSession(); method public abstract java.lang.Object getState(); @@ -55280,14 +55313,14 @@ package org.apache.http.conn { method public abstract void unmarkReusable(); } - public final class MultihomePlainSocketFactory implements org.apache.http.conn.scheme.SocketFactory { + public final deprecated class MultihomePlainSocketFactory implements org.apache.http.conn.scheme.SocketFactory { method public java.net.Socket connectSocket(java.net.Socket, java.lang.String, int, java.net.InetAddress, int, org.apache.http.params.HttpParams) throws java.io.IOException; method public java.net.Socket createSocket(); method public static org.apache.http.conn.MultihomePlainSocketFactory getSocketFactory(); method public final boolean isSecure(java.net.Socket) throws java.lang.IllegalArgumentException; } - public abstract interface OperatedClientConnection implements org.apache.http.HttpClientConnection org.apache.http.HttpInetConnection { + public abstract deprecated interface OperatedClientConnection implements org.apache.http.HttpClientConnection org.apache.http.HttpInetConnection { method public abstract java.net.Socket getSocket(); method public abstract org.apache.http.HttpHost getTargetHost(); method public abstract boolean isSecure(); @@ -55300,29 +55333,29 @@ package org.apache.http.conn { package org.apache.http.conn.params { - public abstract interface ConnConnectionPNames { + public abstract deprecated interface ConnConnectionPNames { field public static final java.lang.String MAX_STATUS_LINE_GARBAGE = "http.connection.max-status-line-garbage"; } - public class ConnConnectionParamBean extends org.apache.http.params.HttpAbstractParamBean { + public deprecated class ConnConnectionParamBean extends org.apache.http.params.HttpAbstractParamBean { ctor public ConnConnectionParamBean(org.apache.http.params.HttpParams); method public void setMaxStatusLineGarbage(int); } - public abstract interface ConnManagerPNames { + public abstract deprecated interface ConnManagerPNames { field public static final java.lang.String MAX_CONNECTIONS_PER_ROUTE = "http.conn-manager.max-per-route"; field public static final java.lang.String MAX_TOTAL_CONNECTIONS = "http.conn-manager.max-total"; field public static final java.lang.String TIMEOUT = "http.conn-manager.timeout"; } - public class ConnManagerParamBean extends org.apache.http.params.HttpAbstractParamBean { + public deprecated class ConnManagerParamBean extends org.apache.http.params.HttpAbstractParamBean { ctor public ConnManagerParamBean(org.apache.http.params.HttpParams); method public void setConnectionsPerRoute(org.apache.http.conn.params.ConnPerRouteBean); method public void setMaxTotalConnections(int); method public void setTimeout(long); } - public final class ConnManagerParams implements org.apache.http.conn.params.ConnManagerPNames { + public final deprecated class ConnManagerParams implements org.apache.http.conn.params.ConnManagerPNames { ctor public ConnManagerParams(); method public static org.apache.http.conn.params.ConnPerRoute getMaxConnectionsPerRoute(org.apache.http.params.HttpParams); method public static int getMaxTotalConnections(org.apache.http.params.HttpParams); @@ -55333,11 +55366,11 @@ package org.apache.http.conn.params { field public static final int DEFAULT_MAX_TOTAL_CONNECTIONS = 20; // 0x14 } - public abstract interface ConnPerRoute { + public abstract deprecated interface ConnPerRoute { method public abstract int getMaxForRoute(org.apache.http.conn.routing.HttpRoute); } - public final class ConnPerRouteBean implements org.apache.http.conn.params.ConnPerRoute { + public final deprecated class ConnPerRouteBean implements org.apache.http.conn.params.ConnPerRoute { ctor public ConnPerRouteBean(int); ctor public ConnPerRouteBean(); method public int getDefaultMax(); @@ -55348,20 +55381,20 @@ package org.apache.http.conn.params { field public static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 2; // 0x2 } - public abstract interface ConnRoutePNames { + public abstract deprecated interface ConnRoutePNames { field public static final java.lang.String DEFAULT_PROXY = "http.route.default-proxy"; field public static final java.lang.String FORCED_ROUTE = "http.route.forced-route"; field public static final java.lang.String LOCAL_ADDRESS = "http.route.local-address"; } - public class ConnRouteParamBean extends org.apache.http.params.HttpAbstractParamBean { + public deprecated class ConnRouteParamBean extends org.apache.http.params.HttpAbstractParamBean { ctor public ConnRouteParamBean(org.apache.http.params.HttpParams); method public void setDefaultProxy(org.apache.http.HttpHost); method public void setForcedRoute(org.apache.http.conn.routing.HttpRoute); method public void setLocalAddress(java.net.InetAddress); } - public class ConnRouteParams implements org.apache.http.conn.params.ConnRoutePNames { + public deprecated class ConnRouteParams implements org.apache.http.conn.params.ConnRoutePNames { method public static org.apache.http.HttpHost getDefaultProxy(org.apache.http.params.HttpParams); method public static org.apache.http.conn.routing.HttpRoute getForcedRoute(org.apache.http.params.HttpParams); method public static java.net.InetAddress getLocalAddress(org.apache.http.params.HttpParams); @@ -55376,7 +55409,7 @@ package org.apache.http.conn.params { package org.apache.http.conn.routing { - public class BasicRouteDirector implements org.apache.http.conn.routing.HttpRouteDirector { + public deprecated class BasicRouteDirector implements org.apache.http.conn.routing.HttpRouteDirector { ctor public BasicRouteDirector(); method protected int directStep(org.apache.http.conn.routing.RouteInfo, org.apache.http.conn.routing.RouteInfo); method protected int firstStep(org.apache.http.conn.routing.RouteInfo); @@ -55384,7 +55417,7 @@ package org.apache.http.conn.routing { method protected int proxiedStep(org.apache.http.conn.routing.RouteInfo, org.apache.http.conn.routing.RouteInfo); } - public final class HttpRoute implements java.lang.Cloneable org.apache.http.conn.routing.RouteInfo { + public final deprecated class HttpRoute implements java.lang.Cloneable org.apache.http.conn.routing.RouteInfo { ctor public HttpRoute(org.apache.http.HttpHost, java.net.InetAddress, org.apache.http.HttpHost[], boolean, org.apache.http.conn.routing.RouteInfo.TunnelType, org.apache.http.conn.routing.RouteInfo.LayerType); ctor public HttpRoute(org.apache.http.HttpHost, java.net.InetAddress, org.apache.http.HttpHost, boolean, org.apache.http.conn.routing.RouteInfo.TunnelType, org.apache.http.conn.routing.RouteInfo.LayerType); ctor public HttpRoute(org.apache.http.HttpHost, java.net.InetAddress, boolean); @@ -55406,7 +55439,7 @@ package org.apache.http.conn.routing { method public final java.lang.String toString(); } - public abstract interface HttpRouteDirector { + public abstract deprecated interface HttpRouteDirector { method public abstract int nextStep(org.apache.http.conn.routing.RouteInfo, org.apache.http.conn.routing.RouteInfo); field public static final int COMPLETE = 0; // 0x0 field public static final int CONNECT_PROXY = 2; // 0x2 @@ -55417,11 +55450,11 @@ package org.apache.http.conn.routing { field public static final int UNREACHABLE = -1; // 0xffffffff } - public abstract interface HttpRoutePlanner { + public abstract deprecated interface HttpRoutePlanner { method public abstract org.apache.http.conn.routing.HttpRoute determineRoute(org.apache.http.HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException; } - public abstract interface RouteInfo { + public abstract deprecated interface RouteInfo { method public abstract int getHopCount(); method public abstract org.apache.http.HttpHost getHopTarget(int); method public abstract org.apache.http.conn.routing.RouteInfo.LayerType getLayerType(); @@ -55448,7 +55481,7 @@ package org.apache.http.conn.routing { enum_constant public static final org.apache.http.conn.routing.RouteInfo.TunnelType TUNNELLED; } - public final class RouteTracker implements java.lang.Cloneable org.apache.http.conn.routing.RouteInfo { + public final deprecated class RouteTracker implements java.lang.Cloneable org.apache.http.conn.routing.RouteInfo { ctor public RouteTracker(org.apache.http.HttpHost, java.net.InetAddress); ctor public RouteTracker(org.apache.http.conn.routing.HttpRoute); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; @@ -55478,15 +55511,15 @@ package org.apache.http.conn.routing { package org.apache.http.conn.scheme { - public abstract interface HostNameResolver { + public abstract deprecated interface HostNameResolver { method public abstract java.net.InetAddress resolve(java.lang.String) throws java.io.IOException; } - public abstract interface LayeredSocketFactory implements org.apache.http.conn.scheme.SocketFactory { + public abstract deprecated interface LayeredSocketFactory implements org.apache.http.conn.scheme.SocketFactory { method public abstract java.net.Socket createSocket(java.net.Socket, java.lang.String, int, boolean) throws java.io.IOException, java.net.UnknownHostException; } - public final class PlainSocketFactory implements org.apache.http.conn.scheme.SocketFactory { + public final deprecated class PlainSocketFactory implements org.apache.http.conn.scheme.SocketFactory { ctor public PlainSocketFactory(org.apache.http.conn.scheme.HostNameResolver); ctor public PlainSocketFactory(); method public java.net.Socket connectSocket(java.net.Socket, java.lang.String, int, java.net.InetAddress, int, org.apache.http.params.HttpParams) throws java.io.IOException; @@ -55495,7 +55528,7 @@ package org.apache.http.conn.scheme { method public final boolean isSecure(java.net.Socket) throws java.lang.IllegalArgumentException; } - public final class Scheme { + public final deprecated class Scheme { ctor public Scheme(java.lang.String, org.apache.http.conn.scheme.SocketFactory, int); method public final boolean equals(java.lang.Object); method public final int getDefaultPort(); @@ -55506,7 +55539,7 @@ package org.apache.http.conn.scheme { method public final java.lang.String toString(); } - public final class SchemeRegistry { + public final deprecated class SchemeRegistry { ctor public SchemeRegistry(); method public final synchronized org.apache.http.conn.scheme.Scheme get(java.lang.String); method public final synchronized org.apache.http.conn.scheme.Scheme getScheme(java.lang.String); @@ -55517,7 +55550,7 @@ package org.apache.http.conn.scheme { method public final synchronized org.apache.http.conn.scheme.Scheme unregister(java.lang.String); } - public abstract interface SocketFactory { + public abstract deprecated interface SocketFactory { method public abstract java.net.Socket connectSocket(java.net.Socket, java.lang.String, int, java.net.InetAddress, int, org.apache.http.params.HttpParams) throws org.apache.http.conn.ConnectTimeoutException, java.io.IOException, java.net.UnknownHostException; method public abstract java.net.Socket createSocket() throws java.io.IOException; method public abstract boolean isSecure(java.net.Socket) throws java.lang.IllegalArgumentException; @@ -55527,7 +55560,7 @@ package org.apache.http.conn.scheme { package org.apache.http.conn.ssl { - public abstract class AbstractVerifier implements org.apache.http.conn.ssl.X509HostnameVerifier { + public abstract deprecated class AbstractVerifier implements org.apache.http.conn.ssl.X509HostnameVerifier { ctor public AbstractVerifier(); method public static boolean acceptableCountryWildcard(java.lang.String); method public static int countDots(java.lang.String); @@ -55539,19 +55572,19 @@ package org.apache.http.conn.ssl { method public final void verify(java.lang.String, java.lang.String[], java.lang.String[], boolean) throws javax.net.ssl.SSLException; } - public class AllowAllHostnameVerifier extends org.apache.http.conn.ssl.AbstractVerifier { + public deprecated class AllowAllHostnameVerifier extends org.apache.http.conn.ssl.AbstractVerifier { ctor public AllowAllHostnameVerifier(); method public final java.lang.String toString(); method public final void verify(java.lang.String, java.lang.String[], java.lang.String[]); } - public class BrowserCompatHostnameVerifier extends org.apache.http.conn.ssl.AbstractVerifier { + public deprecated class BrowserCompatHostnameVerifier extends org.apache.http.conn.ssl.AbstractVerifier { ctor public BrowserCompatHostnameVerifier(); method public final java.lang.String toString(); method public final void verify(java.lang.String, java.lang.String[], java.lang.String[]) throws javax.net.ssl.SSLException; } - public class SSLSocketFactory implements org.apache.http.conn.scheme.LayeredSocketFactory { + public deprecated class SSLSocketFactory implements org.apache.http.conn.scheme.LayeredSocketFactory { ctor public SSLSocketFactory(java.lang.String, java.security.KeyStore, java.lang.String, java.security.KeyStore, java.security.SecureRandom, org.apache.http.conn.scheme.HostNameResolver) throws java.security.KeyManagementException, java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException; ctor public SSLSocketFactory(java.security.KeyStore, java.lang.String, java.security.KeyStore) throws java.security.KeyManagementException, java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException; ctor public SSLSocketFactory(java.security.KeyStore, java.lang.String) throws java.security.KeyManagementException, java.security.KeyStoreException, java.security.NoSuchAlgorithmException, java.security.UnrecoverableKeyException; @@ -55571,13 +55604,13 @@ package org.apache.http.conn.ssl { field public static final java.lang.String TLS = "TLS"; } - public class StrictHostnameVerifier extends org.apache.http.conn.ssl.AbstractVerifier { + public deprecated class StrictHostnameVerifier extends org.apache.http.conn.ssl.AbstractVerifier { ctor public StrictHostnameVerifier(); method public final java.lang.String toString(); method public final void verify(java.lang.String, java.lang.String[], java.lang.String[]) throws javax.net.ssl.SSLException; } - public abstract interface X509HostnameVerifier implements javax.net.ssl.HostnameVerifier { + public abstract deprecated interface X509HostnameVerifier implements javax.net.ssl.HostnameVerifier { method public abstract boolean verify(java.lang.String, javax.net.ssl.SSLSession); method public abstract void verify(java.lang.String, javax.net.ssl.SSLSocket) throws java.io.IOException; method public abstract void verify(java.lang.String, java.security.cert.X509Certificate) throws javax.net.ssl.SSLException; @@ -55588,7 +55621,7 @@ package org.apache.http.conn.ssl { package org.apache.http.conn.util { - public class InetAddressUtils { + public deprecated class InetAddressUtils { method public static boolean isIPv4Address(java.lang.String); method public static boolean isIPv6Address(java.lang.String); method public static boolean isIPv6HexCompressedAddress(java.lang.String); @@ -55599,7 +55632,7 @@ package org.apache.http.conn.util { package org.apache.http.cookie { - public abstract interface ClientCookie implements org.apache.http.cookie.Cookie { + public abstract deprecated interface ClientCookie implements org.apache.http.cookie.Cookie { method public abstract boolean containsAttribute(java.lang.String); method public abstract java.lang.String getAttribute(java.lang.String); field public static final java.lang.String COMMENTURL_ATTR = "commenturl"; @@ -55614,7 +55647,7 @@ package org.apache.http.cookie { field public static final java.lang.String VERSION_ATTR = "version"; } - public abstract interface Cookie { + public abstract deprecated interface Cookie { method public abstract java.lang.String getComment(); method public abstract java.lang.String getCommentURL(); method public abstract java.lang.String getDomain(); @@ -55629,18 +55662,18 @@ package org.apache.http.cookie { method public abstract boolean isSecure(); } - public abstract interface CookieAttributeHandler { + public abstract deprecated interface CookieAttributeHandler { method public abstract boolean match(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin); method public abstract void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; method public abstract void validate(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public class CookieIdentityComparator implements java.util.Comparator java.io.Serializable { + public deprecated class CookieIdentityComparator implements java.util.Comparator java.io.Serializable { ctor public CookieIdentityComparator(); method public int compare(org.apache.http.cookie.Cookie, org.apache.http.cookie.Cookie); } - public final class CookieOrigin { + public final deprecated class CookieOrigin { ctor public CookieOrigin(java.lang.String, int, java.lang.String, boolean); method public java.lang.String getHost(); method public java.lang.String getPath(); @@ -55648,12 +55681,12 @@ package org.apache.http.cookie { method public boolean isSecure(); } - public class CookiePathComparator implements java.util.Comparator java.io.Serializable { + public deprecated class CookiePathComparator implements java.util.Comparator java.io.Serializable { ctor public CookiePathComparator(); method public int compare(org.apache.http.cookie.Cookie, org.apache.http.cookie.Cookie); } - public abstract interface CookieSpec { + public abstract deprecated interface CookieSpec { method public abstract java.util.List<org.apache.http.Header> formatCookies(java.util.List<org.apache.http.cookie.Cookie>); method public abstract int getVersion(); method public abstract org.apache.http.Header getVersionHeader(); @@ -55662,11 +55695,11 @@ package org.apache.http.cookie { method public abstract void validate(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public abstract interface CookieSpecFactory { + public abstract deprecated interface CookieSpecFactory { method public abstract org.apache.http.cookie.CookieSpec newInstance(org.apache.http.params.HttpParams); } - public final class CookieSpecRegistry { + public final deprecated class CookieSpecRegistry { ctor public CookieSpecRegistry(); method public synchronized org.apache.http.cookie.CookieSpec getCookieSpec(java.lang.String, org.apache.http.params.HttpParams) throws java.lang.IllegalStateException; method public synchronized org.apache.http.cookie.CookieSpec getCookieSpec(java.lang.String) throws java.lang.IllegalStateException; @@ -55676,20 +55709,20 @@ package org.apache.http.cookie { method public synchronized void unregister(java.lang.String); } - public class MalformedCookieException extends org.apache.http.ProtocolException { + public deprecated class MalformedCookieException extends org.apache.http.ProtocolException { ctor public MalformedCookieException(); ctor public MalformedCookieException(java.lang.String); ctor public MalformedCookieException(java.lang.String, java.lang.Throwable); } - public abstract interface SM { + public abstract deprecated interface SM { field public static final java.lang.String COOKIE = "Cookie"; field public static final java.lang.String COOKIE2 = "Cookie2"; field public static final java.lang.String SET_COOKIE = "Set-Cookie"; field public static final java.lang.String SET_COOKIE2 = "Set-Cookie2"; } - public abstract interface SetCookie implements org.apache.http.cookie.Cookie { + public abstract deprecated interface SetCookie implements org.apache.http.cookie.Cookie { method public abstract void setComment(java.lang.String); method public abstract void setDomain(java.lang.String); method public abstract void setExpiryDate(java.util.Date); @@ -55699,7 +55732,7 @@ package org.apache.http.cookie { method public abstract void setVersion(int); } - public abstract interface SetCookie2 implements org.apache.http.cookie.SetCookie { + public abstract deprecated interface SetCookie2 implements org.apache.http.cookie.SetCookie { method public abstract void setCommentURL(java.lang.String); method public abstract void setDiscard(boolean); method public abstract void setPorts(int[]); @@ -55709,12 +55742,12 @@ package org.apache.http.cookie { package org.apache.http.cookie.params { - public abstract interface CookieSpecPNames { + public abstract deprecated interface CookieSpecPNames { field public static final java.lang.String DATE_PATTERNS = "http.protocol.cookie-datepatterns"; field public static final java.lang.String SINGLE_COOKIE_HEADER = "http.protocol.single-cookie-header"; } - public class CookieSpecParamBean extends org.apache.http.params.HttpAbstractParamBean { + public deprecated class CookieSpecParamBean extends org.apache.http.params.HttpAbstractParamBean { ctor public CookieSpecParamBean(org.apache.http.params.HttpParams); method public void setDatePatterns(java.util.Collection<java.lang.String>); method public void setSingleHeader(boolean); @@ -55724,7 +55757,7 @@ package org.apache.http.cookie.params { package org.apache.http.entity { - public abstract class AbstractHttpEntity implements org.apache.http.HttpEntity { + public abstract deprecated class AbstractHttpEntity implements org.apache.http.HttpEntity { ctor protected AbstractHttpEntity(); method public void consumeContent() throws java.io.IOException, java.lang.UnsupportedOperationException; method public org.apache.http.Header getContentEncoding(); @@ -55740,7 +55773,7 @@ package org.apache.http.entity { field protected org.apache.http.Header contentType; } - public class BasicHttpEntity extends org.apache.http.entity.AbstractHttpEntity { + public deprecated class BasicHttpEntity extends org.apache.http.entity.AbstractHttpEntity { ctor public BasicHttpEntity(); method public java.io.InputStream getContent() throws java.lang.IllegalStateException; method public long getContentLength(); @@ -55751,11 +55784,11 @@ package org.apache.http.entity { method public void writeTo(java.io.OutputStream) throws java.io.IOException; } - public class BufferedHttpEntity extends org.apache.http.entity.HttpEntityWrapper { + public deprecated class BufferedHttpEntity extends org.apache.http.entity.HttpEntityWrapper { ctor public BufferedHttpEntity(org.apache.http.HttpEntity) throws java.io.IOException; } - public class ByteArrayEntity extends org.apache.http.entity.AbstractHttpEntity implements java.lang.Cloneable { + public deprecated class ByteArrayEntity extends org.apache.http.entity.AbstractHttpEntity implements java.lang.Cloneable { ctor public ByteArrayEntity(byte[]); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; method public java.io.InputStream getContent(); @@ -55766,17 +55799,17 @@ package org.apache.http.entity { field protected final byte[] content; } - public abstract interface ContentLengthStrategy { + public abstract deprecated interface ContentLengthStrategy { method public abstract long determineLength(org.apache.http.HttpMessage) throws org.apache.http.HttpException; field public static final int CHUNKED = -2; // 0xfffffffe field public static final int IDENTITY = -1; // 0xffffffff } - public abstract interface ContentProducer { + public abstract deprecated interface ContentProducer { method public abstract void writeTo(java.io.OutputStream) throws java.io.IOException; } - public class EntityTemplate extends org.apache.http.entity.AbstractHttpEntity { + public deprecated class EntityTemplate extends org.apache.http.entity.AbstractHttpEntity { ctor public EntityTemplate(org.apache.http.entity.ContentProducer); method public java.io.InputStream getContent(); method public long getContentLength(); @@ -55785,7 +55818,7 @@ package org.apache.http.entity { method public void writeTo(java.io.OutputStream) throws java.io.IOException; } - public class FileEntity extends org.apache.http.entity.AbstractHttpEntity implements java.lang.Cloneable { + public deprecated class FileEntity extends org.apache.http.entity.AbstractHttpEntity implements java.lang.Cloneable { ctor public FileEntity(java.io.File, java.lang.String); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; method public java.io.InputStream getContent() throws java.io.IOException; @@ -55796,7 +55829,7 @@ package org.apache.http.entity { field protected final java.io.File file; } - public class HttpEntityWrapper implements org.apache.http.HttpEntity { + public deprecated class HttpEntityWrapper implements org.apache.http.HttpEntity { ctor public HttpEntityWrapper(org.apache.http.HttpEntity); method public void consumeContent() throws java.io.IOException; method public java.io.InputStream getContent() throws java.io.IOException; @@ -55810,7 +55843,7 @@ package org.apache.http.entity { field protected org.apache.http.HttpEntity wrappedEntity; } - public class InputStreamEntity extends org.apache.http.entity.AbstractHttpEntity { + public deprecated class InputStreamEntity extends org.apache.http.entity.AbstractHttpEntity { ctor public InputStreamEntity(java.io.InputStream, long); method public java.io.InputStream getContent() throws java.io.IOException; method public long getContentLength(); @@ -55819,7 +55852,7 @@ package org.apache.http.entity { method public void writeTo(java.io.OutputStream) throws java.io.IOException; } - public class SerializableEntity extends org.apache.http.entity.AbstractHttpEntity { + public deprecated class SerializableEntity extends org.apache.http.entity.AbstractHttpEntity { ctor public SerializableEntity(java.io.Serializable, boolean) throws java.io.IOException; method public java.io.InputStream getContent() throws java.io.IOException, java.lang.IllegalStateException; method public long getContentLength(); @@ -55828,7 +55861,7 @@ package org.apache.http.entity { method public void writeTo(java.io.OutputStream) throws java.io.IOException; } - public class StringEntity extends org.apache.http.entity.AbstractHttpEntity implements java.lang.Cloneable { + public deprecated class StringEntity extends org.apache.http.entity.AbstractHttpEntity implements java.lang.Cloneable { ctor public StringEntity(java.lang.String, java.lang.String) throws java.io.UnsupportedEncodingException; ctor public StringEntity(java.lang.String) throws java.io.UnsupportedEncodingException; method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; @@ -55844,7 +55877,7 @@ package org.apache.http.entity { package org.apache.http.impl { - public abstract class AbstractHttpClientConnection implements org.apache.http.HttpClientConnection { + public abstract deprecated class AbstractHttpClientConnection implements org.apache.http.HttpClientConnection { ctor public AbstractHttpClientConnection(); method protected abstract void assertOpen() throws java.lang.IllegalStateException; method protected org.apache.http.impl.entity.EntityDeserializer createEntityDeserializer(); @@ -55864,7 +55897,7 @@ package org.apache.http.impl { method public void sendRequestHeader(org.apache.http.HttpRequest) throws org.apache.http.HttpException, java.io.IOException; } - public abstract class AbstractHttpServerConnection implements org.apache.http.HttpServerConnection { + public abstract deprecated class AbstractHttpServerConnection implements org.apache.http.HttpServerConnection { ctor public AbstractHttpServerConnection(); method protected abstract void assertOpen() throws java.lang.IllegalStateException; method protected org.apache.http.impl.entity.EntityDeserializer createEntityDeserializer(); @@ -55883,24 +55916,24 @@ package org.apache.http.impl { method public void sendResponseHeader(org.apache.http.HttpResponse) throws org.apache.http.HttpException, java.io.IOException; } - public class DefaultConnectionReuseStrategy implements org.apache.http.ConnectionReuseStrategy { + public deprecated class DefaultConnectionReuseStrategy implements org.apache.http.ConnectionReuseStrategy { ctor public DefaultConnectionReuseStrategy(); method protected org.apache.http.TokenIterator createTokenIterator(org.apache.http.HeaderIterator); method public boolean keepAlive(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext); } - public class DefaultHttpClientConnection extends org.apache.http.impl.SocketHttpClientConnection { + public deprecated class DefaultHttpClientConnection extends org.apache.http.impl.SocketHttpClientConnection { ctor public DefaultHttpClientConnection(); method public void bind(java.net.Socket, org.apache.http.params.HttpParams) throws java.io.IOException; } - public class DefaultHttpRequestFactory implements org.apache.http.HttpRequestFactory { + public deprecated class DefaultHttpRequestFactory implements org.apache.http.HttpRequestFactory { ctor public DefaultHttpRequestFactory(); method public org.apache.http.HttpRequest newHttpRequest(org.apache.http.RequestLine) throws org.apache.http.MethodNotSupportedException; method public org.apache.http.HttpRequest newHttpRequest(java.lang.String, java.lang.String) throws org.apache.http.MethodNotSupportedException; } - public class DefaultHttpResponseFactory implements org.apache.http.HttpResponseFactory { + public deprecated class DefaultHttpResponseFactory implements org.apache.http.HttpResponseFactory { ctor public DefaultHttpResponseFactory(org.apache.http.ReasonPhraseCatalog); ctor public DefaultHttpResponseFactory(); method protected java.util.Locale determineLocale(org.apache.http.protocol.HttpContext); @@ -55909,18 +55942,18 @@ package org.apache.http.impl { field protected final org.apache.http.ReasonPhraseCatalog reasonCatalog; } - public class DefaultHttpServerConnection extends org.apache.http.impl.SocketHttpServerConnection { + public deprecated class DefaultHttpServerConnection extends org.apache.http.impl.SocketHttpServerConnection { ctor public DefaultHttpServerConnection(); method public void bind(java.net.Socket, org.apache.http.params.HttpParams) throws java.io.IOException; } - public class EnglishReasonPhraseCatalog implements org.apache.http.ReasonPhraseCatalog { + public deprecated class EnglishReasonPhraseCatalog implements org.apache.http.ReasonPhraseCatalog { ctor protected EnglishReasonPhraseCatalog(); method public java.lang.String getReason(int, java.util.Locale); field public static final org.apache.http.impl.EnglishReasonPhraseCatalog INSTANCE; } - public class HttpConnectionMetricsImpl implements org.apache.http.HttpConnectionMetrics { + public deprecated class HttpConnectionMetricsImpl implements org.apache.http.HttpConnectionMetrics { ctor public HttpConnectionMetricsImpl(org.apache.http.io.HttpTransportMetrics, org.apache.http.io.HttpTransportMetrics); method public java.lang.Object getMetric(java.lang.String); method public long getReceivedBytesCount(); @@ -55937,12 +55970,12 @@ package org.apache.http.impl { field public static final java.lang.String SENT_BYTES_COUNT = "http.sent-bytes-count"; } - public class NoConnectionReuseStrategy implements org.apache.http.ConnectionReuseStrategy { + public deprecated class NoConnectionReuseStrategy implements org.apache.http.ConnectionReuseStrategy { ctor public NoConnectionReuseStrategy(); method public boolean keepAlive(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext); } - public class SocketHttpClientConnection extends org.apache.http.impl.AbstractHttpClientConnection implements org.apache.http.HttpInetConnection { + public deprecated class SocketHttpClientConnection extends org.apache.http.impl.AbstractHttpClientConnection implements org.apache.http.HttpInetConnection { ctor public SocketHttpClientConnection(); method protected void assertNotOpen(); method protected void assertOpen(); @@ -55961,7 +55994,7 @@ package org.apache.http.impl { method public void shutdown() throws java.io.IOException; } - public class SocketHttpServerConnection extends org.apache.http.impl.AbstractHttpServerConnection implements org.apache.http.HttpInetConnection { + public deprecated class SocketHttpServerConnection extends org.apache.http.impl.AbstractHttpServerConnection implements org.apache.http.HttpInetConnection { ctor public SocketHttpServerConnection(); method protected void assertNotOpen(); method protected void assertOpen(); @@ -55984,14 +56017,14 @@ package org.apache.http.impl { package org.apache.http.impl.auth { - public abstract class AuthSchemeBase implements org.apache.http.auth.AuthScheme { + public abstract deprecated class AuthSchemeBase implements org.apache.http.auth.AuthScheme { ctor public AuthSchemeBase(); method public boolean isProxy(); method protected abstract void parseChallenge(org.apache.http.util.CharArrayBuffer, int, int) throws org.apache.http.auth.MalformedChallengeException; method public void processChallenge(org.apache.http.Header) throws org.apache.http.auth.MalformedChallengeException; } - public class BasicScheme extends org.apache.http.impl.auth.RFC2617Scheme { + public deprecated class BasicScheme extends org.apache.http.impl.auth.RFC2617Scheme { ctor public BasicScheme(); method public org.apache.http.Header authenticate(org.apache.http.auth.Credentials, org.apache.http.HttpRequest) throws org.apache.http.auth.AuthenticationException; method public static org.apache.http.Header authenticate(org.apache.http.auth.Credentials, java.lang.String, boolean); @@ -56000,12 +56033,12 @@ package org.apache.http.impl.auth { method public boolean isConnectionBased(); } - public class BasicSchemeFactory implements org.apache.http.auth.AuthSchemeFactory { + public deprecated class BasicSchemeFactory implements org.apache.http.auth.AuthSchemeFactory { ctor public BasicSchemeFactory(); method public org.apache.http.auth.AuthScheme newInstance(org.apache.http.params.HttpParams); } - public class DigestScheme extends org.apache.http.impl.auth.RFC2617Scheme { + public deprecated class DigestScheme extends org.apache.http.impl.auth.RFC2617Scheme { ctor public DigestScheme(); method public org.apache.http.Header authenticate(org.apache.http.auth.Credentials, org.apache.http.HttpRequest) throws org.apache.http.auth.AuthenticationException; method public static java.lang.String createCnonce(); @@ -56015,23 +56048,23 @@ package org.apache.http.impl.auth { method public void overrideParamter(java.lang.String, java.lang.String); } - public class DigestSchemeFactory implements org.apache.http.auth.AuthSchemeFactory { + public deprecated class DigestSchemeFactory implements org.apache.http.auth.AuthSchemeFactory { ctor public DigestSchemeFactory(); method public org.apache.http.auth.AuthScheme newInstance(org.apache.http.params.HttpParams); } - public abstract interface NTLMEngine { + public abstract deprecated interface NTLMEngine { method public abstract java.lang.String generateType1Msg(java.lang.String, java.lang.String) throws org.apache.http.impl.auth.NTLMEngineException; method public abstract java.lang.String generateType3Msg(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) throws org.apache.http.impl.auth.NTLMEngineException; } - public class NTLMEngineException extends org.apache.http.auth.AuthenticationException { + public deprecated class NTLMEngineException extends org.apache.http.auth.AuthenticationException { ctor public NTLMEngineException(); ctor public NTLMEngineException(java.lang.String); ctor public NTLMEngineException(java.lang.String, java.lang.Throwable); } - public class NTLMScheme extends org.apache.http.impl.auth.AuthSchemeBase { + public deprecated class NTLMScheme extends org.apache.http.impl.auth.AuthSchemeBase { ctor public NTLMScheme(org.apache.http.impl.auth.NTLMEngine); method public org.apache.http.Header authenticate(org.apache.http.auth.Credentials, org.apache.http.HttpRequest) throws org.apache.http.auth.AuthenticationException; method public java.lang.String getParameter(java.lang.String); @@ -56042,7 +56075,7 @@ package org.apache.http.impl.auth { method protected void parseChallenge(org.apache.http.util.CharArrayBuffer, int, int) throws org.apache.http.auth.MalformedChallengeException; } - public abstract class RFC2617Scheme extends org.apache.http.impl.auth.AuthSchemeBase { + public abstract deprecated class RFC2617Scheme extends org.apache.http.impl.auth.AuthSchemeBase { ctor public RFC2617Scheme(); method public java.lang.String getParameter(java.lang.String); method protected java.util.Map<java.lang.String, java.lang.String> getParameters(); @@ -56050,7 +56083,7 @@ package org.apache.http.impl.auth { method protected void parseChallenge(org.apache.http.util.CharArrayBuffer, int, int) throws org.apache.http.auth.MalformedChallengeException; } - public class UnsupportedDigestAlgorithmException extends java.lang.RuntimeException { + public deprecated class UnsupportedDigestAlgorithmException extends java.lang.RuntimeException { ctor public UnsupportedDigestAlgorithmException(); ctor public UnsupportedDigestAlgorithmException(java.lang.String); ctor public UnsupportedDigestAlgorithmException(java.lang.String, java.lang.Throwable); @@ -56060,14 +56093,14 @@ package org.apache.http.impl.auth { package org.apache.http.impl.client { - public abstract class AbstractAuthenticationHandler implements org.apache.http.client.AuthenticationHandler { + public abstract deprecated class AbstractAuthenticationHandler implements org.apache.http.client.AuthenticationHandler { ctor public AbstractAuthenticationHandler(); method protected java.util.List<java.lang.String> getAuthPreferences(); method protected java.util.Map<java.lang.String, org.apache.http.Header> parseChallenges(org.apache.http.Header[]) throws org.apache.http.auth.MalformedChallengeException; method public org.apache.http.auth.AuthScheme selectScheme(java.util.Map<java.lang.String, org.apache.http.Header>, org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.auth.AuthenticationException; } - public abstract class AbstractHttpClient implements org.apache.http.client.HttpClient { + public abstract deprecated class AbstractHttpClient implements org.apache.http.client.HttpClient { ctor protected AbstractHttpClient(org.apache.http.conn.ClientConnectionManager, org.apache.http.params.HttpParams); method public synchronized void addRequestInterceptor(org.apache.http.HttpRequestInterceptor); method public synchronized void addRequestInterceptor(org.apache.http.HttpRequestInterceptor, int); @@ -56139,7 +56172,7 @@ package org.apache.http.impl.client { method public synchronized void setUserTokenHandler(org.apache.http.client.UserTokenHandler); } - public class BasicCookieStore implements org.apache.http.client.CookieStore { + public deprecated class BasicCookieStore implements org.apache.http.client.CookieStore { ctor public BasicCookieStore(); method public synchronized void addCookie(org.apache.http.cookie.Cookie); method public synchronized void addCookies(org.apache.http.cookie.Cookie[]); @@ -56148,19 +56181,19 @@ package org.apache.http.impl.client { method public synchronized java.util.List<org.apache.http.cookie.Cookie> getCookies(); } - public class BasicCredentialsProvider implements org.apache.http.client.CredentialsProvider { + public deprecated class BasicCredentialsProvider implements org.apache.http.client.CredentialsProvider { ctor public BasicCredentialsProvider(); method public synchronized void clear(); method public synchronized org.apache.http.auth.Credentials getCredentials(org.apache.http.auth.AuthScope); method public synchronized void setCredentials(org.apache.http.auth.AuthScope, org.apache.http.auth.Credentials); } - public class BasicResponseHandler implements org.apache.http.client.ResponseHandler { + public deprecated class BasicResponseHandler implements org.apache.http.client.ResponseHandler { ctor public BasicResponseHandler(); method public java.lang.String handleResponse(org.apache.http.HttpResponse) throws org.apache.http.client.HttpResponseException, java.io.IOException; } - public class ClientParamsStack extends org.apache.http.params.AbstractHttpParams { + public deprecated class ClientParamsStack extends org.apache.http.params.AbstractHttpParams { ctor public ClientParamsStack(org.apache.http.params.HttpParams, org.apache.http.params.HttpParams, org.apache.http.params.HttpParams, org.apache.http.params.HttpParams); ctor public ClientParamsStack(org.apache.http.impl.client.ClientParamsStack); ctor public ClientParamsStack(org.apache.http.impl.client.ClientParamsStack, org.apache.http.params.HttpParams, org.apache.http.params.HttpParams, org.apache.http.params.HttpParams, org.apache.http.params.HttpParams); @@ -56178,12 +56211,12 @@ package org.apache.http.impl.client { field protected final org.apache.http.params.HttpParams requestParams; } - public class DefaultConnectionKeepAliveStrategy implements org.apache.http.conn.ConnectionKeepAliveStrategy { + public deprecated class DefaultConnectionKeepAliveStrategy implements org.apache.http.conn.ConnectionKeepAliveStrategy { ctor public DefaultConnectionKeepAliveStrategy(); method public long getKeepAliveDuration(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext); } - public class DefaultHttpClient extends org.apache.http.impl.client.AbstractHttpClient { + public deprecated class DefaultHttpClient extends org.apache.http.impl.client.AbstractHttpClient { ctor public DefaultHttpClient(org.apache.http.conn.ClientConnectionManager, org.apache.http.params.HttpParams); ctor public DefaultHttpClient(org.apache.http.params.HttpParams); ctor public DefaultHttpClient(); @@ -56206,7 +56239,7 @@ package org.apache.http.impl.client { method protected org.apache.http.client.UserTokenHandler createUserTokenHandler(); } - public class DefaultHttpRequestRetryHandler implements org.apache.http.client.HttpRequestRetryHandler { + public deprecated class DefaultHttpRequestRetryHandler implements org.apache.http.client.HttpRequestRetryHandler { ctor public DefaultHttpRequestRetryHandler(int, boolean); ctor public DefaultHttpRequestRetryHandler(); method public int getRetryCount(); @@ -56214,19 +56247,19 @@ package org.apache.http.impl.client { method public boolean retryRequest(java.io.IOException, int, org.apache.http.protocol.HttpContext); } - public class DefaultProxyAuthenticationHandler extends org.apache.http.impl.client.AbstractAuthenticationHandler { + public deprecated class DefaultProxyAuthenticationHandler extends org.apache.http.impl.client.AbstractAuthenticationHandler { ctor public DefaultProxyAuthenticationHandler(); method public java.util.Map<java.lang.String, org.apache.http.Header> getChallenges(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.auth.MalformedChallengeException; method public boolean isAuthenticationRequested(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext); } - public class DefaultRedirectHandler implements org.apache.http.client.RedirectHandler { + public deprecated class DefaultRedirectHandler implements org.apache.http.client.RedirectHandler { ctor public DefaultRedirectHandler(); method public java.net.URI getLocationURI(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.ProtocolException; method public boolean isRedirectRequested(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext); } - public class DefaultRequestDirector implements org.apache.http.client.RequestDirector { + public deprecated class DefaultRequestDirector implements org.apache.http.client.RequestDirector { ctor public DefaultRequestDirector(org.apache.http.protocol.HttpRequestExecutor, org.apache.http.conn.ClientConnectionManager, org.apache.http.ConnectionReuseStrategy, org.apache.http.conn.ConnectionKeepAliveStrategy, org.apache.http.conn.routing.HttpRoutePlanner, org.apache.http.protocol.HttpProcessor, org.apache.http.client.HttpRequestRetryHandler, org.apache.http.client.RedirectHandler, org.apache.http.client.AuthenticationHandler, org.apache.http.client.AuthenticationHandler, org.apache.http.client.UserTokenHandler, org.apache.http.params.HttpParams); method protected org.apache.http.HttpRequest createConnectRequest(org.apache.http.conn.routing.HttpRoute, org.apache.http.protocol.HttpContext); method protected boolean createTunnelToProxy(org.apache.http.conn.routing.HttpRoute, int, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; @@ -56249,32 +56282,32 @@ package org.apache.http.impl.client { field protected final org.apache.http.conn.routing.HttpRoutePlanner routePlanner; } - public class DefaultTargetAuthenticationHandler extends org.apache.http.impl.client.AbstractAuthenticationHandler { + public deprecated class DefaultTargetAuthenticationHandler extends org.apache.http.impl.client.AbstractAuthenticationHandler { ctor public DefaultTargetAuthenticationHandler(); method public java.util.Map<java.lang.String, org.apache.http.Header> getChallenges(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.auth.MalformedChallengeException; method public boolean isAuthenticationRequested(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext); } - public class DefaultUserTokenHandler implements org.apache.http.client.UserTokenHandler { + public deprecated class DefaultUserTokenHandler implements org.apache.http.client.UserTokenHandler { ctor public DefaultUserTokenHandler(); method public java.lang.Object getUserToken(org.apache.http.protocol.HttpContext); } - public class EntityEnclosingRequestWrapper extends org.apache.http.impl.client.RequestWrapper implements org.apache.http.HttpEntityEnclosingRequest { + public deprecated class EntityEnclosingRequestWrapper extends org.apache.http.impl.client.RequestWrapper implements org.apache.http.HttpEntityEnclosingRequest { ctor public EntityEnclosingRequestWrapper(org.apache.http.HttpEntityEnclosingRequest) throws org.apache.http.ProtocolException; method public boolean expectContinue(); method public org.apache.http.HttpEntity getEntity(); method public void setEntity(org.apache.http.HttpEntity); } - public class RedirectLocations { + public deprecated class RedirectLocations { ctor public RedirectLocations(); method public void add(java.net.URI); method public boolean contains(java.net.URI); method public boolean remove(java.net.URI); } - public class RequestWrapper extends org.apache.http.message.AbstractHttpMessage implements org.apache.http.client.methods.HttpUriRequest { + public deprecated class RequestWrapper extends org.apache.http.message.AbstractHttpMessage implements org.apache.http.client.methods.HttpUriRequest { ctor public RequestWrapper(org.apache.http.HttpRequest) throws org.apache.http.ProtocolException; method public void abort() throws java.lang.UnsupportedOperationException; method public int getExecCount(); @@ -56292,7 +56325,7 @@ package org.apache.http.impl.client { method public void setURI(java.net.URI); } - public class RoutedRequest { + public deprecated class RoutedRequest { ctor public RoutedRequest(org.apache.http.impl.client.RequestWrapper, org.apache.http.conn.routing.HttpRoute); method public final org.apache.http.impl.client.RequestWrapper getRequest(); method public final org.apache.http.conn.routing.HttpRoute getRoute(); @@ -56300,7 +56333,7 @@ package org.apache.http.impl.client { field protected final org.apache.http.conn.routing.HttpRoute route; } - public class TunnelRefusedException extends org.apache.http.HttpException { + public deprecated class TunnelRefusedException extends org.apache.http.HttpException { ctor public TunnelRefusedException(java.lang.String, org.apache.http.HttpResponse); method public org.apache.http.HttpResponse getResponse(); } @@ -56309,7 +56342,7 @@ package org.apache.http.impl.client { package org.apache.http.impl.conn { - public abstract class AbstractClientConnAdapter implements org.apache.http.conn.ManagedClientConnection { + public abstract deprecated class AbstractClientConnAdapter implements org.apache.http.conn.ManagedClientConnection { ctor protected AbstractClientConnAdapter(org.apache.http.conn.ClientConnectionManager, org.apache.http.conn.OperatedClientConnection); method public void abortConnection(); method protected final void assertNotAborted() throws java.io.InterruptedIOException; @@ -56341,7 +56374,7 @@ package org.apache.http.impl.conn { method public void unmarkReusable(); } - public abstract class AbstractPoolEntry { + public abstract deprecated class AbstractPoolEntry { ctor protected AbstractPoolEntry(org.apache.http.conn.ClientConnectionOperator, org.apache.http.conn.routing.HttpRoute); method public java.lang.Object getState(); method public void layerProtocol(org.apache.http.protocol.HttpContext, org.apache.http.params.HttpParams) throws java.io.IOException; @@ -56357,7 +56390,7 @@ package org.apache.http.impl.conn { field protected volatile org.apache.http.conn.routing.RouteTracker tracker; } - public abstract class AbstractPooledConnAdapter extends org.apache.http.impl.conn.AbstractClientConnAdapter { + public abstract deprecated class AbstractPooledConnAdapter extends org.apache.http.impl.conn.AbstractClientConnAdapter { ctor protected AbstractPooledConnAdapter(org.apache.http.conn.ClientConnectionManager, org.apache.http.impl.conn.AbstractPoolEntry); method protected final void assertAttached(); method public void close() throws java.io.IOException; @@ -56372,7 +56405,7 @@ package org.apache.http.impl.conn { field protected volatile org.apache.http.impl.conn.AbstractPoolEntry poolEntry; } - public class DefaultClientConnection extends org.apache.http.impl.SocketHttpClientConnection implements org.apache.http.conn.OperatedClientConnection { + public deprecated class DefaultClientConnection extends org.apache.http.impl.SocketHttpClientConnection implements org.apache.http.conn.OperatedClientConnection { ctor public DefaultClientConnection(); method public final java.net.Socket getSocket(); method public final org.apache.http.HttpHost getTargetHost(); @@ -56382,7 +56415,7 @@ package org.apache.http.impl.conn { method public void update(java.net.Socket, org.apache.http.HttpHost, boolean, org.apache.http.params.HttpParams) throws java.io.IOException; } - public class DefaultClientConnectionOperator implements org.apache.http.conn.ClientConnectionOperator { + public deprecated class DefaultClientConnectionOperator implements org.apache.http.conn.ClientConnectionOperator { ctor public DefaultClientConnectionOperator(org.apache.http.conn.scheme.SchemeRegistry); method public org.apache.http.conn.OperatedClientConnection createConnection(); method public void openConnection(org.apache.http.conn.OperatedClientConnection, org.apache.http.HttpHost, java.net.InetAddress, org.apache.http.protocol.HttpContext, org.apache.http.params.HttpParams) throws java.io.IOException; @@ -56391,18 +56424,18 @@ package org.apache.http.impl.conn { field protected org.apache.http.conn.scheme.SchemeRegistry schemeRegistry; } - public class DefaultHttpRoutePlanner implements org.apache.http.conn.routing.HttpRoutePlanner { + public deprecated class DefaultHttpRoutePlanner implements org.apache.http.conn.routing.HttpRoutePlanner { ctor public DefaultHttpRoutePlanner(org.apache.http.conn.scheme.SchemeRegistry); method public org.apache.http.conn.routing.HttpRoute determineRoute(org.apache.http.HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException; field protected org.apache.http.conn.scheme.SchemeRegistry schemeRegistry; } - public class DefaultResponseParser extends org.apache.http.impl.io.AbstractMessageParser { + public deprecated class DefaultResponseParser extends org.apache.http.impl.io.AbstractMessageParser { ctor public DefaultResponseParser(org.apache.http.io.SessionInputBuffer, org.apache.http.message.LineParser, org.apache.http.HttpResponseFactory, org.apache.http.params.HttpParams); method protected org.apache.http.HttpMessage parseHead(org.apache.http.io.SessionInputBuffer) throws org.apache.http.HttpException, java.io.IOException; } - public class IdleConnectionHandler { + public deprecated class IdleConnectionHandler { ctor public IdleConnectionHandler(); method public void add(org.apache.http.HttpConnection, long, java.util.concurrent.TimeUnit); method public void closeExpiredConnections(); @@ -56411,7 +56444,7 @@ package org.apache.http.impl.conn { method public void removeAll(); } - public class LoggingSessionInputBuffer implements org.apache.http.io.SessionInputBuffer { + public deprecated class LoggingSessionInputBuffer implements org.apache.http.io.SessionInputBuffer { ctor public LoggingSessionInputBuffer(org.apache.http.io.SessionInputBuffer, org.apache.http.impl.conn.Wire); method public org.apache.http.io.HttpTransportMetrics getMetrics(); method public boolean isDataAvailable(int) throws java.io.IOException; @@ -56422,7 +56455,7 @@ package org.apache.http.impl.conn { method public int readLine(org.apache.http.util.CharArrayBuffer) throws java.io.IOException; } - public class LoggingSessionOutputBuffer implements org.apache.http.io.SessionOutputBuffer { + public deprecated class LoggingSessionOutputBuffer implements org.apache.http.io.SessionOutputBuffer { ctor public LoggingSessionOutputBuffer(org.apache.http.io.SessionOutputBuffer, org.apache.http.impl.conn.Wire); method public void flush() throws java.io.IOException; method public org.apache.http.io.HttpTransportMetrics getMetrics(); @@ -56433,7 +56466,7 @@ package org.apache.http.impl.conn { method public void writeLine(java.lang.String) throws java.io.IOException; } - public class ProxySelectorRoutePlanner implements org.apache.http.conn.routing.HttpRoutePlanner { + public deprecated class ProxySelectorRoutePlanner implements org.apache.http.conn.routing.HttpRoutePlanner { ctor public ProxySelectorRoutePlanner(org.apache.http.conn.scheme.SchemeRegistry, java.net.ProxySelector); method protected java.net.Proxy chooseProxy(java.util.List<java.net.Proxy>, org.apache.http.HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext); method protected org.apache.http.HttpHost determineProxy(org.apache.http.HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException; @@ -56445,7 +56478,7 @@ package org.apache.http.impl.conn { field protected org.apache.http.conn.scheme.SchemeRegistry schemeRegistry; } - public class SingleClientConnManager implements org.apache.http.conn.ClientConnectionManager { + public deprecated class SingleClientConnManager implements org.apache.http.conn.ClientConnectionManager { ctor public SingleClientConnManager(org.apache.http.params.HttpParams, org.apache.http.conn.scheme.SchemeRegistry); method protected final void assertStillUp() throws java.lang.IllegalStateException; method public void closeExpiredConnections(); @@ -56478,7 +56511,7 @@ package org.apache.http.impl.conn { method protected void shutdown() throws java.io.IOException; } - public class Wire { + public deprecated class Wire { ctor public Wire(org.apache.commons.logging.Log); method public boolean enabled(); method public void input(java.io.InputStream) throws java.io.IOException; @@ -56497,7 +56530,7 @@ package org.apache.http.impl.conn { package org.apache.http.impl.conn.tsccm { - public abstract class AbstractConnPool implements org.apache.http.impl.conn.tsccm.RefQueueHandler { + public abstract deprecated class AbstractConnPool implements org.apache.http.impl.conn.tsccm.RefQueueHandler { ctor protected AbstractConnPool(); method protected void closeConnection(org.apache.http.conn.OperatedClientConnection); method public void closeExpiredConnections(); @@ -56518,24 +56551,24 @@ package org.apache.http.impl.conn.tsccm { field protected java.lang.ref.ReferenceQueue refQueue; } - public class BasicPoolEntry extends org.apache.http.impl.conn.AbstractPoolEntry { + public deprecated class BasicPoolEntry extends org.apache.http.impl.conn.AbstractPoolEntry { ctor public BasicPoolEntry(org.apache.http.conn.ClientConnectionOperator, org.apache.http.conn.routing.HttpRoute, java.lang.ref.ReferenceQueue<java.lang.Object>); method protected final org.apache.http.conn.OperatedClientConnection getConnection(); method protected final org.apache.http.conn.routing.HttpRoute getPlannedRoute(); method protected final org.apache.http.impl.conn.tsccm.BasicPoolEntryRef getWeakRef(); } - public class BasicPoolEntryRef extends java.lang.ref.WeakReference { + public deprecated class BasicPoolEntryRef extends java.lang.ref.WeakReference { ctor public BasicPoolEntryRef(org.apache.http.impl.conn.tsccm.BasicPoolEntry, java.lang.ref.ReferenceQueue<java.lang.Object>); method public final org.apache.http.conn.routing.HttpRoute getRoute(); } - public class BasicPooledConnAdapter extends org.apache.http.impl.conn.AbstractPooledConnAdapter { + public deprecated class BasicPooledConnAdapter extends org.apache.http.impl.conn.AbstractPooledConnAdapter { ctor protected BasicPooledConnAdapter(org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager, org.apache.http.impl.conn.AbstractPoolEntry); method protected org.apache.http.impl.conn.AbstractPoolEntry getPoolEntry(); } - public class ConnPoolByRoute extends org.apache.http.impl.conn.tsccm.AbstractConnPool { + public deprecated class ConnPoolByRoute extends org.apache.http.impl.conn.tsccm.AbstractConnPool { ctor public ConnPoolByRoute(org.apache.http.conn.ClientConnectionOperator, org.apache.http.params.HttpParams); method protected org.apache.http.impl.conn.tsccm.BasicPoolEntry createEntry(org.apache.http.impl.conn.tsccm.RouteSpecificPool, org.apache.http.conn.ClientConnectionOperator); method protected java.util.Queue<org.apache.http.impl.conn.tsccm.BasicPoolEntry> createFreeConnQueue(); @@ -56561,16 +56594,16 @@ package org.apache.http.impl.conn.tsccm { field protected java.util.Queue waitingThreads; } - public abstract interface PoolEntryRequest { + public abstract deprecated interface PoolEntryRequest { method public abstract void abortRequest(); method public abstract org.apache.http.impl.conn.tsccm.BasicPoolEntry getPoolEntry(long, java.util.concurrent.TimeUnit) throws org.apache.http.conn.ConnectionPoolTimeoutException, java.lang.InterruptedException; } - public abstract interface RefQueueHandler { + public abstract deprecated interface RefQueueHandler { method public abstract void handleReference(java.lang.ref.Reference<?>); } - public class RefQueueWorker implements java.lang.Runnable { + public deprecated class RefQueueWorker implements java.lang.Runnable { ctor public RefQueueWorker(java.lang.ref.ReferenceQueue<?>, org.apache.http.impl.conn.tsccm.RefQueueHandler); method public void run(); method public void shutdown(); @@ -56579,7 +56612,7 @@ package org.apache.http.impl.conn.tsccm { field protected volatile java.lang.Thread workerThread; } - public class RouteSpecificPool { + public deprecated class RouteSpecificPool { ctor public RouteSpecificPool(org.apache.http.conn.routing.HttpRoute, int); method public org.apache.http.impl.conn.tsccm.BasicPoolEntry allocEntry(java.lang.Object); method public void createdEntry(org.apache.http.impl.conn.tsccm.BasicPoolEntry); @@ -56602,7 +56635,7 @@ package org.apache.http.impl.conn.tsccm { field protected final java.util.Queue waitingThreads; } - public class ThreadSafeClientConnManager implements org.apache.http.conn.ClientConnectionManager { + public deprecated class ThreadSafeClientConnManager implements org.apache.http.conn.ClientConnectionManager { ctor public ThreadSafeClientConnManager(org.apache.http.params.HttpParams, org.apache.http.conn.scheme.SchemeRegistry); method public void closeExpiredConnections(); method public void closeIdleConnections(long, java.util.concurrent.TimeUnit); @@ -56619,7 +56652,7 @@ package org.apache.http.impl.conn.tsccm { field protected org.apache.http.conn.scheme.SchemeRegistry schemeRegistry; } - public class WaitingThread { + public deprecated class WaitingThread { ctor public WaitingThread(java.util.concurrent.locks.Condition, org.apache.http.impl.conn.tsccm.RouteSpecificPool); method public boolean await(java.util.Date) throws java.lang.InterruptedException; method public final java.util.concurrent.locks.Condition getCondition(); @@ -56629,7 +56662,7 @@ package org.apache.http.impl.conn.tsccm { method public void wakeup(); } - public class WaitingThreadAborter { + public deprecated class WaitingThreadAborter { ctor public WaitingThreadAborter(); method public void abort(); method public void setWaitingThread(org.apache.http.impl.conn.tsccm.WaitingThread); @@ -56639,13 +56672,13 @@ package org.apache.http.impl.conn.tsccm { package org.apache.http.impl.cookie { - public abstract class AbstractCookieAttributeHandler implements org.apache.http.cookie.CookieAttributeHandler { + public abstract deprecated class AbstractCookieAttributeHandler implements org.apache.http.cookie.CookieAttributeHandler { ctor public AbstractCookieAttributeHandler(); method public boolean match(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin); method public void validate(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public abstract class AbstractCookieSpec implements org.apache.http.cookie.CookieSpec { + public abstract deprecated class AbstractCookieSpec implements org.apache.http.cookie.CookieSpec { ctor public AbstractCookieSpec(); method protected org.apache.http.cookie.CookieAttributeHandler findAttribHandler(java.lang.String); method protected org.apache.http.cookie.CookieAttributeHandler getAttribHandler(java.lang.String); @@ -56653,7 +56686,7 @@ package org.apache.http.impl.cookie { method public void registerAttribHandler(java.lang.String, org.apache.http.cookie.CookieAttributeHandler); } - public class BasicClientCookie implements org.apache.http.cookie.ClientCookie java.lang.Cloneable org.apache.http.cookie.SetCookie { + public deprecated class BasicClientCookie implements org.apache.http.cookie.ClientCookie java.lang.Cloneable org.apache.http.cookie.SetCookie { ctor public BasicClientCookie(java.lang.String, java.lang.String); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; method public boolean containsAttribute(java.lang.String); @@ -56680,48 +56713,48 @@ package org.apache.http.impl.cookie { method public void setVersion(int); } - public class BasicClientCookie2 extends org.apache.http.impl.cookie.BasicClientCookie implements org.apache.http.cookie.SetCookie2 { + public deprecated class BasicClientCookie2 extends org.apache.http.impl.cookie.BasicClientCookie implements org.apache.http.cookie.SetCookie2 { ctor public BasicClientCookie2(java.lang.String, java.lang.String); method public void setCommentURL(java.lang.String); method public void setDiscard(boolean); method public void setPorts(int[]); } - public class BasicCommentHandler extends org.apache.http.impl.cookie.AbstractCookieAttributeHandler { + public deprecated class BasicCommentHandler extends org.apache.http.impl.cookie.AbstractCookieAttributeHandler { ctor public BasicCommentHandler(); method public void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; } - public class BasicDomainHandler implements org.apache.http.cookie.CookieAttributeHandler { + public deprecated class BasicDomainHandler implements org.apache.http.cookie.CookieAttributeHandler { ctor public BasicDomainHandler(); method public boolean match(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin); method public void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; method public void validate(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public class BasicExpiresHandler extends org.apache.http.impl.cookie.AbstractCookieAttributeHandler { + public deprecated class BasicExpiresHandler extends org.apache.http.impl.cookie.AbstractCookieAttributeHandler { ctor public BasicExpiresHandler(java.lang.String[]); method public void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; } - public class BasicMaxAgeHandler extends org.apache.http.impl.cookie.AbstractCookieAttributeHandler { + public deprecated class BasicMaxAgeHandler extends org.apache.http.impl.cookie.AbstractCookieAttributeHandler { ctor public BasicMaxAgeHandler(); method public void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; } - public class BasicPathHandler implements org.apache.http.cookie.CookieAttributeHandler { + public deprecated class BasicPathHandler implements org.apache.http.cookie.CookieAttributeHandler { ctor public BasicPathHandler(); method public boolean match(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin); method public void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; method public void validate(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public class BasicSecureHandler extends org.apache.http.impl.cookie.AbstractCookieAttributeHandler { + public deprecated class BasicSecureHandler extends org.apache.http.impl.cookie.AbstractCookieAttributeHandler { ctor public BasicSecureHandler(); method public void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; } - public class BestMatchSpec implements org.apache.http.cookie.CookieSpec { + public deprecated class BestMatchSpec implements org.apache.http.cookie.CookieSpec { ctor public BestMatchSpec(java.lang.String[], boolean); ctor public BestMatchSpec(); method public java.util.List<org.apache.http.Header> formatCookies(java.util.List<org.apache.http.cookie.Cookie>); @@ -56732,12 +56765,12 @@ package org.apache.http.impl.cookie { method public void validate(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public class BestMatchSpecFactory implements org.apache.http.cookie.CookieSpecFactory { + public deprecated class BestMatchSpecFactory implements org.apache.http.cookie.CookieSpecFactory { ctor public BestMatchSpecFactory(); method public org.apache.http.cookie.CookieSpec newInstance(org.apache.http.params.HttpParams); } - public class BrowserCompatSpec extends org.apache.http.impl.cookie.CookieSpecBase { + public deprecated class BrowserCompatSpec extends org.apache.http.impl.cookie.CookieSpecBase { ctor public BrowserCompatSpec(java.lang.String[]); ctor public BrowserCompatSpec(); method public java.util.List<org.apache.http.Header> formatCookies(java.util.List<org.apache.http.cookie.Cookie>); @@ -56747,12 +56780,12 @@ package org.apache.http.impl.cookie { field protected static final java.lang.String[] DATE_PATTERNS; } - public class BrowserCompatSpecFactory implements org.apache.http.cookie.CookieSpecFactory { + public deprecated class BrowserCompatSpecFactory implements org.apache.http.cookie.CookieSpecFactory { ctor public BrowserCompatSpecFactory(); method public org.apache.http.cookie.CookieSpec newInstance(org.apache.http.params.HttpParams); } - public abstract class CookieSpecBase extends org.apache.http.impl.cookie.AbstractCookieSpec { + public abstract deprecated class CookieSpecBase extends org.apache.http.impl.cookie.AbstractCookieSpec { ctor public CookieSpecBase(); method protected static java.lang.String getDefaultDomain(org.apache.http.cookie.CookieOrigin); method protected static java.lang.String getDefaultPath(org.apache.http.cookie.CookieOrigin); @@ -56761,12 +56794,12 @@ package org.apache.http.impl.cookie { method public void validate(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public class DateParseException extends java.lang.Exception { + public deprecated class DateParseException extends java.lang.Exception { ctor public DateParseException(); ctor public DateParseException(java.lang.String); } - public final class DateUtils { + public final deprecated class DateUtils { method public static java.lang.String formatDate(java.util.Date); method public static java.lang.String formatDate(java.util.Date, java.lang.String); method public static java.util.Date parseDate(java.lang.String) throws org.apache.http.impl.cookie.DateParseException; @@ -56778,17 +56811,17 @@ package org.apache.http.impl.cookie { field public static final java.lang.String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"; } - public class NetscapeDomainHandler extends org.apache.http.impl.cookie.BasicDomainHandler { + public deprecated class NetscapeDomainHandler extends org.apache.http.impl.cookie.BasicDomainHandler { ctor public NetscapeDomainHandler(); } - public class NetscapeDraftHeaderParser { + public deprecated class NetscapeDraftHeaderParser { ctor public NetscapeDraftHeaderParser(); method public org.apache.http.HeaderElement parseHeader(org.apache.http.util.CharArrayBuffer, org.apache.http.message.ParserCursor) throws org.apache.http.ParseException; field public static final org.apache.http.impl.cookie.NetscapeDraftHeaderParser DEFAULT; } - public class NetscapeDraftSpec extends org.apache.http.impl.cookie.CookieSpecBase { + public deprecated class NetscapeDraftSpec extends org.apache.http.impl.cookie.CookieSpecBase { ctor public NetscapeDraftSpec(java.lang.String[]); ctor public NetscapeDraftSpec(); method public java.util.List<org.apache.http.Header> formatCookies(java.util.List<org.apache.http.cookie.Cookie>); @@ -56798,19 +56831,19 @@ package org.apache.http.impl.cookie { field protected static final java.lang.String EXPIRES_PATTERN = "EEE, dd-MMM-yyyy HH:mm:ss z"; } - public class NetscapeDraftSpecFactory implements org.apache.http.cookie.CookieSpecFactory { + public deprecated class NetscapeDraftSpecFactory implements org.apache.http.cookie.CookieSpecFactory { ctor public NetscapeDraftSpecFactory(); method public org.apache.http.cookie.CookieSpec newInstance(org.apache.http.params.HttpParams); } - public class RFC2109DomainHandler implements org.apache.http.cookie.CookieAttributeHandler { + public deprecated class RFC2109DomainHandler implements org.apache.http.cookie.CookieAttributeHandler { ctor public RFC2109DomainHandler(); method public boolean match(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin); method public void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; method public void validate(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public class RFC2109Spec extends org.apache.http.impl.cookie.CookieSpecBase { + public deprecated class RFC2109Spec extends org.apache.http.impl.cookie.CookieSpecBase { ctor public RFC2109Spec(java.lang.String[], boolean); ctor public RFC2109Spec(); method protected void formatCookieAsVer(org.apache.http.util.CharArrayBuffer, org.apache.http.cookie.Cookie, int); @@ -56821,31 +56854,31 @@ package org.apache.http.impl.cookie { method public java.util.List<org.apache.http.cookie.Cookie> parse(org.apache.http.Header, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public class RFC2109SpecFactory implements org.apache.http.cookie.CookieSpecFactory { + public deprecated class RFC2109SpecFactory implements org.apache.http.cookie.CookieSpecFactory { ctor public RFC2109SpecFactory(); method public org.apache.http.cookie.CookieSpec newInstance(org.apache.http.params.HttpParams); } - public class RFC2109VersionHandler extends org.apache.http.impl.cookie.AbstractCookieAttributeHandler { + public deprecated class RFC2109VersionHandler extends org.apache.http.impl.cookie.AbstractCookieAttributeHandler { ctor public RFC2109VersionHandler(); method public void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; } - public class RFC2965CommentUrlAttributeHandler implements org.apache.http.cookie.CookieAttributeHandler { + public deprecated class RFC2965CommentUrlAttributeHandler implements org.apache.http.cookie.CookieAttributeHandler { ctor public RFC2965CommentUrlAttributeHandler(); method public boolean match(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin); method public void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; method public void validate(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public class RFC2965DiscardAttributeHandler implements org.apache.http.cookie.CookieAttributeHandler { + public deprecated class RFC2965DiscardAttributeHandler implements org.apache.http.cookie.CookieAttributeHandler { ctor public RFC2965DiscardAttributeHandler(); method public boolean match(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin); method public void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; method public void validate(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public class RFC2965DomainAttributeHandler implements org.apache.http.cookie.CookieAttributeHandler { + public deprecated class RFC2965DomainAttributeHandler implements org.apache.http.cookie.CookieAttributeHandler { ctor public RFC2965DomainAttributeHandler(); method public boolean domainMatch(java.lang.String, java.lang.String); method public boolean match(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin); @@ -56853,24 +56886,24 @@ package org.apache.http.impl.cookie { method public void validate(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public class RFC2965PortAttributeHandler implements org.apache.http.cookie.CookieAttributeHandler { + public deprecated class RFC2965PortAttributeHandler implements org.apache.http.cookie.CookieAttributeHandler { ctor public RFC2965PortAttributeHandler(); method public boolean match(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin); method public void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; method public void validate(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin) throws org.apache.http.cookie.MalformedCookieException; } - public class RFC2965Spec extends org.apache.http.impl.cookie.RFC2109Spec { + public deprecated class RFC2965Spec extends org.apache.http.impl.cookie.RFC2109Spec { ctor public RFC2965Spec(); ctor public RFC2965Spec(java.lang.String[], boolean); } - public class RFC2965SpecFactory implements org.apache.http.cookie.CookieSpecFactory { + public deprecated class RFC2965SpecFactory implements org.apache.http.cookie.CookieSpecFactory { ctor public RFC2965SpecFactory(); method public org.apache.http.cookie.CookieSpec newInstance(org.apache.http.params.HttpParams); } - public class RFC2965VersionAttributeHandler implements org.apache.http.cookie.CookieAttributeHandler { + public deprecated class RFC2965VersionAttributeHandler implements org.apache.http.cookie.CookieAttributeHandler { ctor public RFC2965VersionAttributeHandler(); method public boolean match(org.apache.http.cookie.Cookie, org.apache.http.cookie.CookieOrigin); method public void parse(org.apache.http.cookie.SetCookie, java.lang.String) throws org.apache.http.cookie.MalformedCookieException; @@ -56881,24 +56914,24 @@ package org.apache.http.impl.cookie { package org.apache.http.impl.entity { - public class EntityDeserializer { + public deprecated class EntityDeserializer { ctor public EntityDeserializer(org.apache.http.entity.ContentLengthStrategy); method public org.apache.http.HttpEntity deserialize(org.apache.http.io.SessionInputBuffer, org.apache.http.HttpMessage) throws org.apache.http.HttpException, java.io.IOException; method protected org.apache.http.entity.BasicHttpEntity doDeserialize(org.apache.http.io.SessionInputBuffer, org.apache.http.HttpMessage) throws org.apache.http.HttpException, java.io.IOException; } - public class EntitySerializer { + public deprecated class EntitySerializer { ctor public EntitySerializer(org.apache.http.entity.ContentLengthStrategy); method protected java.io.OutputStream doSerialize(org.apache.http.io.SessionOutputBuffer, org.apache.http.HttpMessage) throws org.apache.http.HttpException, java.io.IOException; method public void serialize(org.apache.http.io.SessionOutputBuffer, org.apache.http.HttpMessage, org.apache.http.HttpEntity) throws org.apache.http.HttpException, java.io.IOException; } - public class LaxContentLengthStrategy implements org.apache.http.entity.ContentLengthStrategy { + public deprecated class LaxContentLengthStrategy implements org.apache.http.entity.ContentLengthStrategy { ctor public LaxContentLengthStrategy(); method public long determineLength(org.apache.http.HttpMessage) throws org.apache.http.HttpException; } - public class StrictContentLengthStrategy implements org.apache.http.entity.ContentLengthStrategy { + public deprecated class StrictContentLengthStrategy implements org.apache.http.entity.ContentLengthStrategy { ctor public StrictContentLengthStrategy(); method public long determineLength(org.apache.http.HttpMessage) throws org.apache.http.HttpException; } @@ -56907,7 +56940,7 @@ package org.apache.http.impl.entity { package org.apache.http.impl.io { - public abstract class AbstractMessageParser implements org.apache.http.io.HttpMessageParser { + public abstract deprecated class AbstractMessageParser implements org.apache.http.io.HttpMessageParser { ctor public AbstractMessageParser(org.apache.http.io.SessionInputBuffer, org.apache.http.message.LineParser, org.apache.http.params.HttpParams); method public org.apache.http.HttpMessage parse() throws org.apache.http.HttpException, java.io.IOException; method protected abstract org.apache.http.HttpMessage parseHead(org.apache.http.io.SessionInputBuffer) throws org.apache.http.HttpException, java.io.IOException, org.apache.http.ParseException; @@ -56915,7 +56948,7 @@ package org.apache.http.impl.io { field protected final org.apache.http.message.LineParser lineParser; } - public abstract class AbstractMessageWriter implements org.apache.http.io.HttpMessageWriter { + public abstract deprecated class AbstractMessageWriter implements org.apache.http.io.HttpMessageWriter { ctor public AbstractMessageWriter(org.apache.http.io.SessionOutputBuffer, org.apache.http.message.LineFormatter, org.apache.http.params.HttpParams); method public void write(org.apache.http.HttpMessage) throws org.apache.http.HttpException, java.io.IOException; method protected abstract void writeHeadLine(org.apache.http.HttpMessage) throws java.io.IOException; @@ -56924,7 +56957,7 @@ package org.apache.http.impl.io { field protected final org.apache.http.io.SessionOutputBuffer sessionBuffer; } - public abstract class AbstractSessionInputBuffer implements org.apache.http.io.SessionInputBuffer { + public abstract deprecated class AbstractSessionInputBuffer implements org.apache.http.io.SessionInputBuffer { ctor public AbstractSessionInputBuffer(); method protected int fillBuffer() throws java.io.IOException; method public org.apache.http.io.HttpTransportMetrics getMetrics(); @@ -56937,7 +56970,7 @@ package org.apache.http.impl.io { method public java.lang.String readLine() throws java.io.IOException; } - public abstract class AbstractSessionOutputBuffer implements org.apache.http.io.SessionOutputBuffer { + public abstract deprecated class AbstractSessionOutputBuffer implements org.apache.http.io.SessionOutputBuffer { ctor public AbstractSessionOutputBuffer(); method public void flush() throws java.io.IOException; method protected void flushBuffer() throws java.io.IOException; @@ -56950,13 +56983,13 @@ package org.apache.http.impl.io { method public void writeLine(org.apache.http.util.CharArrayBuffer) throws java.io.IOException; } - public class ChunkedInputStream extends java.io.InputStream { + public deprecated class ChunkedInputStream extends java.io.InputStream { ctor public ChunkedInputStream(org.apache.http.io.SessionInputBuffer); method public org.apache.http.Header[] getFooters(); method public int read() throws java.io.IOException; } - public class ChunkedOutputStream extends java.io.OutputStream { + public deprecated class ChunkedOutputStream extends java.io.OutputStream { ctor public ChunkedOutputStream(org.apache.http.io.SessionOutputBuffer, int) throws java.io.IOException; ctor public ChunkedOutputStream(org.apache.http.io.SessionOutputBuffer) throws java.io.IOException; method public void finish() throws java.io.IOException; @@ -56966,37 +56999,37 @@ package org.apache.http.impl.io { method protected void writeClosingChunk() throws java.io.IOException; } - public class ContentLengthInputStream extends java.io.InputStream { + public deprecated class ContentLengthInputStream extends java.io.InputStream { ctor public ContentLengthInputStream(org.apache.http.io.SessionInputBuffer, long); method public int read() throws java.io.IOException; } - public class ContentLengthOutputStream extends java.io.OutputStream { + public deprecated class ContentLengthOutputStream extends java.io.OutputStream { ctor public ContentLengthOutputStream(org.apache.http.io.SessionOutputBuffer, long); method public void write(int) throws java.io.IOException; } - public class HttpRequestParser extends org.apache.http.impl.io.AbstractMessageParser { + public deprecated class HttpRequestParser extends org.apache.http.impl.io.AbstractMessageParser { ctor public HttpRequestParser(org.apache.http.io.SessionInputBuffer, org.apache.http.message.LineParser, org.apache.http.HttpRequestFactory, org.apache.http.params.HttpParams); method protected org.apache.http.HttpMessage parseHead(org.apache.http.io.SessionInputBuffer) throws org.apache.http.HttpException, java.io.IOException, org.apache.http.ParseException; } - public class HttpRequestWriter extends org.apache.http.impl.io.AbstractMessageWriter { + public deprecated class HttpRequestWriter extends org.apache.http.impl.io.AbstractMessageWriter { ctor public HttpRequestWriter(org.apache.http.io.SessionOutputBuffer, org.apache.http.message.LineFormatter, org.apache.http.params.HttpParams); method protected void writeHeadLine(org.apache.http.HttpMessage) throws java.io.IOException; } - public class HttpResponseParser extends org.apache.http.impl.io.AbstractMessageParser { + public deprecated class HttpResponseParser extends org.apache.http.impl.io.AbstractMessageParser { ctor public HttpResponseParser(org.apache.http.io.SessionInputBuffer, org.apache.http.message.LineParser, org.apache.http.HttpResponseFactory, org.apache.http.params.HttpParams); method protected org.apache.http.HttpMessage parseHead(org.apache.http.io.SessionInputBuffer) throws org.apache.http.HttpException, java.io.IOException, org.apache.http.ParseException; } - public class HttpResponseWriter extends org.apache.http.impl.io.AbstractMessageWriter { + public deprecated class HttpResponseWriter extends org.apache.http.impl.io.AbstractMessageWriter { ctor public HttpResponseWriter(org.apache.http.io.SessionOutputBuffer, org.apache.http.message.LineFormatter, org.apache.http.params.HttpParams); method protected void writeHeadLine(org.apache.http.HttpMessage) throws java.io.IOException; } - public class HttpTransportMetricsImpl implements org.apache.http.io.HttpTransportMetrics { + public deprecated class HttpTransportMetricsImpl implements org.apache.http.io.HttpTransportMetrics { ctor public HttpTransportMetricsImpl(); method public long getBytesTransferred(); method public void incrementBytesTransferred(long); @@ -57004,22 +57037,22 @@ package org.apache.http.impl.io { method public void setBytesTransferred(long); } - public class IdentityInputStream extends java.io.InputStream { + public deprecated class IdentityInputStream extends java.io.InputStream { ctor public IdentityInputStream(org.apache.http.io.SessionInputBuffer); method public int read() throws java.io.IOException; } - public class IdentityOutputStream extends java.io.OutputStream { + public deprecated class IdentityOutputStream extends java.io.OutputStream { ctor public IdentityOutputStream(org.apache.http.io.SessionOutputBuffer); method public void write(int) throws java.io.IOException; } - public class SocketInputBuffer extends org.apache.http.impl.io.AbstractSessionInputBuffer { + public deprecated class SocketInputBuffer extends org.apache.http.impl.io.AbstractSessionInputBuffer { ctor public SocketInputBuffer(java.net.Socket, int, org.apache.http.params.HttpParams) throws java.io.IOException; method public boolean isDataAvailable(int) throws java.io.IOException; } - public class SocketOutputBuffer extends org.apache.http.impl.io.AbstractSessionOutputBuffer { + public deprecated class SocketOutputBuffer extends org.apache.http.impl.io.AbstractSessionOutputBuffer { ctor public SocketOutputBuffer(java.net.Socket, int, org.apache.http.params.HttpParams) throws java.io.IOException; } @@ -57027,20 +57060,20 @@ package org.apache.http.impl.io { package org.apache.http.io { - public abstract interface HttpMessageParser { + public abstract deprecated interface HttpMessageParser { method public abstract org.apache.http.HttpMessage parse() throws org.apache.http.HttpException, java.io.IOException; } - public abstract interface HttpMessageWriter { + public abstract deprecated interface HttpMessageWriter { method public abstract void write(org.apache.http.HttpMessage) throws org.apache.http.HttpException, java.io.IOException; } - public abstract interface HttpTransportMetrics { + public abstract deprecated interface HttpTransportMetrics { method public abstract long getBytesTransferred(); method public abstract void reset(); } - public abstract interface SessionInputBuffer { + public abstract deprecated interface SessionInputBuffer { method public abstract org.apache.http.io.HttpTransportMetrics getMetrics(); method public abstract boolean isDataAvailable(int) throws java.io.IOException; method public abstract int read(byte[], int, int) throws java.io.IOException; @@ -57050,7 +57083,7 @@ package org.apache.http.io { method public abstract java.lang.String readLine() throws java.io.IOException; } - public abstract interface SessionOutputBuffer { + public abstract deprecated interface SessionOutputBuffer { method public abstract void flush() throws java.io.IOException; method public abstract org.apache.http.io.HttpTransportMetrics getMetrics(); method public abstract void write(byte[], int, int) throws java.io.IOException; @@ -57064,7 +57097,7 @@ package org.apache.http.io { package org.apache.http.message { - public abstract class AbstractHttpMessage implements org.apache.http.HttpMessage { + public abstract deprecated class AbstractHttpMessage implements org.apache.http.HttpMessage { ctor protected AbstractHttpMessage(org.apache.http.params.HttpParams); ctor protected AbstractHttpMessage(); method public void addHeader(org.apache.http.Header); @@ -57087,7 +57120,7 @@ package org.apache.http.message { field protected org.apache.http.params.HttpParams params; } - public class BasicHeader implements java.lang.Cloneable org.apache.http.Header { + public deprecated class BasicHeader implements java.lang.Cloneable org.apache.http.Header { ctor public BasicHeader(java.lang.String, java.lang.String); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; method public org.apache.http.HeaderElement[] getElements() throws org.apache.http.ParseException; @@ -57095,7 +57128,7 @@ package org.apache.http.message { method public java.lang.String getValue(); } - public class BasicHeaderElement implements java.lang.Cloneable org.apache.http.HeaderElement { + public deprecated class BasicHeaderElement implements java.lang.Cloneable org.apache.http.HeaderElement { ctor public BasicHeaderElement(java.lang.String, java.lang.String, org.apache.http.NameValuePair[]); ctor public BasicHeaderElement(java.lang.String, java.lang.String); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; @@ -57107,7 +57140,7 @@ package org.apache.http.message { method public java.lang.String getValue(); } - public class BasicHeaderElementIterator implements org.apache.http.HeaderElementIterator { + public deprecated class BasicHeaderElementIterator implements org.apache.http.HeaderElementIterator { ctor public BasicHeaderElementIterator(org.apache.http.HeaderIterator, org.apache.http.message.HeaderValueParser); ctor public BasicHeaderElementIterator(org.apache.http.HeaderIterator); method public boolean hasNext(); @@ -57116,7 +57149,7 @@ package org.apache.http.message { method public void remove() throws java.lang.UnsupportedOperationException; } - public class BasicHeaderIterator implements org.apache.http.HeaderIterator { + public deprecated class BasicHeaderIterator implements org.apache.http.HeaderIterator { ctor public BasicHeaderIterator(org.apache.http.Header[], java.lang.String); method protected boolean filterHeader(int); method protected int findNext(int); @@ -57129,7 +57162,7 @@ package org.apache.http.message { field protected java.lang.String headerName; } - public class BasicHeaderValueFormatter implements org.apache.http.message.HeaderValueFormatter { + public deprecated class BasicHeaderValueFormatter implements org.apache.http.message.HeaderValueFormatter { ctor public BasicHeaderValueFormatter(); method protected void doFormatValue(org.apache.http.util.CharArrayBuffer, java.lang.String, boolean); method protected int estimateElementsLen(org.apache.http.HeaderElement[]); @@ -57151,7 +57184,7 @@ package org.apache.http.message { field public static final java.lang.String UNSAFE_CHARS = "\"\\"; } - public class BasicHeaderValueParser implements org.apache.http.message.HeaderValueParser { + public deprecated class BasicHeaderValueParser implements org.apache.http.message.HeaderValueParser { ctor public BasicHeaderValueParser(); method protected org.apache.http.HeaderElement createHeaderElement(java.lang.String, java.lang.String, org.apache.http.NameValuePair[]); method protected org.apache.http.NameValuePair createNameValuePair(java.lang.String, java.lang.String); @@ -57167,7 +57200,7 @@ package org.apache.http.message { field public static final org.apache.http.message.BasicHeaderValueParser DEFAULT; } - public class BasicHttpEntityEnclosingRequest extends org.apache.http.message.BasicHttpRequest implements org.apache.http.HttpEntityEnclosingRequest { + public deprecated class BasicHttpEntityEnclosingRequest extends org.apache.http.message.BasicHttpRequest implements org.apache.http.HttpEntityEnclosingRequest { ctor public BasicHttpEntityEnclosingRequest(java.lang.String, java.lang.String); ctor public BasicHttpEntityEnclosingRequest(java.lang.String, java.lang.String, org.apache.http.ProtocolVersion); ctor public BasicHttpEntityEnclosingRequest(org.apache.http.RequestLine); @@ -57176,7 +57209,7 @@ package org.apache.http.message { method public void setEntity(org.apache.http.HttpEntity); } - public class BasicHttpRequest extends org.apache.http.message.AbstractHttpMessage implements org.apache.http.HttpRequest { + public deprecated class BasicHttpRequest extends org.apache.http.message.AbstractHttpMessage implements org.apache.http.HttpRequest { ctor public BasicHttpRequest(java.lang.String, java.lang.String); ctor public BasicHttpRequest(java.lang.String, java.lang.String, org.apache.http.ProtocolVersion); ctor public BasicHttpRequest(org.apache.http.RequestLine); @@ -57184,7 +57217,7 @@ package org.apache.http.message { method public org.apache.http.RequestLine getRequestLine(); } - public class BasicHttpResponse extends org.apache.http.message.AbstractHttpMessage implements org.apache.http.HttpResponse { + public deprecated class BasicHttpResponse extends org.apache.http.message.AbstractHttpMessage implements org.apache.http.HttpResponse { ctor public BasicHttpResponse(org.apache.http.StatusLine, org.apache.http.ReasonPhraseCatalog, java.util.Locale); ctor public BasicHttpResponse(org.apache.http.StatusLine); ctor public BasicHttpResponse(org.apache.http.ProtocolVersion, int, java.lang.String); @@ -57202,7 +57235,7 @@ package org.apache.http.message { method public void setStatusLine(org.apache.http.ProtocolVersion, int, java.lang.String); } - public class BasicLineFormatter implements org.apache.http.message.LineFormatter { + public deprecated class BasicLineFormatter implements org.apache.http.message.LineFormatter { ctor public BasicLineFormatter(); method public org.apache.http.util.CharArrayBuffer appendProtocolVersion(org.apache.http.util.CharArrayBuffer, org.apache.http.ProtocolVersion); method protected void doFormatHeader(org.apache.http.util.CharArrayBuffer, org.apache.http.Header); @@ -57220,7 +57253,7 @@ package org.apache.http.message { field public static final org.apache.http.message.BasicLineFormatter DEFAULT; } - public class BasicLineParser implements org.apache.http.message.LineParser { + public deprecated class BasicLineParser implements org.apache.http.message.LineParser { ctor public BasicLineParser(org.apache.http.ProtocolVersion); ctor public BasicLineParser(); method protected org.apache.http.ProtocolVersion createProtocolVersion(int, int); @@ -57240,7 +57273,7 @@ package org.apache.http.message { field protected final org.apache.http.ProtocolVersion protocol; } - public class BasicListHeaderIterator implements org.apache.http.HeaderIterator { + public deprecated class BasicListHeaderIterator implements org.apache.http.HeaderIterator { ctor public BasicListHeaderIterator(java.util.List, java.lang.String); method protected boolean filterHeader(int); method protected int findNext(int); @@ -57254,14 +57287,14 @@ package org.apache.http.message { field protected int lastIndex; } - public class BasicNameValuePair implements java.lang.Cloneable org.apache.http.NameValuePair { + public deprecated class BasicNameValuePair implements java.lang.Cloneable org.apache.http.NameValuePair { ctor public BasicNameValuePair(java.lang.String, java.lang.String); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; method public java.lang.String getName(); method public java.lang.String getValue(); } - public class BasicRequestLine implements java.lang.Cloneable org.apache.http.RequestLine { + public deprecated class BasicRequestLine implements java.lang.Cloneable org.apache.http.RequestLine { ctor public BasicRequestLine(java.lang.String, java.lang.String, org.apache.http.ProtocolVersion); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; method public java.lang.String getMethod(); @@ -57269,7 +57302,7 @@ package org.apache.http.message { method public java.lang.String getUri(); } - public class BasicStatusLine implements java.lang.Cloneable org.apache.http.StatusLine { + public deprecated class BasicStatusLine implements java.lang.Cloneable org.apache.http.StatusLine { ctor public BasicStatusLine(org.apache.http.ProtocolVersion, int, java.lang.String); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; method public org.apache.http.ProtocolVersion getProtocolVersion(); @@ -57277,7 +57310,7 @@ package org.apache.http.message { method public int getStatusCode(); } - public class BasicTokenIterator implements org.apache.http.TokenIterator { + public deprecated class BasicTokenIterator implements org.apache.http.TokenIterator { ctor public BasicTokenIterator(org.apache.http.HeaderIterator); method protected java.lang.String createToken(java.lang.String, int, int); method protected int findNext(int) throws org.apache.http.ParseException; @@ -57299,7 +57332,7 @@ package org.apache.http.message { field protected int searchPos; } - public class BufferedHeader implements java.lang.Cloneable org.apache.http.FormattedHeader { + public deprecated class BufferedHeader implements java.lang.Cloneable org.apache.http.FormattedHeader { ctor public BufferedHeader(org.apache.http.util.CharArrayBuffer) throws org.apache.http.ParseException; method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; method public org.apache.http.util.CharArrayBuffer getBuffer(); @@ -57309,7 +57342,7 @@ package org.apache.http.message { method public int getValuePos(); } - public class HeaderGroup implements java.lang.Cloneable { + public deprecated class HeaderGroup implements java.lang.Cloneable { ctor public HeaderGroup(); method public void addHeader(org.apache.http.Header); method public void clear(); @@ -57328,28 +57361,28 @@ package org.apache.http.message { method public void updateHeader(org.apache.http.Header); } - public abstract interface HeaderValueFormatter { + public abstract deprecated interface HeaderValueFormatter { method public abstract org.apache.http.util.CharArrayBuffer formatElements(org.apache.http.util.CharArrayBuffer, org.apache.http.HeaderElement[], boolean); method public abstract org.apache.http.util.CharArrayBuffer formatHeaderElement(org.apache.http.util.CharArrayBuffer, org.apache.http.HeaderElement, boolean); method public abstract org.apache.http.util.CharArrayBuffer formatNameValuePair(org.apache.http.util.CharArrayBuffer, org.apache.http.NameValuePair, boolean); method public abstract org.apache.http.util.CharArrayBuffer formatParameters(org.apache.http.util.CharArrayBuffer, org.apache.http.NameValuePair[], boolean); } - public abstract interface HeaderValueParser { + public abstract deprecated interface HeaderValueParser { method public abstract org.apache.http.HeaderElement[] parseElements(org.apache.http.util.CharArrayBuffer, org.apache.http.message.ParserCursor) throws org.apache.http.ParseException; method public abstract org.apache.http.HeaderElement parseHeaderElement(org.apache.http.util.CharArrayBuffer, org.apache.http.message.ParserCursor) throws org.apache.http.ParseException; method public abstract org.apache.http.NameValuePair parseNameValuePair(org.apache.http.util.CharArrayBuffer, org.apache.http.message.ParserCursor) throws org.apache.http.ParseException; method public abstract org.apache.http.NameValuePair[] parseParameters(org.apache.http.util.CharArrayBuffer, org.apache.http.message.ParserCursor) throws org.apache.http.ParseException; } - public abstract interface LineFormatter { + public abstract deprecated interface LineFormatter { method public abstract org.apache.http.util.CharArrayBuffer appendProtocolVersion(org.apache.http.util.CharArrayBuffer, org.apache.http.ProtocolVersion); method public abstract org.apache.http.util.CharArrayBuffer formatHeader(org.apache.http.util.CharArrayBuffer, org.apache.http.Header); method public abstract org.apache.http.util.CharArrayBuffer formatRequestLine(org.apache.http.util.CharArrayBuffer, org.apache.http.RequestLine); method public abstract org.apache.http.util.CharArrayBuffer formatStatusLine(org.apache.http.util.CharArrayBuffer, org.apache.http.StatusLine); } - public abstract interface LineParser { + public abstract deprecated interface LineParser { method public abstract boolean hasProtocolVersion(org.apache.http.util.CharArrayBuffer, org.apache.http.message.ParserCursor); method public abstract org.apache.http.Header parseHeader(org.apache.http.util.CharArrayBuffer) throws org.apache.http.ParseException; method public abstract org.apache.http.ProtocolVersion parseProtocolVersion(org.apache.http.util.CharArrayBuffer, org.apache.http.message.ParserCursor) throws org.apache.http.ParseException; @@ -57357,7 +57390,7 @@ package org.apache.http.message { method public abstract org.apache.http.StatusLine parseStatusLine(org.apache.http.util.CharArrayBuffer, org.apache.http.message.ParserCursor) throws org.apache.http.ParseException; } - public class ParserCursor { + public deprecated class ParserCursor { ctor public ParserCursor(int, int); method public boolean atEnd(); method public int getLowerBound(); @@ -57370,7 +57403,7 @@ package org.apache.http.message { package org.apache.http.params { - public abstract class AbstractHttpParams implements org.apache.http.params.HttpParams { + public abstract deprecated class AbstractHttpParams implements org.apache.http.params.HttpParams { ctor protected AbstractHttpParams(); method public boolean getBooleanParameter(java.lang.String, boolean); method public double getDoubleParameter(java.lang.String, double); @@ -57384,7 +57417,7 @@ package org.apache.http.params { method public org.apache.http.params.HttpParams setLongParameter(java.lang.String, long); } - public final class BasicHttpParams extends org.apache.http.params.AbstractHttpParams implements java.lang.Cloneable java.io.Serializable { + public final deprecated class BasicHttpParams extends org.apache.http.params.AbstractHttpParams implements java.lang.Cloneable java.io.Serializable { ctor public BasicHttpParams(); method public void clear(); method public java.lang.Object clone() throws java.lang.CloneNotSupportedException; @@ -57398,7 +57431,7 @@ package org.apache.http.params { method public void setParameters(java.lang.String[], java.lang.Object); } - public abstract interface CoreConnectionPNames { + public abstract deprecated interface CoreConnectionPNames { field public static final java.lang.String CONNECTION_TIMEOUT = "http.connection.timeout"; field public static final java.lang.String MAX_HEADER_COUNT = "http.connection.max-header-count"; field public static final java.lang.String MAX_LINE_LENGTH = "http.connection.max-line-length"; @@ -57409,7 +57442,7 @@ package org.apache.http.params { field public static final java.lang.String TCP_NODELAY = "http.tcp.nodelay"; } - public abstract interface CoreProtocolPNames { + public abstract deprecated interface CoreProtocolPNames { field public static final java.lang.String HTTP_CONTENT_CHARSET = "http.protocol.content-charset"; field public static final java.lang.String HTTP_ELEMENT_CHARSET = "http.protocol.element-charset"; field public static final java.lang.String ORIGIN_SERVER = "http.origin-server"; @@ -57420,7 +57453,7 @@ package org.apache.http.params { field public static final java.lang.String WAIT_FOR_CONTINUE = "http.protocol.wait-for-continue"; } - public final class DefaultedHttpParams extends org.apache.http.params.AbstractHttpParams { + public final deprecated class DefaultedHttpParams extends org.apache.http.params.AbstractHttpParams { ctor public DefaultedHttpParams(org.apache.http.params.HttpParams, org.apache.http.params.HttpParams); method public org.apache.http.params.HttpParams copy(); method public org.apache.http.params.HttpParams getDefaults(); @@ -57429,12 +57462,12 @@ package org.apache.http.params { method public org.apache.http.params.HttpParams setParameter(java.lang.String, java.lang.Object); } - public abstract class HttpAbstractParamBean { + public abstract deprecated class HttpAbstractParamBean { ctor public HttpAbstractParamBean(org.apache.http.params.HttpParams); field protected final org.apache.http.params.HttpParams params; } - public class HttpConnectionParamBean extends org.apache.http.params.HttpAbstractParamBean { + public deprecated class HttpConnectionParamBean extends org.apache.http.params.HttpAbstractParamBean { ctor public HttpConnectionParamBean(org.apache.http.params.HttpParams); method public void setConnectionTimeout(int); method public void setLinger(int); @@ -57444,7 +57477,7 @@ package org.apache.http.params { method public void setTcpNoDelay(boolean); } - public final class HttpConnectionParams implements org.apache.http.params.CoreConnectionPNames { + public final deprecated class HttpConnectionParams implements org.apache.http.params.CoreConnectionPNames { method public static int getConnectionTimeout(org.apache.http.params.HttpParams); method public static int getLinger(org.apache.http.params.HttpParams); method public static int getSoTimeout(org.apache.http.params.HttpParams); @@ -57459,7 +57492,7 @@ package org.apache.http.params { method public static void setTcpNoDelay(org.apache.http.params.HttpParams, boolean); } - public abstract interface HttpParams { + public abstract deprecated interface HttpParams { method public abstract org.apache.http.params.HttpParams copy(); method public abstract boolean getBooleanParameter(java.lang.String, boolean); method public abstract double getDoubleParameter(java.lang.String, double); @@ -57476,7 +57509,7 @@ package org.apache.http.params { method public abstract org.apache.http.params.HttpParams setParameter(java.lang.String, java.lang.Object); } - public class HttpProtocolParamBean extends org.apache.http.params.HttpAbstractParamBean { + public deprecated class HttpProtocolParamBean extends org.apache.http.params.HttpAbstractParamBean { ctor public HttpProtocolParamBean(org.apache.http.params.HttpParams); method public void setContentCharset(java.lang.String); method public void setHttpElementCharset(java.lang.String); @@ -57485,7 +57518,7 @@ package org.apache.http.params { method public void setVersion(org.apache.http.HttpVersion); } - public final class HttpProtocolParams implements org.apache.http.params.CoreProtocolPNames { + public final deprecated class HttpProtocolParams implements org.apache.http.params.CoreProtocolPNames { method public static java.lang.String getContentCharset(org.apache.http.params.HttpParams); method public static java.lang.String getHttpElementCharset(org.apache.http.params.HttpParams); method public static java.lang.String getUserAgent(org.apache.http.params.HttpParams); @@ -57502,7 +57535,7 @@ package org.apache.http.params { package org.apache.http.protocol { - public class BasicHttpContext implements org.apache.http.protocol.HttpContext { + public deprecated class BasicHttpContext implements org.apache.http.protocol.HttpContext { ctor public BasicHttpContext(); ctor public BasicHttpContext(org.apache.http.protocol.HttpContext); method public java.lang.Object getAttribute(java.lang.String); @@ -57510,7 +57543,7 @@ package org.apache.http.protocol { method public void setAttribute(java.lang.String, java.lang.Object); } - public final class BasicHttpProcessor implements java.lang.Cloneable org.apache.http.protocol.HttpProcessor org.apache.http.protocol.HttpRequestInterceptorList org.apache.http.protocol.HttpResponseInterceptorList { + public final deprecated class BasicHttpProcessor implements java.lang.Cloneable org.apache.http.protocol.HttpProcessor org.apache.http.protocol.HttpRequestInterceptorList org.apache.http.protocol.HttpResponseInterceptorList { ctor public BasicHttpProcessor(); method public final void addInterceptor(org.apache.http.HttpRequestInterceptor); method public final void addInterceptor(org.apache.http.HttpRequestInterceptor, int); @@ -57539,7 +57572,7 @@ package org.apache.http.protocol { field protected java.util.List responseInterceptors; } - public final class DefaultedHttpContext implements org.apache.http.protocol.HttpContext { + public final deprecated class DefaultedHttpContext implements org.apache.http.protocol.HttpContext { ctor public DefaultedHttpContext(org.apache.http.protocol.HttpContext, org.apache.http.protocol.HttpContext); method public java.lang.Object getAttribute(java.lang.String); method public org.apache.http.protocol.HttpContext getDefaults(); @@ -57547,7 +57580,7 @@ package org.apache.http.protocol { method public void setAttribute(java.lang.String, java.lang.Object); } - public abstract interface ExecutionContext { + public abstract deprecated interface ExecutionContext { field public static final java.lang.String HTTP_CONNECTION = "http.connection"; field public static final java.lang.String HTTP_PROXY_HOST = "http.proxy_host"; field public static final java.lang.String HTTP_REQUEST = "http.request"; @@ -57556,7 +57589,7 @@ package org.apache.http.protocol { field public static final java.lang.String HTTP_TARGET_HOST = "http.target_host"; } - public final class HTTP { + public final deprecated class HTTP { method public static boolean isWhitespace(char); field public static final java.lang.String ASCII = "ASCII"; field public static final java.lang.String CHARSET_PARAM = "; charset="; @@ -57590,28 +57623,28 @@ package org.apache.http.protocol { field public static final java.lang.String UTF_8 = "UTF-8"; } - public abstract interface HttpContext { + public abstract deprecated interface HttpContext { method public abstract java.lang.Object getAttribute(java.lang.String); method public abstract java.lang.Object removeAttribute(java.lang.String); method public abstract void setAttribute(java.lang.String, java.lang.Object); field public static final java.lang.String RESERVED_PREFIX = "http."; } - public class HttpDateGenerator { + public deprecated class HttpDateGenerator { ctor public HttpDateGenerator(); method public synchronized java.lang.String getCurrentDate(); field public static final java.util.TimeZone GMT; field public static final java.lang.String PATTERN_RFC1123 = "EEE, dd MMM yyyy HH:mm:ss zzz"; } - public abstract interface HttpExpectationVerifier { + public abstract deprecated interface HttpExpectationVerifier { method public abstract void verify(org.apache.http.HttpRequest, org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException; } - public abstract interface HttpProcessor implements org.apache.http.HttpRequestInterceptor org.apache.http.HttpResponseInterceptor { + public abstract deprecated interface HttpProcessor implements org.apache.http.HttpRequestInterceptor org.apache.http.HttpResponseInterceptor { } - public class HttpRequestExecutor { + public deprecated class HttpRequestExecutor { ctor public HttpRequestExecutor(); method protected boolean canResponseHaveBody(org.apache.http.HttpRequest, org.apache.http.HttpResponse); method protected org.apache.http.HttpResponse doReceiveResponse(org.apache.http.HttpRequest, org.apache.http.HttpClientConnection, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; @@ -57621,11 +57654,11 @@ package org.apache.http.protocol { method public void preProcess(org.apache.http.HttpRequest, org.apache.http.protocol.HttpProcessor, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public abstract interface HttpRequestHandler { + public abstract deprecated interface HttpRequestHandler { method public abstract void handle(org.apache.http.HttpRequest, org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class HttpRequestHandlerRegistry implements org.apache.http.protocol.HttpRequestHandlerResolver { + public deprecated class HttpRequestHandlerRegistry implements org.apache.http.protocol.HttpRequestHandlerResolver { ctor public HttpRequestHandlerRegistry(); method public org.apache.http.protocol.HttpRequestHandler lookup(java.lang.String); method protected deprecated boolean matchUriRequestPattern(java.lang.String, java.lang.String); @@ -57634,11 +57667,11 @@ package org.apache.http.protocol { method public void unregister(java.lang.String); } - public abstract interface HttpRequestHandlerResolver { + public abstract deprecated interface HttpRequestHandlerResolver { method public abstract org.apache.http.protocol.HttpRequestHandler lookup(java.lang.String); } - public abstract interface HttpRequestInterceptorList { + public abstract deprecated interface HttpRequestInterceptorList { method public abstract void addRequestInterceptor(org.apache.http.HttpRequestInterceptor); method public abstract void addRequestInterceptor(org.apache.http.HttpRequestInterceptor, int); method public abstract void clearRequestInterceptors(); @@ -57648,7 +57681,7 @@ package org.apache.http.protocol { method public abstract void setInterceptors(java.util.List); } - public abstract interface HttpResponseInterceptorList { + public abstract deprecated interface HttpResponseInterceptorList { method public abstract void addResponseInterceptor(org.apache.http.HttpResponseInterceptor); method public abstract void addResponseInterceptor(org.apache.http.HttpResponseInterceptor, int); method public abstract void clearResponseInterceptors(); @@ -57658,7 +57691,7 @@ package org.apache.http.protocol { method public abstract void setInterceptors(java.util.List); } - public class HttpService { + public deprecated class HttpService { ctor public HttpService(org.apache.http.protocol.HttpProcessor, org.apache.http.ConnectionReuseStrategy, org.apache.http.HttpResponseFactory); method protected void doService(org.apache.http.HttpRequest, org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; method public org.apache.http.params.HttpParams getParams(); @@ -57672,61 +57705,61 @@ package org.apache.http.protocol { method public void setResponseFactory(org.apache.http.HttpResponseFactory); } - public class RequestConnControl implements org.apache.http.HttpRequestInterceptor { + public deprecated class RequestConnControl implements org.apache.http.HttpRequestInterceptor { ctor public RequestConnControl(); method public void process(org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class RequestContent implements org.apache.http.HttpRequestInterceptor { + public deprecated class RequestContent implements org.apache.http.HttpRequestInterceptor { ctor public RequestContent(); method public void process(org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class RequestDate implements org.apache.http.HttpRequestInterceptor { + public deprecated class RequestDate implements org.apache.http.HttpRequestInterceptor { ctor public RequestDate(); method public void process(org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class RequestExpectContinue implements org.apache.http.HttpRequestInterceptor { + public deprecated class RequestExpectContinue implements org.apache.http.HttpRequestInterceptor { ctor public RequestExpectContinue(); method public void process(org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class RequestTargetHost implements org.apache.http.HttpRequestInterceptor { + public deprecated class RequestTargetHost implements org.apache.http.HttpRequestInterceptor { ctor public RequestTargetHost(); method public void process(org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class RequestUserAgent implements org.apache.http.HttpRequestInterceptor { + public deprecated class RequestUserAgent implements org.apache.http.HttpRequestInterceptor { ctor public RequestUserAgent(); method public void process(org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class ResponseConnControl implements org.apache.http.HttpResponseInterceptor { + public deprecated class ResponseConnControl implements org.apache.http.HttpResponseInterceptor { ctor public ResponseConnControl(); method public void process(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class ResponseContent implements org.apache.http.HttpResponseInterceptor { + public deprecated class ResponseContent implements org.apache.http.HttpResponseInterceptor { ctor public ResponseContent(); method public void process(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class ResponseDate implements org.apache.http.HttpResponseInterceptor { + public deprecated class ResponseDate implements org.apache.http.HttpResponseInterceptor { ctor public ResponseDate(); method public void process(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class ResponseServer implements org.apache.http.HttpResponseInterceptor { + public deprecated class ResponseServer implements org.apache.http.HttpResponseInterceptor { ctor public ResponseServer(); method public void process(org.apache.http.HttpResponse, org.apache.http.protocol.HttpContext) throws org.apache.http.HttpException, java.io.IOException; } - public class SyncBasicHttpContext extends org.apache.http.protocol.BasicHttpContext { + public deprecated class SyncBasicHttpContext extends org.apache.http.protocol.BasicHttpContext { ctor public SyncBasicHttpContext(org.apache.http.protocol.HttpContext); } - public class UriPatternMatcher { + public deprecated class UriPatternMatcher { ctor public UriPatternMatcher(); method public java.lang.Object lookup(java.lang.String); method protected boolean matchUriRequestPattern(java.lang.String, java.lang.String); @@ -57739,7 +57772,7 @@ package org.apache.http.protocol { package org.apache.http.util { - public final class ByteArrayBuffer { + public final deprecated class ByteArrayBuffer { ctor public ByteArrayBuffer(int); method public void append(byte[], int, int); method public void append(int); @@ -57756,7 +57789,7 @@ package org.apache.http.util { method public byte[] toByteArray(); } - public final class CharArrayBuffer { + public final deprecated class CharArrayBuffer { ctor public CharArrayBuffer(int); method public void append(char[], int, int); method public void append(java.lang.String); @@ -57782,7 +57815,7 @@ package org.apache.http.util { method public char[] toCharArray(); } - public final class EncodingUtils { + public final deprecated class EncodingUtils { method public static byte[] getAsciiBytes(java.lang.String); method public static java.lang.String getAsciiString(byte[], int, int); method public static java.lang.String getAsciiString(byte[]); @@ -57791,18 +57824,18 @@ package org.apache.http.util { method public static java.lang.String getString(byte[], java.lang.String); } - public final class EntityUtils { + public final deprecated class EntityUtils { method public static java.lang.String getContentCharSet(org.apache.http.HttpEntity) throws org.apache.http.ParseException; method public static byte[] toByteArray(org.apache.http.HttpEntity) throws java.io.IOException; method public static java.lang.String toString(org.apache.http.HttpEntity, java.lang.String) throws java.io.IOException, org.apache.http.ParseException; method public static java.lang.String toString(org.apache.http.HttpEntity) throws java.io.IOException, org.apache.http.ParseException; } - public final class ExceptionUtils { + public final deprecated class ExceptionUtils { method public static void initCause(java.lang.Throwable, java.lang.Throwable); } - public final class LangUtils { + public final deprecated class LangUtils { method public static boolean equals(java.lang.Object, java.lang.Object); method public static boolean equals(java.lang.Object[], java.lang.Object[]); method public static int hashCode(int, int); @@ -57812,7 +57845,7 @@ package org.apache.http.util { field public static final int HASH_SEED = 17; // 0x11 } - public class VersionInfo { + public deprecated class VersionInfo { ctor protected VersionInfo(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String); method protected static final org.apache.http.util.VersionInfo fromMap(java.lang.String, java.util.Map, java.lang.ClassLoader); method public final java.lang.String getClassloader(); diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java index 13ceb4adfcdd..1e1b33f67496 100644 --- a/core/java/android/accessibilityservice/AccessibilityService.java +++ b/core/java/android/accessibilityservice/AccessibilityService.java @@ -24,13 +24,18 @@ import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.util.Log; +import android.view.Display; import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityInteractionClient; import android.view.accessibility.AccessibilityNodeInfo; import android.view.accessibility.AccessibilityWindowInfo; import com.android.internal.os.HandlerCaller; +import com.android.internal.os.SomeArgs; import java.util.List; @@ -366,7 +371,7 @@ public abstract class AccessibilityService extends Service { public void onAccessibilityEvent(AccessibilityEvent event); public void onInterrupt(); public void onServiceConnected(); - public void onSetConnectionId(int connectionId); + public void init(int connectionId, IBinder windowToken); public boolean onGesture(int gestureId); public boolean onKeyEvent(KeyEvent event); } @@ -375,6 +380,10 @@ public abstract class AccessibilityService extends Service { private AccessibilityServiceInfo mInfo; + private IBinder mWindowToken; + + private WindowManager mWindowManager; + /** * Callback for {@link android.view.accessibility.AccessibilityEvent}s. * @@ -611,6 +620,18 @@ public abstract class AccessibilityService extends Service { } } + @Override + public Object getSystemService(String name) { + if (Context.WINDOW_SERVICE.equals(name)) { + if (mWindowManager == null) { + WindowManager wrapped = (WindowManager) super.getSystemService(name); + mWindowManager = new LocalWindowManager(wrapped); + } + return mWindowManager; + } + return super.getSystemService(name); + } + /** * Implement to return the implementation of the internal accessibility * service interface. @@ -634,8 +655,9 @@ public abstract class AccessibilityService extends Service { } @Override - public void onSetConnectionId( int connectionId) { + public void init(int connectionId, IBinder windowToken) { mConnectionId = connectionId; + mWindowToken = windowToken; } @Override @@ -658,7 +680,7 @@ public abstract class AccessibilityService extends Service { */ public static class IAccessibilityServiceClientWrapper extends IAccessibilityServiceClient.Stub implements HandlerCaller.Callback { - private static final int DO_SET_SET_CONNECTION = 1; + private static final int DO_INIT = 1; private static final int DO_ON_INTERRUPT = 2; private static final int DO_ON_ACCESSIBILITY_EVENT = 3; private static final int DO_ON_GESTURE = 4; @@ -677,9 +699,10 @@ public abstract class AccessibilityService extends Service { mCaller = new HandlerCaller(context, looper, this, true /*asyncHandler*/); } - public void setConnection(IAccessibilityServiceConnection connection, int connectionId) { - Message message = mCaller.obtainMessageIO(DO_SET_SET_CONNECTION, connectionId, - connection); + public void init(IAccessibilityServiceConnection connection, int connectionId, + IBinder windowToken) { + Message message = mCaller.obtainMessageIOO(DO_INIT, connectionId, + connection, windowToken); mCaller.sendMessage(message); } @@ -730,20 +753,24 @@ public abstract class AccessibilityService extends Service { mCallback.onInterrupt(); } return; - case DO_SET_SET_CONNECTION: { + case DO_INIT: { mConnectionId = message.arg1; + SomeArgs args = (SomeArgs) message.obj; IAccessibilityServiceConnection connection = - (IAccessibilityServiceConnection) message.obj; + (IAccessibilityServiceConnection) args.arg1; + IBinder windowToken = (IBinder) args.arg2; + args.recycle(); if (connection != null) { AccessibilityInteractionClient.getInstance().addConnection(mConnectionId, connection); - mCallback.onSetConnectionId(mConnectionId); + mCallback.init(mConnectionId, windowToken); mCallback.onServiceConnected(); } else { AccessibilityInteractionClient.getInstance().removeConnection( mConnectionId); + mConnectionId = AccessibilityInteractionClient.NO_ID; AccessibilityInteractionClient.getInstance().clearCache(); - mCallback.onSetConnectionId(AccessibilityInteractionClient.NO_ID); + mCallback.init(AccessibilityInteractionClient.NO_ID, null); } } return; @@ -785,4 +812,53 @@ public abstract class AccessibilityService extends Service { } } } + + private class LocalWindowManager implements WindowManager { + private final WindowManager mImpl; + + private LocalWindowManager(WindowManager impl) { + mImpl = impl; + } + + @Override + public Display getDefaultDisplay() { + return mImpl.getDefaultDisplay(); + } + + @Override + public void addView(View view, ViewGroup.LayoutParams params) { + if (!(params instanceof WindowManager.LayoutParams)) { + throw new IllegalArgumentException("Params must be WindowManager.LayoutParams"); + } + WindowManager.LayoutParams windowParams = (WindowManager.LayoutParams) params; + if (windowParams.type == LayoutParams.TYPE_ACCESSIBILITY_OVERLAY + && windowParams.token == null) { + windowParams.token = mWindowToken; + } + mImpl.addView(view, params); + } + + @Override + public void updateViewLayout(View view, ViewGroup.LayoutParams params) { + if (!(params instanceof WindowManager.LayoutParams)) { + throw new IllegalArgumentException("Params must be WindowManager.LayoutParams"); + } + WindowManager.LayoutParams windowParams = (WindowManager.LayoutParams) params; + if (windowParams.type == LayoutParams.TYPE_ACCESSIBILITY_OVERLAY + && windowParams.token == null) { + windowParams.token = mWindowToken; + } + mImpl.updateViewLayout(view, params); + } + + @Override + public void removeViewImmediate(View view) { + mImpl.removeViewImmediate(view); + } + + @Override + public void removeView(View view) { + mImpl.removeView(view); + } + } } diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl index 6ce0219b81f5..8b503ddad947 100644 --- a/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl +++ b/core/java/android/accessibilityservice/IAccessibilityServiceClient.aidl @@ -28,7 +28,7 @@ import android.view.KeyEvent; */ oneway interface IAccessibilityServiceClient { - void setConnection(in IAccessibilityServiceConnection connection, int connectionId); + void init(in IAccessibilityServiceConnection connection, int connectionId, IBinder windowToken); void onAccessibilityEvent(in AccessibilityEvent event); diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java index 3720c8191e77..da4870901db9 100644 --- a/core/java/android/animation/Animator.java +++ b/core/java/android/animation/Animator.java @@ -16,6 +16,8 @@ package android.animation; +import android.content.res.ConstantState; + import java.util.ArrayList; /** @@ -41,6 +43,18 @@ public abstract class Animator implements Cloneable { boolean mPaused = false; /** + * A set of flags which identify the type of configuration changes that can affect this + * Animator. Used by the Animator cache. + */ + int mChangingConfigurations = 0; + + /** + * If this animator is inflated from a constant state, keep a reference to it so that + * ConstantState will not be garbage collected until this animator is collected + */ + private AnimatorConstantState mConstantState; + + /** * Starts this animation. If the animation has a nonzero startDelay, the animation will start * running after that delay elapses. A non-delayed animation will have its initial * value(s) set immediately, followed by calls to @@ -295,25 +309,71 @@ public abstract class Animator implements Cloneable { } } + /** + * Return a mask of the configuration parameters for which this animator may change, requiring + * that it should be re-created from Resources. The default implementation returns whatever + * value was provided through setChangingConfigurations(int) or 0 by default. + * + * @return Returns a mask of the changing configuration parameters, as defined by + * {@link android.content.pm.ActivityInfo}. + * @see android.content.pm.ActivityInfo + * @hide + */ + public int getChangingConfigurations() { + return mChangingConfigurations; + } + + /** + * Set a mask of the configuration parameters for which this animator may change, requiring + * that it be re-created from resource. + * + * @param configs A mask of the changing configuration parameters, as + * defined by {@link android.content.pm.ActivityInfo}. + * + * @see android.content.pm.ActivityInfo + * @hide + */ + public void setChangingConfigurations(int configs) { + mChangingConfigurations = configs; + } + + /** + * Sets the changing configurations value to the union of the current changing configurations + * and the provided configs. + * This method is called while loading the animator. + * @hide + */ + public void appendChangingConfigurations(int configs) { + mChangingConfigurations |= configs; + } + + /** + * Return a {@link android.content.res.ConstantState} instance that holds the shared state of + * this Animator. + * <p> + * This constant state is used to create new instances of this animator when needed, instead + * of re-loading it from resources. Default implementation creates a new + * {@link AnimatorConstantState}. You can override this method to provide your custom logic or + * return null if you don't want this animator to be cached. + * + * @return The ConfigurationBoundResourceCache.BaseConstantState associated to this Animator. + * @see android.content.res.ConstantState + * @see #clone() + * @hide + */ + public ConstantState<Animator> createConstantState() { + return new AnimatorConstantState(this); + } + @Override public Animator clone() { try { final Animator anim = (Animator) super.clone(); if (mListeners != null) { - ArrayList<AnimatorListener> oldListeners = mListeners; - anim.mListeners = new ArrayList<AnimatorListener>(); - int numListeners = oldListeners.size(); - for (int i = 0; i < numListeners; ++i) { - anim.mListeners.add(oldListeners.get(i)); - } + anim.mListeners = new ArrayList<AnimatorListener>(mListeners); } if (mPauseListeners != null) { - ArrayList<AnimatorPauseListener> oldListeners = mPauseListeners; - anim.mPauseListeners = new ArrayList<AnimatorPauseListener>(); - int numListeners = oldListeners.size(); - for (int i = 0; i < numListeners; ++i) { - anim.mPauseListeners.add(oldListeners.get(i)); - } + anim.mPauseListeners = new ArrayList<AnimatorPauseListener>(mPauseListeners); } return anim; } catch (CloneNotSupportedException e) { @@ -469,4 +529,35 @@ public abstract class Animator implements Cloneable { public void setAllowRunningAsynchronously(boolean mayRunAsync) { // It is up to subclasses to support this, if they can. } + + /** + * Creates a {@link ConstantState} which holds changing configurations information associated + * with the given Animator. + * <p> + * When {@link #newInstance()} is called, default implementation clones the Animator. + */ + private static class AnimatorConstantState extends ConstantState<Animator> { + + final Animator mAnimator; + int mChangingConf; + + public AnimatorConstantState(Animator animator) { + mAnimator = animator; + // ensure a reference back to here so that constante state is not gc'ed. + mAnimator.mConstantState = this; + mChangingConf = mAnimator.getChangingConfigurations(); + } + + @Override + public int getChangingConfigurations() { + return mChangingConf; + } + + @Override + public Animator newInstance() { + final Animator clone = mAnimator.clone(); + clone.mConstantState = this; + return clone; + } + } } diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java index 25417edb6f62..688d7e42dd36 100644 --- a/core/java/android/animation/AnimatorInflater.java +++ b/core/java/android/animation/AnimatorInflater.java @@ -16,6 +16,8 @@ package android.animation; import android.content.Context; +import android.content.res.ConfigurationBoundResourceCache; +import android.content.res.ConstantState; import android.content.res.Resources; import android.content.res.Resources.NotFoundException; import android.content.res.Resources.Theme; @@ -30,6 +32,8 @@ import android.util.TypedValue; import android.util.Xml; import android.view.InflateException; import android.view.animation.AnimationUtils; +import android.view.animation.BaseInterpolator; +import android.view.animation.Interpolator; import com.android.internal.R; @@ -67,6 +71,9 @@ public class AnimatorInflater { private static final boolean DBG_ANIMATOR_INFLATER = false; + // used to calculate changing configs for resource references + private static final TypedValue sTmpTypedValue = new TypedValue(); + /** * Loads an {@link Animator} object from a resource * @@ -98,11 +105,34 @@ public class AnimatorInflater { /** @hide */ public static Animator loadAnimator(Resources resources, Theme theme, int id, float pathErrorScale) throws NotFoundException { - + final ConfigurationBoundResourceCache<Animator> animatorCache = resources + .getAnimatorCache(); + Animator animator = animatorCache.get(id, theme); + if (animator != null) { + if (DBG_ANIMATOR_INFLATER) { + Log.d(TAG, "loaded animator from cache, " + resources.getResourceName(id)); + } + return animator; + } else if (DBG_ANIMATOR_INFLATER) { + Log.d(TAG, "cache miss for animator " + resources.getResourceName(id)); + } XmlResourceParser parser = null; try { parser = resources.getAnimation(id); - return createAnimatorFromXml(resources, theme, parser, pathErrorScale); + animator = createAnimatorFromXml(resources, theme, parser, pathErrorScale); + if (animator != null) { + animator.appendChangingConfigurations(getChangingConfigs(resources, id)); + final ConstantState<Animator> constantState = animator.createConstantState(); + if (constantState != null) { + if (DBG_ANIMATOR_INFLATER) { + Log.d(TAG, "caching animator for res " + resources.getResourceName(id)); + } + animatorCache.put(id, theme, constantState); + // create a new animator so that cached version is never used by the user + animator = constantState.newInstance(resources, theme); + } + } + return animator; } catch (XmlPullParserException ex) { Resources.NotFoundException rnf = new Resources.NotFoundException("Can't load animation resource ID #0x" + @@ -122,10 +152,29 @@ public class AnimatorInflater { public static StateListAnimator loadStateListAnimator(Context context, int id) throws NotFoundException { + final Resources resources = context.getResources(); + final ConfigurationBoundResourceCache<StateListAnimator> cache = resources + .getStateListAnimatorCache(); + final Theme theme = context.getTheme(); + StateListAnimator animator = cache.get(id, theme); + if (animator != null) { + return animator; + } XmlResourceParser parser = null; try { - parser = context.getResources().getAnimation(id); - return createStateListAnimatorFromXml(context, parser, Xml.asAttributeSet(parser)); + parser = resources.getAnimation(id); + animator = createStateListAnimatorFromXml(context, parser, Xml.asAttributeSet(parser)); + if (animator != null) { + animator.appendChangingConfigurations(getChangingConfigs(resources, id)); + final ConstantState<StateListAnimator> constantState = animator + .createConstantState(); + if (constantState != null) { + cache.put(id, theme, constantState); + // return a clone so that the animator in constant state is never used. + animator = constantState.newInstance(resources, theme); + } + } + return animator; } catch (XmlPullParserException ex) { Resources.NotFoundException rnf = new Resources.NotFoundException( @@ -172,14 +221,13 @@ public class AnimatorInflater { for (int i = 0; i < attributeCount; i++) { int attrName = attributeSet.getAttributeNameResource(i); if (attrName == R.attr.animation) { - animator = loadAnimator(context, - attributeSet.getAttributeResourceValue(i, 0)); + final int animId = attributeSet.getAttributeResourceValue(i, 0); + animator = loadAnimator(context, animId); } else { states[stateIndex++] = attributeSet.getAttributeBooleanValue(i, false) ? attrName : -attrName; } - } if (animator == null) { animator = createAnimatorFromXml(context.getResources(), @@ -192,7 +240,6 @@ public class AnimatorInflater { } stateListAnimator .addState(StateSet.trimStateSet(states, stateIndex), animator); - } break; } @@ -508,7 +555,6 @@ public class AnimatorInflater { private static Animator createAnimatorFromXml(Resources res, Theme theme, XmlPullParser parser, AttributeSet attrs, AnimatorSet parent, int sequenceOrdering, float pixelSize) throws XmlPullParserException, IOException { - Animator anim = null; ArrayList<Animator> childAnims = null; @@ -537,8 +583,8 @@ public class AnimatorInflater { } else { a = res.obtainAttributes(attrs, R.styleable.AnimatorSet); } - int ordering = a.getInt(R.styleable.AnimatorSet_ordering, - TOGETHER); + anim.appendChangingConfigurations(a.getChangingConfigurations()); + int ordering = a.getInt(R.styleable.AnimatorSet_ordering, TOGETHER); createAnimatorFromXml(res, theme, parser, attrs, (AnimatorSet) anim, ordering, pixelSize); a.recycle(); @@ -565,7 +611,6 @@ public class AnimatorInflater { parent.playSequentially(animsArray); } } - return anim; } @@ -591,7 +636,6 @@ public class AnimatorInflater { private static ValueAnimator loadAnimator(Resources res, Theme theme, AttributeSet attrs, ValueAnimator anim, float pathErrorScale) throws NotFoundException { - TypedArray arrayAnimator = null; TypedArray arrayObjectAnimator = null; @@ -609,25 +653,37 @@ public class AnimatorInflater { } else { arrayObjectAnimator = res.obtainAttributes(attrs, R.styleable.PropertyAnimator); } + anim.appendChangingConfigurations(arrayObjectAnimator.getChangingConfigurations()); } if (anim == null) { anim = new ValueAnimator(); } + anim.appendChangingConfigurations(arrayAnimator.getChangingConfigurations()); parseAnimatorFromTypeArray(anim, arrayAnimator, arrayObjectAnimator, pathErrorScale); - final int resID = - arrayAnimator.getResourceId(R.styleable.Animator_interpolator, 0); + final int resID = arrayAnimator.getResourceId(R.styleable.Animator_interpolator, 0); if (resID > 0) { - anim.setInterpolator(AnimationUtils.loadInterpolator(res, theme, resID)); + final Interpolator interpolator = AnimationUtils.loadInterpolator(res, theme, resID); + if (interpolator instanceof BaseInterpolator) { + anim.appendChangingConfigurations( + ((BaseInterpolator) interpolator).getChangingConfiguration()); + } + anim.setInterpolator(interpolator); } arrayAnimator.recycle(); if (arrayObjectAnimator != null) { arrayObjectAnimator.recycle(); } - return anim; } + + private static int getChangingConfigs(Resources resources, int id) { + synchronized (sTmpTypedValue) { + resources.getValue(id, sTmpTypedValue, true); + return sTmpTypedValue.changingConfigurations; + } + } } diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java index 0aa8fdd06e23..92762c33674f 100644 --- a/core/java/android/animation/AnimatorSet.java +++ b/core/java/android/animation/AnimatorSet.java @@ -241,6 +241,19 @@ public final class AnimatorSet extends Animator { } /** + * @hide + */ + @Override + public int getChangingConfigurations() { + int conf = super.getChangingConfigurations(); + final int nodeCount = mNodes.size(); + for (int i = 0; i < nodeCount; i ++) { + conf |= mNodes.get(i).animation.getChangingConfigurations(); + } + return conf; + } + + /** * Sets the TimeInterpolator for all current {@link #getChildAnimations() child animations} * of this AnimatorSet. The default value is null, which means that no interpolator * is set on this AnimatorSet. Setting the interpolator to any non-null value @@ -628,23 +641,25 @@ public final class AnimatorSet extends Animator { * manually, as we clone each Node (and its animation). The clone will then be sorted, * and will populate any appropriate lists, when it is started. */ + final int nodeCount = mNodes.size(); anim.mNeedsSort = true; anim.mTerminated = false; anim.mStarted = false; anim.mPlayingSet = new ArrayList<Animator>(); anim.mNodeMap = new HashMap<Animator, Node>(); - anim.mNodes = new ArrayList<Node>(); - anim.mSortedNodes = new ArrayList<Node>(); + anim.mNodes = new ArrayList<Node>(nodeCount); + anim.mSortedNodes = new ArrayList<Node>(nodeCount); anim.mReversible = mReversible; anim.mSetListener = null; // Walk through the old nodes list, cloning each node and adding it to the new nodemap. // One problem is that the old node dependencies point to nodes in the old AnimatorSet. // We need to track the old/new nodes in order to reconstruct the dependencies in the clone. - HashMap<Node, Node> nodeCloneMap = new HashMap<Node, Node>(); // <old, new> - for (Node node : mNodes) { + + for (int n = 0; n < nodeCount; n++) { + final Node node = mNodes.get(n); Node nodeClone = node.clone(); - nodeCloneMap.put(node, nodeClone); + node.mTmpClone = nodeClone; anim.mNodes.add(nodeClone); anim.mNodeMap.put(nodeClone.animation, nodeClone); // Clear out the dependencies in the clone; we'll set these up manually later @@ -652,40 +667,50 @@ public final class AnimatorSet extends Animator { nodeClone.tmpDependencies = null; nodeClone.nodeDependents = null; nodeClone.nodeDependencies = null; + // clear out any listeners that were set up by the AnimatorSet; these will // be set up when the clone's nodes are sorted - ArrayList<AnimatorListener> cloneListeners = nodeClone.animation.getListeners(); + final ArrayList<AnimatorListener> cloneListeners = nodeClone.animation.getListeners(); if (cloneListeners != null) { - ArrayList<AnimatorListener> listenersToRemove = null; - for (AnimatorListener listener : cloneListeners) { + for (int i = cloneListeners.size() - 1; i >= 0; i--) { + final AnimatorListener listener = cloneListeners.get(i); if (listener instanceof AnimatorSetListener) { - if (listenersToRemove == null) { - listenersToRemove = new ArrayList<AnimatorListener>(); - } - listenersToRemove.add(listener); - } - } - if (listenersToRemove != null) { - for (AnimatorListener listener : listenersToRemove) { - cloneListeners.remove(listener); + cloneListeners.remove(i); } } } } // Now that we've cloned all of the nodes, we're ready to walk through their // dependencies, mapping the old dependencies to the new nodes - for (Node node : mNodes) { - Node nodeClone = nodeCloneMap.get(node); + for (int n = 0; n < nodeCount; n++) { + final Node node = mNodes.get(n); + final Node clone = node.mTmpClone; if (node.dependencies != null) { - for (Dependency dependency : node.dependencies) { - Node clonedDependencyNode = nodeCloneMap.get(dependency.node); - Dependency cloneDependency = new Dependency(clonedDependencyNode, + clone.dependencies = new ArrayList<Dependency>(node.dependencies.size()); + final int depSize = node.dependencies.size(); + for (int i = 0; i < depSize; i ++) { + final Dependency dependency = node.dependencies.get(i); + Dependency cloneDependency = new Dependency(dependency.node.mTmpClone, dependency.rule); - nodeClone.addDependency(cloneDependency); + clone.dependencies.add(cloneDependency); + } + } + if (node.nodeDependents != null) { + clone.nodeDependents = new ArrayList<Node>(node.nodeDependents.size()); + for (Node dep : node.nodeDependents) { + clone.nodeDependents.add(dep.mTmpClone); + } + } + if (node.nodeDependencies != null) { + clone.nodeDependencies = new ArrayList<Node>(node.nodeDependencies.size()); + for (Node dep : node.nodeDependencies) { + clone.nodeDependencies.add(dep.mTmpClone); } } } - + for (int n = 0; n < nodeCount; n++) { + mNodes.get(n).mTmpClone = null; + } return anim; } @@ -1017,6 +1042,11 @@ public final class AnimatorSet extends Animator { public boolean done = false; /** + * Temporary field to hold the clone in AnimatorSet#clone. Cleaned after clone is complete + */ + private Node mTmpClone = null; + + /** * Constructs the Node with the animation that it encapsulates. A Node has no * dependencies by default; dependencies are added via the addDependency() * method. diff --git a/core/java/android/animation/FloatKeyframeSet.java b/core/java/android/animation/FloatKeyframeSet.java index 12e586293005..abac24671c87 100644 --- a/core/java/android/animation/FloatKeyframeSet.java +++ b/core/java/android/animation/FloatKeyframeSet.java @@ -19,6 +19,7 @@ package android.animation; import android.animation.Keyframe.FloatKeyframe; import java.util.ArrayList; +import java.util.List; /** * This class holds a collection of FloatKeyframe objects and is called by ValueAnimator to calculate @@ -47,8 +48,8 @@ class FloatKeyframeSet extends KeyframeSet implements Keyframes.FloatKeyframes { @Override public FloatKeyframeSet clone() { - ArrayList<Keyframe> keyframes = mKeyframes; - int numKeyframes = mKeyframes.size(); + final List<Keyframe> keyframes = mKeyframes; + final int numKeyframes = mKeyframes.size(); FloatKeyframe[] newKeyframes = new FloatKeyframe[numKeyframes]; for (int i = 0; i < numKeyframes; ++i) { newKeyframes[i] = (FloatKeyframe) keyframes.get(i).clone(); diff --git a/core/java/android/animation/IntKeyframeSet.java b/core/java/android/animation/IntKeyframeSet.java index 7a5b0ece4bae..0ec5138922be 100644 --- a/core/java/android/animation/IntKeyframeSet.java +++ b/core/java/android/animation/IntKeyframeSet.java @@ -19,6 +19,7 @@ package android.animation; import android.animation.Keyframe.IntKeyframe; import java.util.ArrayList; +import java.util.List; /** * This class holds a collection of IntKeyframe objects and is called by ValueAnimator to calculate @@ -47,7 +48,7 @@ class IntKeyframeSet extends KeyframeSet implements Keyframes.IntKeyframes { @Override public IntKeyframeSet clone() { - ArrayList<Keyframe> keyframes = mKeyframes; + List<Keyframe> keyframes = mKeyframes; int numKeyframes = mKeyframes.size(); IntKeyframe[] newKeyframes = new IntKeyframe[numKeyframes]; for (int i = 0; i < numKeyframes; ++i) { diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java index 8d15db2fbdf8..0e99bff257ff 100644 --- a/core/java/android/animation/KeyframeSet.java +++ b/core/java/android/animation/KeyframeSet.java @@ -18,6 +18,8 @@ package android.animation; import java.util.ArrayList; import java.util.Arrays; +import java.util.List; + import android.animation.Keyframe.IntKeyframe; import android.animation.Keyframe.FloatKeyframe; import android.animation.Keyframe.ObjectKeyframe; @@ -36,16 +38,16 @@ class KeyframeSet implements Keyframes { Keyframe mFirstKeyframe; Keyframe mLastKeyframe; TimeInterpolator mInterpolator; // only used in the 2-keyframe case - ArrayList<Keyframe> mKeyframes; // only used when there are not 2 keyframes + List<Keyframe> mKeyframes; // only used when there are not 2 keyframes TypeEvaluator mEvaluator; public KeyframeSet(Keyframe... keyframes) { mNumKeyframes = keyframes.length; - mKeyframes = new ArrayList<Keyframe>(); - mKeyframes.addAll(Arrays.asList(keyframes)); - mFirstKeyframe = mKeyframes.get(0); - mLastKeyframe = mKeyframes.get(mNumKeyframes - 1); + // immutable list + mKeyframes = Arrays.asList(keyframes); + mFirstKeyframe = keyframes[0]; + mLastKeyframe = keyframes[mNumKeyframes - 1]; mInterpolator = mLastKeyframe.getInterpolator(); } @@ -57,7 +59,7 @@ class KeyframeSet implements Keyframes { public void invalidateCache() { } - public ArrayList<Keyframe> getKeyframes() { + public List<Keyframe> getKeyframes() { return mKeyframes; } @@ -177,9 +179,9 @@ class KeyframeSet implements Keyframes { @Override public KeyframeSet clone() { - ArrayList<Keyframe> keyframes = mKeyframes; + List<Keyframe> keyframes = mKeyframes; int numKeyframes = mKeyframes.size(); - Keyframe[] newKeyframes = new Keyframe[numKeyframes]; + final Keyframe[] newKeyframes = new Keyframe[numKeyframes]; for (int i = 0; i < numKeyframes; ++i) { newKeyframes[i] = keyframes.get(i).clone(); } diff --git a/core/java/android/animation/Keyframes.java b/core/java/android/animation/Keyframes.java index 6611c6caf4a5..c921466b328f 100644 --- a/core/java/android/animation/Keyframes.java +++ b/core/java/android/animation/Keyframes.java @@ -16,6 +16,7 @@ package android.animation; import java.util.ArrayList; +import java.util.List; /** * This interface abstracts a collection of Keyframe objects and is called by @@ -62,7 +63,7 @@ interface Keyframes extends Cloneable { * @return A list of all Keyframes contained by this. This may return null if this is * not made up of Keyframes. */ - ArrayList<Keyframe> getKeyframes(); + List<Keyframe> getKeyframes(); Keyframes clone(); diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java index d372933e0265..97426c381cdf 100644 --- a/core/java/android/animation/PropertyValuesHolder.java +++ b/core/java/android/animation/PropertyValuesHolder.java @@ -27,6 +27,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.concurrent.locks.ReentrantReadWriteLock; /** @@ -791,7 +792,7 @@ public class PropertyValuesHolder implements Cloneable { // check to make sure that mProperty is on the class of target try { Object testValue = null; - ArrayList<Keyframe> keyframes = mKeyframes.getKeyframes(); + List<Keyframe> keyframes = mKeyframes.getKeyframes(); int keyframeCount = keyframes == null ? 0 : keyframes.size(); for (int i = 0; i < keyframeCount; i++) { Keyframe kf = keyframes.get(i); @@ -814,7 +815,7 @@ public class PropertyValuesHolder implements Cloneable { if (mSetter == null) { setupSetter(targetClass); } - ArrayList<Keyframe> keyframes = mKeyframes.getKeyframes(); + List<Keyframe> keyframes = mKeyframes.getKeyframes(); int keyframeCount = keyframes == null ? 0 : keyframes.size(); for (int i = 0; i < keyframeCount; i++) { Keyframe kf = keyframes.get(i); @@ -890,7 +891,7 @@ public class PropertyValuesHolder implements Cloneable { * @param target The object which holds the start values that should be set. */ void setupStartValue(Object target) { - ArrayList<Keyframe> keyframes = mKeyframes.getKeyframes(); + List<Keyframe> keyframes = mKeyframes.getKeyframes(); if (!keyframes.isEmpty()) { setupValue(target, keyframes.get(0)); } @@ -905,7 +906,7 @@ public class PropertyValuesHolder implements Cloneable { * @param target The object which holds the start values that should be set. */ void setupEndValue(Object target) { - ArrayList<Keyframe> keyframes = mKeyframes.getKeyframes(); + List<Keyframe> keyframes = mKeyframes.getKeyframes(); if (!keyframes.isEmpty()) { setupValue(target, keyframes.get(keyframes.size() - 1)); } diff --git a/core/java/android/animation/StateListAnimator.java b/core/java/android/animation/StateListAnimator.java index 7256a0638e10..d49e914cf5cc 100644 --- a/core/java/android/animation/StateListAnimator.java +++ b/core/java/android/animation/StateListAnimator.java @@ -16,6 +16,7 @@ package android.animation; +import android.content.res.ConstantState; import android.util.StateSet; import android.view.View; @@ -44,25 +45,31 @@ import java.util.ArrayList; * @attr ref android.R.styleable#DrawableStates_state_pressed * @attr ref android.R.styleable#StateListAnimatorItem_animation */ -public class StateListAnimator { - - private final ArrayList<Tuple> mTuples = new ArrayList<Tuple>(); +public class StateListAnimator implements Cloneable { + private ArrayList<Tuple> mTuples = new ArrayList<Tuple>(); private Tuple mLastMatch = null; - private Animator mRunningAnimator = null; - private WeakReference<View> mViewRef; + private StateListAnimatorConstantState mConstantState; + private AnimatorListenerAdapter mAnimatorListener; + private int mChangingConfigurations; - private AnimatorListenerAdapter mAnimatorListener = new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - animation.setTarget(null); - if (mRunningAnimator == animation) { - mRunningAnimator = null; + public StateListAnimator() { + initAnimatorListener(); + } + + private void initAnimatorListener() { + mAnimatorListener = new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + animation.setTarget(null); + if (mRunningAnimator == animation) { + mRunningAnimator = null; + } } - } - }; + }; + } /** * Associates the given animator with the provided drawable state specs so that it will be run @@ -75,6 +82,7 @@ public class StateListAnimator { Tuple tuple = new Tuple(specs, animator); tuple.mAnimator.addListener(mAnimatorListener); mTuples.add(tuple); + mChangingConfigurations |= animator.getChangingConfigurations(); } /** @@ -118,12 +126,35 @@ public class StateListAnimator { for (int i = 0; i < size; i++) { mTuples.get(i).mAnimator.setTarget(null); } - mViewRef = null; mLastMatch = null; mRunningAnimator = null; } + @Override + public StateListAnimator clone() { + try { + StateListAnimator clone = (StateListAnimator) super.clone(); + clone.mTuples = new ArrayList<Tuple>(mTuples.size()); + clone.mLastMatch = null; + clone.mRunningAnimator = null; + clone.mViewRef = null; + clone.mAnimatorListener = null; + clone.initAnimatorListener(); + final int tupleSize = mTuples.size(); + for (int i = 0; i < tupleSize; i++) { + final Tuple tuple = mTuples.get(i); + final Animator animatorClone = tuple.mAnimator.clone(); + animatorClone.removeListener(mAnimatorListener); + clone.addState(tuple.mSpecs, animatorClone); + } + clone.setChangingConfigurations(getChangingConfigurations()); + return clone; + } catch (CloneNotSupportedException e) { + throw new AssertionError("cannot clone state list animator", e); + } + } + /** * Called by View * @hide @@ -182,6 +213,63 @@ public class StateListAnimator { } /** + * Return a mask of the configuration parameters for which this animator may change, requiring + * that it be re-created. The default implementation returns whatever was provided through + * {@link #setChangingConfigurations(int)} or 0 by default. + * + * @return Returns a mask of the changing configuration parameters, as defined by + * {@link android.content.pm.ActivityInfo}. + * + * @see android.content.pm.ActivityInfo + * @hide + */ + public int getChangingConfigurations() { + return mChangingConfigurations; + } + + /** + * Set a mask of the configuration parameters for which this animator may change, requiring + * that it should be recreated from resources instead of being cloned. + * + * @param configs A mask of the changing configuration parameters, as + * defined by {@link android.content.pm.ActivityInfo}. + * + * @see android.content.pm.ActivityInfo + * @hide + */ + public void setChangingConfigurations(int configs) { + mChangingConfigurations = configs; + } + + /** + * Sets the changing configurations value to the union of the current changing configurations + * and the provided configs. + * This method is called while loading the animator. + * @hide + */ + public void appendChangingConfigurations(int configs) { + mChangingConfigurations |= configs; + } + + /** + * Return a {@link android.content.res.ConstantState} instance that holds the shared state of + * this Animator. + * <p> + * This constant state is used to create new instances of this animator when needed. Default + * implementation creates a new {@link StateListAnimatorConstantState}. You can override this + * method to provide your custom logic or return null if you don't want this animator to be + * cached. + * + * @return The {@link android.content.res.ConstantState} associated to this Animator. + * @see android.content.res.ConstantState + * @see #clone() + * @hide + */ + public ConstantState<StateListAnimator> createConstantState() { + return new StateListAnimatorConstantState(this); + } + + /** * @hide */ public static class Tuple { @@ -209,4 +297,36 @@ public class StateListAnimator { return mAnimator; } } + + /** + * Creates a constant state which holds changing configurations information associated with the + * given Animator. + * <p> + * When new instance is called, default implementation clones the Animator. + */ + private static class StateListAnimatorConstantState + extends ConstantState<StateListAnimator> { + + final StateListAnimator mAnimator; + + int mChangingConf; + + public StateListAnimatorConstantState(StateListAnimator animator) { + mAnimator = animator; + mAnimator.mConstantState = this; + mChangingConf = mAnimator.getChangingConfigurations(); + } + + @Override + public int getChangingConfigurations() { + return mChangingConf; + } + + @Override + public StateListAnimator newInstance() { + final StateListAnimator clone = mAnimator.clone(); + clone.mConstantState = this; + return clone; + } + } } diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 0d17d6716d6d..07f79b8b33a2 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -16,6 +16,7 @@ package android.animation; +import android.content.res.ConfigurationBoundResourceCache; import android.os.Looper; import android.os.Trace; import android.util.AndroidRuntimeException; @@ -1289,12 +1290,7 @@ public class ValueAnimator extends Animator { public ValueAnimator clone() { final ValueAnimator anim = (ValueAnimator) super.clone(); if (mUpdateListeners != null) { - ArrayList<AnimatorUpdateListener> oldListeners = mUpdateListeners; - anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>(); - int numListeners = oldListeners.size(); - for (int i = 0; i < numListeners; ++i) { - anim.mUpdateListeners.add(oldListeners.get(i)); - } + anim.mUpdateListeners = new ArrayList<AnimatorUpdateListener>(mUpdateListeners); } anim.mSeekTime = -1; anim.mPlayingBackwards = false; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index dd49009281f3..fa15ad758cc6 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2513,7 +2513,12 @@ public final class ActivityThread { } public void handleInstallProvider(ProviderInfo info) { - installContentProviders(mInitialApplication, Lists.newArrayList(info)); + final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites(); + try { + installContentProviders(mInitialApplication, Lists.newArrayList(info)); + } finally { + StrictMode.setThreadPolicy(oldPolicy); + } } private void handleEnterAnimationComplete(IBinder token) { diff --git a/core/java/android/app/EnterTransitionCoordinator.java b/core/java/android/app/EnterTransitionCoordinator.java index add67f2ec8a5..9bf8b3c8ea6b 100644 --- a/core/java/android/app/EnterTransitionCoordinator.java +++ b/core/java/android/app/EnterTransitionCoordinator.java @@ -322,6 +322,7 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { if (mListener != null) { mListener.onRejectSharedElements(rejectedSnapshots); } + removeNullViews(rejectedSnapshots); startRejectedAnimations(rejectedSnapshots); // Now start shared element transition @@ -370,6 +371,16 @@ class EnterTransitionCoordinator extends ActivityTransitionCoordinator { } } + private static void removeNullViews(ArrayList<View> views) { + if (views != null) { + for (int i = views.size() - 1; i >= 0; i--) { + if (views.get(i) == null) { + views.remove(i); + } + } + } + } + private void onTakeSharedElements() { if (!mIsReadyForTransition || mSharedElementsBundle == null) { return; diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java index cc9aed8ccdbc..5038df93192d 100644 --- a/core/java/android/app/KeyguardManager.java +++ b/core/java/android/app/KeyguardManager.java @@ -16,10 +16,14 @@ package android.app; +import android.app.trust.ITrustManager; +import android.content.Context; import android.content.Intent; import android.os.Binder; import android.os.RemoteException; import android.os.IBinder; +import android.os.ServiceManager; +import android.os.UserHandle; import android.view.IWindowManager; import android.view.IOnKeyguardExitResult; import android.view.WindowManagerGlobal; @@ -33,6 +37,7 @@ import android.view.WindowManagerGlobal; */ public class KeyguardManager { private IWindowManager mWM; + private ITrustManager mTrustManager; /** * Intent used to prompt user for device credentials. @@ -151,6 +156,8 @@ public class KeyguardManager { KeyguardManager() { mWM = WindowManagerGlobal.getWindowManagerService(); + mTrustManager = ITrustManager.Stub.asInterface( + ServiceManager.getService(Context.TRUST_SERVICE)); } /** @@ -218,6 +225,34 @@ public class KeyguardManager { } /** + * Return whether unlocking the device is currently not requiring a password + * because of a trust agent. + * + * @return true if the keyguard can currently be unlocked without entering credentials + * because the device is in a trusted environment. + */ + public boolean isKeyguardInTrustedState() { + return isKeyguardInTrustedState(UserHandle.getCallingUserId()); + } + + /** + * Return whether unlocking the device is currently not requiring a password + * because of a trust agent. + * + * @param userId the user for which the trusted state should be reported. + * @return true if the keyguard can currently be unlocked without entering credentials + * because the device is in a trusted environment. + * @hide + */ + public boolean isKeyguardInTrustedState(int userId) { + try { + return mTrustManager.isTrusted(userId); + } catch (RemoteException e) { + return false; + } + } + + /** * @deprecated Use {@link android.view.WindowManager.LayoutParams#FLAG_DISMISS_KEYGUARD} * and/or {@link android.view.WindowManager.LayoutParams#FLAG_SHOW_WHEN_LOCKED} * instead; this allows you to seamlessly hide the keyguard as your application diff --git a/core/java/android/app/SharedElementCallback.java b/core/java/android/app/SharedElementCallback.java index 060bbe61e407..6ac24013672c 100644 --- a/core/java/android/app/SharedElementCallback.java +++ b/core/java/android/app/SharedElementCallback.java @@ -18,13 +18,16 @@ package android.app; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; -import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.os.Bundle; import android.os.Parcelable; import android.transition.TransitionUtils; import android.view.View; +import android.widget.ImageView; +import android.widget.ImageView.ScaleType; import java.util.List; import java.util.Map; @@ -40,6 +43,9 @@ import java.util.Map; */ public abstract class SharedElementCallback { private Matrix mTempMatrix; + private static final String BUNDLE_SNAPSHOT_BITMAP = "sharedElement:snapshot:bitmap"; + private static final String BUNDLE_SNAPSHOT_IMAGE_SCALETYPE = "sharedElement:snapshot:imageScaleType"; + private static final String BUNDLE_SNAPSHOT_IMAGE_MATRIX = "sharedElement:snapshot:imageMatrix"; static final SharedElementCallback NULL_CALLBACK = new SharedElementCallback() { }; @@ -142,6 +148,27 @@ public abstract class SharedElementCallback { */ public Parcelable onCaptureSharedElementSnapshot(View sharedElement, Matrix viewToGlobalMatrix, RectF screenBounds) { + if (sharedElement instanceof ImageView) { + ImageView imageView = ((ImageView) sharedElement); + Drawable d = imageView.getDrawable(); + Drawable bg = imageView.getBackground(); + if (d != null && (bg == null || bg.getAlpha() == 0)) { + Bitmap bitmap = TransitionUtils.createDrawableBitmap(d); + if (bitmap != null) { + Bundle bundle = new Bundle(); + bundle.putParcelable(BUNDLE_SNAPSHOT_BITMAP, bitmap); + bundle.putString(BUNDLE_SNAPSHOT_IMAGE_SCALETYPE, + imageView.getScaleType().toString()); + if (imageView.getScaleType() == ScaleType.MATRIX) { + Matrix matrix = imageView.getImageMatrix(); + float[] values = new float[9]; + matrix.getValues(values); + bundle.putFloatArray(BUNDLE_SNAPSHOT_IMAGE_MATRIX, values); + } + return bundle; + } + } + } if (mTempMatrix == null) { mTempMatrix = new Matrix(viewToGlobalMatrix); } else { @@ -169,7 +196,24 @@ public abstract class SharedElementCallback { */ public View onCreateSnapshotView(Context context, Parcelable snapshot) { View view = null; - if (snapshot instanceof Bitmap) { + if (snapshot instanceof Bundle) { + Bundle bundle = (Bundle) snapshot; + Bitmap bitmap = (Bitmap) bundle.getParcelable(BUNDLE_SNAPSHOT_BITMAP); + if (bitmap == null) { + return null; + } + ImageView imageView = new ImageView(context); + view = imageView; + imageView.setImageBitmap(bitmap); + imageView.setScaleType( + ScaleType.valueOf(bundle.getString(BUNDLE_SNAPSHOT_IMAGE_SCALETYPE))); + if (imageView.getScaleType() == ScaleType.MATRIX) { + float[] values = bundle.getFloatArray(BUNDLE_SNAPSHOT_IMAGE_MATRIX); + Matrix matrix = new Matrix(); + matrix.setValues(values); + imageView.setImageMatrix(matrix); + } + } else if (snapshot instanceof Bitmap) { Bitmap bitmap = (Bitmap) snapshot; view = new View(context); Resources resources = context.getResources(); diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java index 4aec9e00e56f..b0dd70f34fd2 100644 --- a/core/java/android/app/UiAutomation.java +++ b/core/java/android/app/UiAutomation.java @@ -25,6 +25,7 @@ import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Point; import android.hardware.display.DisplayManagerGlobal; +import android.os.IBinder; import android.os.Looper; import android.os.ParcelFileDescriptor; import android.os.RemoteException; @@ -919,7 +920,7 @@ public final class UiAutomation { public IAccessibilityServiceClientImpl(Looper looper) { super(null, looper, new Callbacks() { @Override - public void onSetConnectionId(int connectionId) { + public void init(int connectionId, IBinder windowToken) { synchronized (mLock) { mConnectionId = connectionId; mLock.notifyAll(); diff --git a/core/java/android/app/trust/ITrustManager.aidl b/core/java/android/app/trust/ITrustManager.aidl index 6fbf87d2d335..0193711fd588 100644 --- a/core/java/android/app/trust/ITrustManager.aidl +++ b/core/java/android/app/trust/ITrustManager.aidl @@ -29,4 +29,5 @@ interface ITrustManager { void reportRequireCredentialEntry(int userId); void registerTrustListener(in ITrustListener trustListener); void unregisterTrustListener(in ITrustListener trustListener); + boolean isTrusted(int userId); } diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java index af6f1816ae8c..7676e4b8d6fc 100644 --- a/core/java/android/content/Intent.java +++ b/core/java/android/content/Intent.java @@ -876,12 +876,44 @@ public class Intent implements Parcelable, Cloneable { * related methods. */ public static Intent createChooser(Intent target, CharSequence title) { + return createChooser(target, title, null); + } + + /** + * Convenience function for creating a {@link #ACTION_CHOOSER} Intent. + * + * <p>Builds a new {@link #ACTION_CHOOSER} Intent that wraps the given + * target intent, also optionally supplying a title. If the target + * intent has specified {@link #FLAG_GRANT_READ_URI_PERMISSION} or + * {@link #FLAG_GRANT_WRITE_URI_PERMISSION}, then these flags will also be + * set in the returned chooser intent, with its ClipData set appropriately: + * either a direct reflection of {@link #getClipData()} if that is non-null, + * or a new ClipData built from {@link #getData()}.</p> + * + * <p>The caller may optionally supply an {@link IntentSender} to receive a callback + * when the user makes a choice. This can be useful if the calling application wants + * to remember the last chosen target and surface it as a more prominent or one-touch + * affordance elsewhere in the UI for next time.</p> + * + * @param target The Intent that the user will be selecting an activity + * to perform. + * @param title Optional title that will be displayed in the chooser. + * @param sender Optional IntentSender to be called when a choice is made. + * @return Return a new Intent object that you can hand to + * {@link Context#startActivity(Intent) Context.startActivity()} and + * related methods. + */ + public static Intent createChooser(Intent target, CharSequence title, IntentSender sender) { Intent intent = new Intent(ACTION_CHOOSER); intent.putExtra(EXTRA_INTENT, target); if (title != null) { intent.putExtra(EXTRA_TITLE, title); } + if (sender != null) { + intent.putExtra(EXTRA_CHOSEN_COMPONENT_INTENT_SENDER, sender); + } + // Migrate any clip data and flags from target. int permFlags = target.getFlags() & (FLAG_GRANT_READ_URI_PERMISSION | FLAG_GRANT_WRITE_URI_PERMISSION | FLAG_GRANT_PERSISTABLE_URI_PERMISSION @@ -3140,6 +3172,26 @@ public class Intent implements Parcelable, Cloneable { "android.intent.extra.REPLACEMENT_EXTRAS"; /** + * An {@link IntentSender} that will be notified if a user successfully chooses a target + * component to handle an action in an {@link #ACTION_CHOOSER} activity. The IntentSender + * will have the extra {@link #EXTRA_CHOSEN_COMPONENT} appended to it containing the + * {@link ComponentName} of the chosen component. + * + * <p>In some situations this callback may never come, for example if the user abandons + * the chooser, switches to another task or any number of other reasons. Apps should not + * be written assuming that this callback will always occur.</p> + */ + public static final String EXTRA_CHOSEN_COMPONENT_INTENT_SENDER = + "android.intent.extra.CHOSEN_COMPONENT_INTENT_SENDER"; + + /** + * The {@link ComponentName} chosen by the user to complete an action. + * + * @see #EXTRA_CHOSEN_COMPONENT_INTENT_SENDER + */ + public static final String EXTRA_CHOSEN_COMPONENT = "android.intent.extra.CHOSEN_COMPONENT"; + + /** * A {@link android.view.KeyEvent} object containing the event that * triggered the creation of the Intent it is in. */ diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index ca4ff6a49c6c..8515520c0d0a 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -74,7 +74,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; @@ -380,7 +379,7 @@ public class PackageParser { */ public static PackageInfo generatePackageInfo(PackageParser.Package p, int gids[], int flags, long firstInstallTime, long lastUpdateTime, - HashSet<String> grantedPermissions, PackageUserState state) { + ArraySet<String> grantedPermissions, PackageUserState state) { return generatePackageInfo(p, gids, flags, firstInstallTime, lastUpdateTime, grantedPermissions, state, UserHandle.getCallingUserId()); @@ -401,7 +400,7 @@ public class PackageParser { public static PackageInfo generatePackageInfo(PackageParser.Package p, int gids[], int flags, long firstInstallTime, long lastUpdateTime, - HashSet<String> grantedPermissions, PackageUserState state, int userId) { + ArraySet<String> grantedPermissions, PackageUserState state, int userId) { if (!checkUseInstalledOrHidden(flags, state)) { return null; diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java index 4dcad6f16195..a9c7be376656 100644 --- a/core/java/android/content/pm/PackageUserState.java +++ b/core/java/android/content/pm/PackageUserState.java @@ -18,7 +18,7 @@ package android.content.pm; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT; -import java.util.HashSet; +import android.util.ArraySet; /** * Per-user state information about a package. @@ -34,8 +34,8 @@ public class PackageUserState { public String lastDisableAppCaller; - public HashSet<String> disabledComponents; - public HashSet<String> enabledComponents; + public ArraySet<String> disabledComponents; + public ArraySet<String> enabledComponents; public PackageUserState() { installed = true; @@ -51,9 +51,9 @@ public class PackageUserState { hidden = o.hidden; lastDisableAppCaller = o.lastDisableAppCaller; disabledComponents = o.disabledComponents != null - ? new HashSet<String>(o.disabledComponents) : null; + ? new ArraySet<String>(o.disabledComponents) : null; enabledComponents = o.enabledComponents != null - ? new HashSet<String>(o.enabledComponents) : null; + ? new ArraySet<String>(o.enabledComponents) : null; blockUninstall = o.blockUninstall; } -}
\ No newline at end of file +} diff --git a/core/java/android/content/res/ConfigurationBoundResourceCache.java b/core/java/android/content/res/ConfigurationBoundResourceCache.java new file mode 100644 index 000000000000..cde7e84b70ce --- /dev/null +++ b/core/java/android/content/res/ConfigurationBoundResourceCache.java @@ -0,0 +1,138 @@ +/* +* Copyright (C) 2014 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.content.res; + +import android.util.ArrayMap; +import android.util.LongSparseArray; +import java.lang.ref.WeakReference; + +/** + * A Cache class which can be used to cache resource objects that are easy to clone but more + * expensive to inflate. + * @hide + */ +public class ConfigurationBoundResourceCache<T> { + + private final ArrayMap<String, LongSparseArray<WeakReference<ConstantState<T>>>> mCache = + new ArrayMap<String, LongSparseArray<WeakReference<ConstantState<T>>>>(); + + final Resources mResources; + + /** + * Creates a Resource cache for the given Resources instance. + * + * @param resources The Resource which can be used when creating new instances. + */ + public ConfigurationBoundResourceCache(Resources resources) { + mResources = resources; + } + + /** + * Adds a new item to the cache. + * + * @param key A custom key that uniquely identifies the resource. + * @param theme The Theme instance where this resource was loaded. + * @param constantState The constant state that can create new instances of the resource. + * + */ + public void put(long key, Resources.Theme theme, ConstantState<T> constantState) { + if (constantState == null) { + return; + } + final String themeKey = theme == null ? "" : theme.getKey(); + LongSparseArray<WeakReference<ConstantState<T>>> themedCache; + synchronized (this) { + themedCache = mCache.get(themeKey); + if (themedCache == null) { + themedCache = new LongSparseArray<WeakReference<ConstantState<T>>>(1); + mCache.put(themeKey, themedCache); + } + themedCache.put(key, new WeakReference<ConstantState<T>>(constantState)); + } + } + + /** + * If the resource is cached, creates a new instance of it and returns. + * + * @param key The long key which can be used to uniquely identify the resource. + * @param theme The The Theme instance where we want to load this resource. + * + * @return If this resources was loaded before, returns a new instance of it. Otherwise, returns + * null. + */ + public T get(long key, Resources.Theme theme) { + final String themeKey = theme != null ? theme.getKey() : ""; + final LongSparseArray<WeakReference<ConstantState<T>>> themedCache; + final WeakReference<ConstantState<T>> wr; + synchronized (this) { + themedCache = mCache.get(themeKey); + if (themedCache == null) { + return null; + } + wr = themedCache.get(key); + } + if (wr == null) { + return null; + } + final ConstantState entry = wr.get(); + if (entry != null) { + return (T) entry.newInstance(mResources, theme); + } else { // our entry has been purged + synchronized (this) { + // there is a potential race condition here where this entry may be put in + // another thread. But we prefer it to minimize lock duration + themedCache.delete(key); + } + } + return null; + } + + /** + * Users of ConfigurationBoundResourceCache must call this method whenever a configuration + * change happens. On this callback, the cache invalidates all resources that are not valid + * anymore. + * + * @param configChanges The configuration changes + */ + public void onConfigurationChange(final int configChanges) { + synchronized (this) { + final int size = mCache.size(); + for (int i = size - 1; i >= 0; i--) { + final LongSparseArray<WeakReference<ConstantState<T>>> + themeCache = mCache.valueAt(i); + onConfigurationChangeInt(themeCache, configChanges); + if (themeCache.size() == 0) { + mCache.removeAt(i); + } + } + } + } + + private void onConfigurationChangeInt( + final LongSparseArray<WeakReference<ConstantState<T>>> themeCache, + final int configChanges) { + final int size = themeCache.size(); + for (int i = size - 1; i >= 0; i--) { + final WeakReference<ConstantState<T>> wr = themeCache.valueAt(i); + final ConstantState<T> constantState = wr.get(); + if (constantState == null || Configuration.needNewResources( + configChanges, constantState.getChangingConfigurations())) { + themeCache.removeAt(i); + } + } + } + +} diff --git a/core/java/android/content/res/ConstantState.java b/core/java/android/content/res/ConstantState.java new file mode 100644 index 000000000000..ee609df2e232 --- /dev/null +++ b/core/java/android/content/res/ConstantState.java @@ -0,0 +1,61 @@ +/* +* Copyright (C) 2014 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.content.res; + +/** + * A cache class that can provide new instances of a particular resource which may change + * depending on the current {@link Resources.Theme} or {@link Configuration}. + * <p> + * A constant state should be able to return a bitmask of changing configurations, which + * identifies the type of configuration changes that may invalidate this resource. These + * configuration changes can be obtained from {@link android.util.TypedValue}. Entities such as + * {@link android.animation.Animator} also provide a changing configuration method to include + * their dependencies (e.g. An AnimatorSet's changing configuration is the union of the + * changing configurations of each Animator in the set) + * @hide + */ +abstract public class ConstantState<T> { + + /** + * Return a bit mask of configuration changes that will impact + * this resource (and thus require completely reloading it). + */ + abstract public int getChangingConfigurations(); + + /** + * Create a new instance without supplying resources the caller + * is running in. + */ + public abstract T newInstance(); + + /** + * Create a new instance from its constant state. This + * must be implemented for resources that change based on the target + * density of their caller (that is depending on whether it is + * in compatibility mode). + */ + public T newInstance(Resources res) { + return newInstance(); + } + + /** + * Create a new instance from its constant state. This must be + * implemented for resources that can have a theme applied. + */ + public T newInstance(Resources res, Resources.Theme theme) { + return newInstance(res); + } +} diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java index e34ce3e9535a..6e9efe1fdc1b 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -16,6 +16,8 @@ package android.content.res; +import android.animation.Animator; +import android.animation.StateListAnimator; import android.util.Pools.SynchronizedPool; import android.view.ViewDebug; import com.android.internal.util.XmlUtils; @@ -115,6 +117,10 @@ public class Resources { new ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>>(); private final LongSparseArray<WeakReference<ColorStateList>> mColorStateListCache = new LongSparseArray<WeakReference<ColorStateList>>(); + private final ConfigurationBoundResourceCache<Animator> mAnimatorCache = + new ConfigurationBoundResourceCache<Animator>(this); + private final ConfigurationBoundResourceCache<StateListAnimator> mStateListAnimatorCache = + new ConfigurationBoundResourceCache<StateListAnimator>(this); private TypedValue mTmpValue = new TypedValue(); private boolean mPreloading; @@ -183,6 +189,24 @@ public class Resources { } /** + * Used by AnimatorInflater. + * + * @hide + */ + public ConfigurationBoundResourceCache<Animator> getAnimatorCache() { + return mAnimatorCache; + } + + /** + * Used by AnimatorInflater. + * + * @hide + */ + public ConfigurationBoundResourceCache<StateListAnimator> getStateListAnimatorCache() { + return mStateListAnimatorCache; + } + + /** * This exception is thrown by the resource APIs when a requested resource * can not be found. */ @@ -1761,23 +1785,7 @@ public class Resources { // the framework. mCompatibilityInfo.applyToDisplayMetrics(mMetrics); - int configChanges = 0xfffffff; - if (config != null) { - mTmpConfig.setTo(config); - int density = config.densityDpi; - if (density == Configuration.DENSITY_DPI_UNDEFINED) { - density = mMetrics.noncompatDensityDpi; - } - - mCompatibilityInfo.applyToConfiguration(density, mTmpConfig); - - if (mTmpConfig.locale == null) { - mTmpConfig.locale = Locale.getDefault(); - mTmpConfig.setLayoutDirection(mTmpConfig.locale); - } - configChanges = mConfiguration.updateFrom(mTmpConfig); - configChanges = ActivityInfo.activityInfoConfigToNative(configChanges); - } + int configChanges = calcConfigChanges(config); if (mConfiguration.locale == null) { mConfiguration.locale = Locale.getDefault(); mConfiguration.setLayoutDirection(mConfiguration.locale); @@ -1825,6 +1833,8 @@ public class Resources { clearDrawableCachesLocked(mDrawableCache, configChanges); clearDrawableCachesLocked(mColorDrawableCache, configChanges); + mAnimatorCache.onConfigurationChange(configChanges); + mStateListAnimatorCache.onConfigurationChange(configChanges); mColorStateListCache.clear(); @@ -1837,6 +1847,30 @@ public class Resources { } } + /** + * Called by ConfigurationBoundResourceCacheTest via reflection. + */ + private int calcConfigChanges(Configuration config) { + int configChanges = 0xfffffff; + if (config != null) { + mTmpConfig.setTo(config); + int density = config.densityDpi; + if (density == Configuration.DENSITY_DPI_UNDEFINED) { + density = mMetrics.noncompatDensityDpi; + } + + mCompatibilityInfo.applyToConfiguration(density, mTmpConfig); + + if (mTmpConfig.locale == null) { + mTmpConfig.locale = Locale.getDefault(); + mTmpConfig.setLayoutDirection(mTmpConfig.locale); + } + configChanges = mConfiguration.updateFrom(mTmpConfig); + configChanges = ActivityInfo.activityInfoConfigToNative(configChanges); + } + return configChanges; + } + private void clearDrawableCachesLocked( ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches, int configChanges) { diff --git a/core/java/android/hardware/hdmi/HdmiClient.java b/core/java/android/hardware/hdmi/HdmiClient.java index c2b9846c0cdd..45a79e1f3cae 100644 --- a/core/java/android/hardware/hdmi/HdmiClient.java +++ b/core/java/android/hardware/hdmi/HdmiClient.java @@ -8,7 +8,7 @@ import android.util.Log; /** * Parent for classes of various HDMI-CEC device type used to access - * {@link HdmiControlService}. Contains methods and data used in common. + * the HDMI control system service. Contains methods and data used in common. * * @hide */ @@ -16,11 +16,13 @@ import android.util.Log; public abstract class HdmiClient { private static final String TAG = "HdmiClient"; - protected final IHdmiControlService mService; + /* package */ final IHdmiControlService mService; - protected abstract int getDeviceType(); + private IHdmiVendorCommandListener mIHdmiVendorCommandListener; - public HdmiClient(IHdmiControlService service) { + /* package */ abstract int getDeviceType(); + + /* package */ HdmiClient(IHdmiControlService service) { mService = service; } @@ -40,7 +42,7 @@ public abstract class HdmiClient { } /** - * Send a key event to other logical device. + * Sends a key event to other logical device. * * @param keyCode key code to send. Defined in {@link android.view.KeyEvent}. * @param isPressed true if this is key press event @@ -54,7 +56,7 @@ public abstract class HdmiClient { } /** - * Send vendor-specific command. + * Sends vendor-specific command. * * @param targetAddress address of the target device * @param params vendor-specific parameter. For <Vendor Command With ID> do not @@ -71,18 +73,23 @@ public abstract class HdmiClient { } /** - * Add a listener used to receive incoming vendor-specific command. + * Sets a listener used to receive incoming vendor-specific command. * * @param listener listener object */ - public void addVendorCommandListener(@NonNull VendorCommandListener listener) { + public void setVendorCommandListener(@NonNull VendorCommandListener listener) { if (listener == null) { throw new IllegalArgumentException("listener cannot be null"); } + if (mIHdmiVendorCommandListener != null) { + throw new IllegalStateException("listener was already set"); + } try { - mService.addVendorCommandListener(getListenerWrapper(listener), getDeviceType()); + IHdmiVendorCommandListener wrappedListener = getListenerWrapper(listener); + mService.addVendorCommandListener(wrappedListener, getDeviceType()); + mIHdmiVendorCommandListener = wrappedListener; } catch (RemoteException e) { - Log.e(TAG, "failed to add vendor command listener: ", e); + Log.e(TAG, "failed to set vendor command listener: ", e); } } diff --git a/core/java/android/hardware/hdmi/HdmiControlManager.java b/core/java/android/hardware/hdmi/HdmiControlManager.java index ff2ba1eec20f..308a21918ba9 100644 --- a/core/java/android/hardware/hdmi/HdmiControlManager.java +++ b/core/java/android/hardware/hdmi/HdmiControlManager.java @@ -21,6 +21,8 @@ import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.os.RemoteException; +import android.util.ArrayMap; +import android.util.Log; /** * The {@link HdmiControlManager} class is used to send HDMI control messages @@ -36,6 +38,8 @@ import android.os.RemoteException; */ @SystemApi public final class HdmiControlManager { + private static final String TAG = "HdmiControlManager"; + @Nullable private final IHdmiControlService mService; /** @@ -56,7 +60,7 @@ public final class HdmiControlManager { /** * Message used by TV to receive volume status from Audio Receiver. It should check volume value - * that is retrieved from extra value with the key {@link #EXTRA_MESSAGE_EXTRAM_PARAM1}. If the + * that is retrieved from extra value with the key {@link #EXTRA_MESSAGE_EXTRA_PARAM1}. If the * value is in range of [0,100], it is current volume of Audio Receiver. And there is another * value, {@link #AVR_VOLUME_MUTED}, which is used to inform volume mute. */ @@ -71,7 +75,7 @@ public final class HdmiControlManager { * Used as an extra field in the intent {@link #ACTION_OSD_MESSAGE}. Contains the extra value * of the message. */ - public static final String EXTRA_MESSAGE_EXTRAM_PARAM1 = + public static final String EXTRA_MESSAGE_EXTRA_PARAM1 = "android.hardware.hdmi.extra.MESSAGE_EXTRA_PARAM1"; /** @@ -251,10 +255,9 @@ public final class HdmiControlManager { private final boolean mHasTvDevice; /** - * @hide - hide this constructor because it has a parameter of type - * IHdmiControlService, which is a system private class. The right way - * to create an instance of this class is using the factory - * Context.getSystemService. + * {@hide} - hide this constructor because it has a parameter of type IHdmiControlService, + * which is a system private class. The right way to create an instance of this class is + * using the factory Context.getSystemService. */ public HdmiControlManager(IHdmiControlService service) { mService = service; @@ -340,6 +343,9 @@ public final class HdmiControlManager { void onReceived(HdmiHotplugEvent event); } + private final ArrayMap<HotplugEventListener, IHdmiHotplugEventListener> + mHotplugEventListeners = new ArrayMap<>(); + /** * Listener used to get vendor-specific commands. */ @@ -384,12 +390,19 @@ public final class HdmiControlManager { */ public void addHotplugEventListener(HotplugEventListener listener) { if (mService == null) { + Log.e(TAG, "HdmiControlService is not available"); + return; + } + if (mHotplugEventListeners.containsKey(listener)) { + Log.e(TAG, "listener is already registered"); return; } + IHdmiHotplugEventListener wrappedListener = getHotplugEventListenerWrapper(listener); + mHotplugEventListeners.put(listener, wrappedListener); try { - mService.addHotplugEventListener(getHotplugEventListenerWrapper(listener)); + mService.addHotplugEventListener(wrappedListener); } catch (RemoteException e) { - // Do nothing. + Log.e(TAG, "failed to add hotplug event listener: ", e); } } @@ -400,12 +413,18 @@ public final class HdmiControlManager { */ public void removeHotplugEventListener(HotplugEventListener listener) { if (mService == null) { + Log.e(TAG, "HdmiControlService is not available"); + return; + } + IHdmiHotplugEventListener wrappedListener = mHotplugEventListeners.remove(listener); + if (wrappedListener == null) { + Log.e(TAG, "tried to remove not-registered listener"); return; } try { - mService.removeHotplugEventListener(getHotplugEventListenerWrapper(listener)); + mService.removeHotplugEventListener(wrappedListener); } catch (RemoteException e) { - // Do nothing. + Log.e(TAG, "failed to remove hotplug event listener: ", e); } } diff --git a/core/java/android/hardware/hdmi/HdmiDeviceInfo.java b/core/java/android/hardware/hdmi/HdmiDeviceInfo.java index 7abea3696f44..fe414e6b11b5 100644 --- a/core/java/android/hardware/hdmi/HdmiDeviceInfo.java +++ b/core/java/android/hardware/hdmi/HdmiDeviceInfo.java @@ -237,14 +237,14 @@ public class HdmiDeviceInfo implements Parcelable { } /** - * Return the id of the device. + * Returns the id of the device. */ public int getId() { return mId; } /** - * Return the id to be used for CEC device. + * Returns the id to be used for CEC device. * * @param address logical address of CEC device * @return id for CEC device @@ -255,7 +255,7 @@ public class HdmiDeviceInfo implements Parcelable { } /** - * Return the id to be used for MHL device. + * Returns the id to be used for MHL device. * * @param portId port which the MHL device is connected to * @return id for MHL device @@ -266,7 +266,7 @@ public class HdmiDeviceInfo implements Parcelable { } /** - * Return the id to be used for hardware port. + * Returns the id to be used for hardware port. * * @param portId port id * @return id for hardware port @@ -276,28 +276,28 @@ public class HdmiDeviceInfo implements Parcelable { } /** - * Return the CEC logical address of the device. + * Returns the CEC logical address of the device. */ public int getLogicalAddress() { return mLogicalAddress; } /** - * Return the physical address of the device. + * Returns the physical address of the device. */ public int getPhysicalAddress() { return mPhysicalAddress; } /** - * Return the port ID. + * Returns the port ID. */ public int getPortId() { return mPortId; } /** - * Return CEC type of the device. For more details, refer constants between {@link #DEVICE_TV} + * Returns CEC type of the device. For more details, refer constants between {@link #DEVICE_TV} * and {@link #DEVICE_INACTIVE}. */ public int getDeviceType() { @@ -305,7 +305,7 @@ public class HdmiDeviceInfo implements Parcelable { } /** - * Return device's power status. It should be one of the following values. + * Returns device's power status. It should be one of the following values. * <ul> * <li>{@link HdmiControlManager#POWER_STATUS_ON} * <li>{@link HdmiControlManager#POWER_STATUS_STANDBY} @@ -319,21 +319,21 @@ public class HdmiDeviceInfo implements Parcelable { } /** - * Return MHL device id. Return -1 for non-MHL device. + * Returns MHL device id. Return -1 for non-MHL device. */ public int getDeviceId() { return mDeviceId; } /** - * Return MHL adopter id. Return -1 for non-MHL device. + * Returns MHL adopter id. Return -1 for non-MHL device. */ public int getAdopterId() { return mAdopterId; } /** - * Return {@code true} if the device is of a type that can be an input source. + * Returns {@code true} if the device is of a type that can be an input source. */ public boolean isSourceType() { return mDeviceType == DEVICE_PLAYBACK @@ -342,7 +342,7 @@ public class HdmiDeviceInfo implements Parcelable { } /** - * Return {@code true} if the device represents an HDMI-CEC device. {@code false} if the device + * Returns {@code true} if the device represents an HDMI-CEC device. {@code false} if the device * is either MHL or other device. */ public boolean isCecDevice() { @@ -350,7 +350,7 @@ public class HdmiDeviceInfo implements Parcelable { } /** - * Return {@code true} if the device represents an MHL device. {@code false} if the device is + * Returns {@code true} if the device represents an MHL device. {@code false} if the device is * either CEC or other device. */ public boolean isMhlDevice() { @@ -358,14 +358,14 @@ public class HdmiDeviceInfo implements Parcelable { } /** - * Return display (OSD) name of the device. + * Returns display (OSD) name of the device. */ public String getDisplayName() { return mDisplayName; } /** - * Return vendor id of the device. Vendor id is used to distinguish devices built by other + * Returns vendor id of the device. Vendor id is used to distinguish devices built by other * manufactures. This is required for vendor-specific command on CEC standard. */ public int getVendorId() { @@ -373,7 +373,7 @@ public class HdmiDeviceInfo implements Parcelable { } /** - * Describe the kinds of special objects contained in this Parcelable's marshalled + * Describes the kinds of special objects contained in this Parcelable's marshalled * representation. */ @Override @@ -382,7 +382,7 @@ public class HdmiDeviceInfo implements Parcelable { } /** - * Serialize this object into a {@link Parcel}. + * Serializes this object into a {@link Parcel}. * * @param dest The Parcel in which the object should be written. * @param flags Additional flags about how the object should be written. May be 0 or diff --git a/core/java/android/hardware/hdmi/HdmiHotplugEvent.java b/core/java/android/hardware/hdmi/HdmiHotplugEvent.java index 7be4bc57a329..94767428d031 100644 --- a/core/java/android/hardware/hdmi/HdmiHotplugEvent.java +++ b/core/java/android/hardware/hdmi/HdmiHotplugEvent.java @@ -44,7 +44,7 @@ public final class HdmiHotplugEvent implements Parcelable { } /** - * Return the port number for which the event occurred. + * Returns the port number for which the event occurred. * * @return port number */ @@ -53,7 +53,7 @@ public final class HdmiHotplugEvent implements Parcelable { } /** - * Return the connection status associated with this event + * Returns the connection status associated with this event * * @return true if the device gets connected; otherwise false */ @@ -62,7 +62,7 @@ public final class HdmiHotplugEvent implements Parcelable { } /** - * Describe the kinds of special objects contained in this Parcelable's + * Describes the kinds of special objects contained in this Parcelable's * marshalled representation. */ @Override @@ -71,7 +71,7 @@ public final class HdmiHotplugEvent implements Parcelable { } /** - * Flatten this object in to a Parcel. + * Flattens this object in to a Parcel. * * @param dest The Parcel in which the object should be written. * @param flags Additional flags about how the object should be written. @@ -86,17 +86,19 @@ public final class HdmiHotplugEvent implements Parcelable { public static final Parcelable.Creator<HdmiHotplugEvent> CREATOR = new Parcelable.Creator<HdmiHotplugEvent>() { /** - * Rebuild a {@link HdmiHotplugEvent} previously stored with + * Rebuilds a {@link HdmiHotplugEvent} previously stored with * {@link Parcelable#writeToParcel(Parcel, int)}. * * @param p {@link HdmiHotplugEvent} object to read the Rating from * @return a new {@link HdmiHotplugEvent} created from the data in the parcel */ + @Override public HdmiHotplugEvent createFromParcel(Parcel p) { int port = p.readInt(); boolean connected = p.readByte() == 1; return new HdmiHotplugEvent(port, connected); } + @Override public HdmiHotplugEvent[] newArray(int size) { return new HdmiHotplugEvent[size]; } diff --git a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java index 85ccb7455216..263d6b1872ff 100644 --- a/core/java/android/hardware/hdmi/HdmiPlaybackClient.java +++ b/core/java/android/hardware/hdmi/HdmiPlaybackClient.java @@ -64,12 +64,12 @@ public final class HdmiPlaybackClient extends HdmiClient { public void onComplete(int status); } - HdmiPlaybackClient(IHdmiControlService service) { + /* package */ HdmiPlaybackClient(IHdmiControlService service) { super(service); } /** - * Perform the feature 'one touch play' from playback device to turn on display + * Performs the feature 'one touch play' from playback device to turn on display * and switch the input. * * @param callback {@link OneTouchPlayCallback} object to get informed @@ -90,7 +90,7 @@ public final class HdmiPlaybackClient extends HdmiClient { } /** - * Get the status of display device connected through HDMI bus. + * Gets the status of display device connected through HDMI bus. * * @param callback {@link DisplayStatusCallback} object to get informed * of the result diff --git a/core/java/android/hardware/hdmi/HdmiPortInfo.java b/core/java/android/hardware/hdmi/HdmiPortInfo.java index 2ec6126eb7b1..e52baed525a1 100644 --- a/core/java/android/hardware/hdmi/HdmiPortInfo.java +++ b/core/java/android/hardware/hdmi/HdmiPortInfo.java @@ -114,7 +114,7 @@ public final class HdmiPortInfo implements Parcelable { } /** - * Describe the kinds of special objects contained in this Parcelable's + * Describes the kinds of special objects contained in this Parcelable's * marshalled representation. */ @Override @@ -146,7 +146,7 @@ public final class HdmiPortInfo implements Parcelable { }; /** - * Serialize this object into a {@link Parcel}. + * Serializes this object into a {@link Parcel}. * * @param dest The Parcel in which the object should be written. * @param flags Additional flags about how the object should be written. diff --git a/core/java/android/hardware/hdmi/HdmiRecordListener.java b/core/java/android/hardware/hdmi/HdmiRecordListener.java index f6a348a65f68..29f6cfc3a29a 100644 --- a/core/java/android/hardware/hdmi/HdmiRecordListener.java +++ b/core/java/android/hardware/hdmi/HdmiRecordListener.java @@ -25,7 +25,7 @@ import android.hardware.hdmi.HdmiRecordSources.RecordSource; */ @SystemApi public abstract class HdmiRecordListener { - protected HdmiRecordListener() {} + public HdmiRecordListener() {} /** * Called when TV received one touch record request from record device. The client of this @@ -34,7 +34,7 @@ public abstract class HdmiRecordListener { * @param recorderAddress * @return record source to be used for recording. Null if no device is available. */ - public abstract RecordSource getOneTouchRecordSource(int recorderAddress); + public abstract RecordSource onOneTouchRecordSourceRequested(int recorderAddress); /** * Called when one touch record is started or failed during initialization. diff --git a/core/java/android/hardware/hdmi/HdmiRecordSources.java b/core/java/android/hardware/hdmi/HdmiRecordSources.java index c294f72d3425..922b8e7ae14f 100644 --- a/core/java/android/hardware/hdmi/HdmiRecordSources.java +++ b/core/java/android/hardware/hdmi/HdmiRecordSources.java @@ -59,21 +59,21 @@ public final class HdmiRecordSources { */ @SystemApi public static abstract class RecordSource { - protected final int mSourceType; - protected final int mExtraDataSize; + /* package */ final int mSourceType; + /* package */ final int mExtraDataSize; - protected RecordSource(int sourceType, int extraDataSize) { + /* package */ RecordSource(int sourceType, int extraDataSize) { mSourceType = sourceType; mExtraDataSize = extraDataSize; } - abstract int extraParamToByteArray(byte[] data, int index); + /* package */ abstract int extraParamToByteArray(byte[] data, int index); - final int getDataSize(boolean includeType) { + /* package */ final int getDataSize(boolean includeType) { return includeType ? mExtraDataSize + 1 : mExtraDataSize; } - final int toByteArray(boolean includeType, byte[] data, int index) { + /* package */ final int toByteArray(boolean includeType, byte[] data, int index) { if (includeType) { // 1 to 8 bytes (depends on source). // {[Record Source Type]} | @@ -94,7 +94,7 @@ public final class HdmiRecordSources { // ---- Own source ----------------------------------------------------------------------------- // --------------------------------------------------------------------------------------------- /** - * Create {@link OwnSource} of own source. + * Creates {@link OwnSource} of own source. */ public static OwnSource ofOwnSource() { return new OwnSource(); @@ -311,7 +311,7 @@ public final class HdmiRecordSources { */ public static final class DigitalChannelData implements DigitalServiceIdentification { /** Identifies the logical or virtual channel number of a service. */ - private ChannelIdentifier mChannelIdentifier; + private final ChannelIdentifier mChannelIdentifier; public static DigitalChannelData ofTwoNumbers(int majorNumber, int minorNumber) { return new DigitalChannelData( @@ -338,7 +338,7 @@ public final class HdmiRecordSources { } /** - * Create {@link DigitalServiceSource} with channel type. + * Creates {@link DigitalServiceSource} with channel type. * * @param broadcastSystem digital broadcast system. It should be one of * <ul> @@ -389,7 +389,7 @@ public final class HdmiRecordSources { } /** - * Create {@link DigitalServiceSource} of ARIB type. + * Creates {@link DigitalServiceSource} of ARIB type. * * @param aribType ARIB type. It should be one of * <ul> @@ -420,7 +420,7 @@ public final class HdmiRecordSources { } /** - * Create {@link DigitalServiceSource} of ATSC type. + * Creates {@link DigitalServiceSource} of ATSC type. * * @param atscType ATSC type. It should be one of * <ul> @@ -451,7 +451,7 @@ public final class HdmiRecordSources { } /** - * Create {@link DigitalServiceSource} of ATSC type. + * Creates {@link DigitalServiceSource} of ATSC type. * * @param dvbType DVB type. It should be one of * <ul> @@ -572,7 +572,7 @@ public final class HdmiRecordSources { public static final int BROADCAST_SYSTEM_PAL_OTHER_SYSTEM = 31; /** - * Create {@link AnalogueServiceSource} of analogue service. + * Creates {@link AnalogueServiceSource} of analogue service. * * @param broadcastType * @param frequency @@ -615,7 +615,7 @@ public final class HdmiRecordSources { */ @SystemApi public static final class AnalogueServiceSource extends RecordSource { - static final int EXTRA_DATA_SIZE = 4; + /* package */ static final int EXTRA_DATA_SIZE = 4; /** Indicates the Analogue broadcast type. */ private final int mBroadcastType; @@ -635,7 +635,7 @@ public final class HdmiRecordSources { } @Override - protected int extraParamToByteArray(byte[] data, int index) { + /* package */ int extraParamToByteArray(byte[] data, int index) { // [Analogue Broadcast Type] - 1 byte data[index] = (byte) mBroadcastType; // [Analogue Frequency] - 2 bytes @@ -651,7 +651,7 @@ public final class HdmiRecordSources { // ---- External plug data --------------------------------------------------------------------- // --------------------------------------------------------------------------------------------- /** - * Create {@link ExternalPlugData} of external plug type. + * Creates {@link ExternalPlugData} of external plug type. * * @param plugNumber plug number. It should be in range of [1, 255] * @hide @@ -695,7 +695,7 @@ public final class HdmiRecordSources { // ---- External physical address -------------------------------------------------------------- // --------------------------------------------------------------------------------------------- /** - * Create {@link ExternalPhysicalAddress} of external physical address. + * Creates {@link ExternalPhysicalAddress} of external physical address. * * @param physicalAddress * @hide @@ -754,7 +754,7 @@ public final class HdmiRecordSources { } /** - * Check the byte array of record source. + * Checks the byte array of record source. * @hide */ @SystemApi diff --git a/core/java/android/hardware/hdmi/HdmiTimerRecordSources.java b/core/java/android/hardware/hdmi/HdmiTimerRecordSources.java index 178070762ba7..bf97375c8f95 100644 --- a/core/java/android/hardware/hdmi/HdmiTimerRecordSources.java +++ b/core/java/android/hardware/hdmi/HdmiTimerRecordSources.java @@ -67,7 +67,7 @@ public class HdmiTimerRecordSources { private HdmiTimerRecordSources() {} /** - * Create {@link TimerRecordSource} for digital source which is used for <Set Digital + * Creates {@link TimerRecordSource} for digital source which is used for <Set Digital * Timer>. * * @param timerInfo timer info used for timer recording @@ -82,7 +82,7 @@ public class HdmiTimerRecordSources { } /** - * Create {@link TimerRecordSource} for analogue source which is used for <Set Analogue + * Creates {@link TimerRecordSource} for analogue source which is used for <Set Analogue * Timer>. * * @param timerInfo timer info used for timer recording @@ -97,7 +97,7 @@ public class HdmiTimerRecordSources { } /** - * Create {@link TimerRecordSource} for external plug which is used for <Set External + * Creates {@link TimerRecordSource} for external plug which is used for <Set External * Timer>. * * @param timerInfo timer info used for timer recording @@ -112,7 +112,7 @@ public class HdmiTimerRecordSources { } /** - * Create {@link TimerRecordSource} for external physical address which is used for <Set + * Creates {@link TimerRecordSource} for external physical address which is used for <Set * External Timer>. * * @param timerInfo timer info used for timer recording @@ -140,7 +140,7 @@ public class HdmiTimerRecordSources { } /** - * Create {@link Duration} for time value. + * Creates {@link Duration} for time value. * * @param hour hour in range of [0, 23] * @param minute minute in range of [0, 60] @@ -162,7 +162,7 @@ public class HdmiTimerRecordSources { } /** - * Create {@link Duration} for duration value. + * Creates {@link Duration} for duration value. * * @param hour hour in range of [0, 99] * @param minute minute in range of [0, 59] @@ -184,21 +184,21 @@ public class HdmiTimerRecordSources { } private static class TimeUnit { - protected final int mHour; - protected final int mMinute; + /* package */ final int mHour; + /* package */ final int mMinute; - protected TimeUnit(int hour, int minute) { + /* package */ TimeUnit(int hour, int minute) { mHour = hour; mMinute = minute; } - protected int toByteArray(byte[] data, int index) { + /* package */ int toByteArray(byte[] data, int index) { data[index] = toBcdByte(mHour); data[index + 1] = toBcdByte(mMinute); return 2; } - protected static byte toBcdByte(int value) { + /* package */ static byte toBcdByte(int value) { int digitOfTen = (value / 10) % 10; int digitOfOne = value % 10; return (byte) ((digitOfTen << 4) | digitOfOne); @@ -247,7 +247,7 @@ public class HdmiTimerRecordSources { RECORDING_SEQUENCE_REPEAT_SATUREDAY); /** - * Create {@link TimerInfo} with the given information. + * Creates {@link TimerInfo} with the given information. * * @param dayOfMonth day of month * @param monthOfYear month of year @@ -426,7 +426,7 @@ public class HdmiTimerRecordSources { } /** - * Check the byte array of timer record source. + * Checks the byte array of timer record source. * @param sourcetype * @param recordSource * @hide diff --git a/core/java/android/hardware/hdmi/HdmiTvClient.java b/core/java/android/hardware/hdmi/HdmiTvClient.java index 683d04b3ef5d..dbfb4efe52a3 100644 --- a/core/java/android/hardware/hdmi/HdmiTvClient.java +++ b/core/java/android/hardware/hdmi/HdmiTvClient.java @@ -22,11 +22,11 @@ import android.hardware.hdmi.HdmiTimerRecordSources.TimerRecordSource; import android.os.RemoteException; import android.util.Log; +import libcore.util.EmptyArray; + import java.util.Collections; import java.util.List; -import libcore.util.EmptyArray; - /** * HdmiTvClient represents HDMI-CEC logical device of type TV in the Android system * which acts as TV/Display. It provides with methods that manage, interact with other @@ -43,13 +43,13 @@ public final class HdmiTvClient extends HdmiClient { */ public static final int VENDOR_DATA_SIZE = 16; - HdmiTvClient(IHdmiControlService service) { + /* package */ HdmiTvClient(IHdmiControlService service) { super(service); } // Factory method for HdmiTvClient. // Declared package-private. Accessed by HdmiControlManager only. - static HdmiTvClient create(IHdmiControlService service) { + /* package */ static HdmiTvClient create(IHdmiControlService service) { return new HdmiTvClient(service); } @@ -71,7 +71,7 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Select a CEC logical device to be a new active source. + * Selects a CEC logical device to be a new active source. * * @param logicalAddress logical address of the device to select * @param callback callback to get the result with @@ -98,7 +98,7 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Select a HDMI port to be a new route path. + * Selects a HDMI port to be a new route path. * * @param portId HDMI port to select * @param callback callback to get the result with @@ -128,7 +128,7 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Set the listener used to get informed of the input change event. + * Sets the listener used to get informed of the input change event. * * @param listener listener object */ @@ -168,7 +168,7 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Set system audio volume + * Sets system audio volume * * @param oldIndex current volume index * @param newIndex volume index to be set @@ -183,7 +183,7 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Set system audio mute status + * Sets system audio mute status * * @param mute {@code true} if muted; otherwise, {@code false} */ @@ -196,7 +196,7 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Set record listener + * Sets record listener * * @param listener */ @@ -216,7 +216,7 @@ public final class HdmiTvClient extends HdmiClient { @Override public byte[] getOneTouchRecordSource(int recorderAddress) { HdmiRecordSources.RecordSource source = - callback.getOneTouchRecordSource(recorderAddress); + callback.onOneTouchRecordSourceRequested(recorderAddress); if (source == null) { return EmptyArray.BYTE; } @@ -244,13 +244,13 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Start one touch recording with the given recorder address and recorder source. + * Starts one touch recording with the given recorder address and recorder source. * <p> * Usage * <pre> * HdmiTvClient tvClient = ....; * // for own source. - * OwnSource ownSource = ownHdmiRecordSources.ownSource(); + * OwnSource ownSource = HdmiRecordSources.ofOwnSource(); * tvClient.startOneTouchRecord(recorderAddress, ownSource); * </pre> */ @@ -269,7 +269,7 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Stop one touch record. + * Stops one touch record. * * @param recorderAddress recorder address where recoding will be stopped */ @@ -282,7 +282,7 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Start timer recording with the given recoder address and recorder source. + * Starts timer recording with the given recoder address and recorder source. * <p> * Usage * <pre> @@ -331,7 +331,7 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Clear timer recording with the given recorder address and recording source. + * Clears timer recording with the given recorder address and recording source. * For more details, please refer {@link #startTimerRecording(int, int, TimerRecordSource)}. */ public void clearTimerRecording(int recorderAddress, int sourceType, TimerRecordSource source) { @@ -357,7 +357,7 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Set {@link HdmiMhlVendorCommandListener} to get incoming MHL vendor command. + * Sets {@link HdmiMhlVendorCommandListener} to get incoming MHL vendor command. * * @param listener to receive incoming MHL vendor command */ @@ -383,7 +383,7 @@ public final class HdmiTvClient extends HdmiClient { } /** - * Send MHL vendor command to the device connected to a port of the given portId. + * Sends MHL vendor command to the device connected to a port of the given portId. * * @param portId id of port to send MHL vendor command * @param offset offset in the in given data diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java index 58f0fc047dd8..4fa0593c5e13 100644 --- a/core/java/android/net/Network.java +++ b/core/java/android/net/Network.java @@ -21,7 +21,9 @@ import android.os.Parcelable; import android.os.Parcel; import android.system.ErrnoException; +import java.io.FileDescriptor; import java.io.IOException; +import java.net.DatagramSocket; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.MalformedURLException; @@ -264,18 +266,40 @@ public class Network implements Parcelable { } /** + * Binds the specified {@link DatagramSocket} to this {@code Network}. All data traffic on the + * socket will be sent on this {@code Network}, irrespective of any process-wide network binding + * set by {@link ConnectivityManager#setProcessDefaultNetwork}. The socket must not be + * connected. + */ + public void bindSocket(DatagramSocket socket) throws IOException { + // Apparently, the kernel doesn't update a connected UDP socket's routing upon mark changes. + if (socket.isConnected()) { + throw new SocketException("Socket is connected"); + } + // Query a property of the underlying socket to ensure that the socket's file descriptor + // exists, is available to bind to a network and is not closed. + socket.getReuseAddress(); + bindSocketFd(socket.getFileDescriptor$()); + } + + /** * Binds the specified {@link Socket} to this {@code Network}. All data traffic on the socket * will be sent on this {@code Network}, irrespective of any process-wide network binding set by * {@link ConnectivityManager#setProcessDefaultNetwork}. The socket must not be connected. */ public void bindSocket(Socket socket) throws IOException { + // Apparently, the kernel doesn't update a connected TCP socket's routing upon mark changes. if (socket.isConnected()) { throw new SocketException("Socket is connected"); } - // Query a property of the underlying socket to ensure the underlying - // socket exists so a file descriptor is available to bind to a network. + // Query a property of the underlying socket to ensure that the socket's file descriptor + // exists, is available to bind to a network and is not closed. socket.getReuseAddress(); - int err = NetworkUtils.bindSocketToNetwork(socket.getFileDescriptor$().getInt$(), netId); + bindSocketFd(socket.getFileDescriptor$()); + } + + private void bindSocketFd(FileDescriptor fd) throws IOException { + int err = NetworkUtils.bindSocketToNetwork(fd.getInt$(), netId); if (err != 0) { // bindSocketToNetwork returns negative errno. throw new ErrnoException("Binding socket to network " + netId, -err) diff --git a/core/java/android/net/Proxy.java b/core/java/android/net/Proxy.java index 6a78c29c15ac..3477b029f793 100644 --- a/core/java/android/net/Proxy.java +++ b/core/java/android/net/Proxy.java @@ -19,17 +19,10 @@ package android.net; import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.content.Context; -import android.net.ProxyInfo; import android.text.TextUtils; import android.util.Log; - import org.apache.http.HttpHost; -import org.apache.http.HttpRequest; -import org.apache.http.conn.routing.HttpRoute; -import org.apache.http.conn.routing.HttpRoutePlanner; -import org.apache.http.conn.scheme.SchemeRegistry; -import org.apache.http.protocol.HttpContext; import java.net.InetSocketAddress; import java.net.ProxySelector; @@ -212,6 +205,7 @@ public final class Proxy { * is no proxy. * {@hide} */ + // TODO: Get rid of this method. It's used only in tests. public static final HttpHost getPreferredHttpHost(Context context, String url) { java.net.Proxy prefProxy = getProxy(context, url); diff --git a/core/java/android/net/ProxyInfo.java b/core/java/android/net/ProxyInfo.java index 1534e2c7f4b1..7694420e7065 100644 --- a/core/java/android/net/ProxyInfo.java +++ b/core/java/android/net/ProxyInfo.java @@ -36,7 +36,13 @@ import java.util.Locale; * * Other HTTP stacks will need to obtain the proxy info from * {@link Proxy#PROXY_CHANGE_ACTION} broadcast as the extra {@link Proxy#EXTRA_PROXY_INFO}. + * + * @deprecated Please use {@link java.net.URL#openConnection}, {@link java.net.Proxy} and + * friends. The Apache HTTP client is no longer maintained and may be removed in a future + * release. Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> + * for further details. */ +@Deprecated public class ProxyInfo implements Parcelable { private String mHost; diff --git a/core/java/android/net/SSLCertificateSocketFactory.java b/core/java/android/net/SSLCertificateSocketFactory.java index b0278d39e072..c15e6e55ab45 100644 --- a/core/java/android/net/SSLCertificateSocketFactory.java +++ b/core/java/android/net/SSLCertificateSocketFactory.java @@ -154,7 +154,13 @@ public class SSLCertificateSocketFactory extends SSLSocketFactory { * for none. The socket timeout is reset to 0 after the handshake. * @param cache The {@link SSLSessionCache} to use, or null for no cache. * @return a new SocketFactory with the specified parameters + * + * @deprecated Use {@link #getDefault()} along with a {@link javax.net.ssl.HttpsURLConnection} + * instead. The Apache HTTP client is no longer maintained and may be removed in a future + * release. Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> + * for further details. */ + @Deprecated public static org.apache.http.conn.ssl.SSLSocketFactory getHttpSocketFactory( int handshakeTimeoutMillis, SSLSessionCache cache) { return new org.apache.http.conn.ssl.SSLSocketFactory( diff --git a/core/java/android/net/http/AndroidHttpClient.java b/core/java/android/net/http/AndroidHttpClient.java index 04f3974f4132..a26207666283 100644 --- a/core/java/android/net/http/AndroidHttpClient.java +++ b/core/java/android/net/http/AndroidHttpClient.java @@ -74,7 +74,13 @@ import java.util.zip.GZIPOutputStream; * To retain cookies, simply add a cookie store to the HttpContext:</p> * * <pre>context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);</pre> + * + * @deprecated Please use {@link java.net.URLConnection} and friends instead. + * The Apache HTTP client is no longer maintained and may be removed in a future + * release. Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> + * for further details. */ +@Deprecated public final class AndroidHttpClient implements HttpClient { // Gzip of data shorter than this probably won't be worthwhile @@ -108,7 +114,13 @@ public final class AndroidHttpClient implements HttpClient { * @param userAgent to report in your HTTP requests * @param context to use for caching SSL sessions (may be null for no caching) * @return AndroidHttpClient for you to use for all your requests. + * + * @deprecated Please use {@link java.net.URLConnection} and friends instead. See + * {@link android.net.SSLCertificateSocketFactory} for SSL cache support. If you'd + * like to set a custom useragent, please use {@link java.net.URLConnection#setRequestProperty(String, String)} + * with {@code field} set to {@code User-Agent}. */ + @Deprecated public static AndroidHttpClient newInstance(String userAgent, Context context) { HttpParams params = new BasicHttpParams(); @@ -148,7 +160,13 @@ public final class AndroidHttpClient implements HttpClient { * Create a new HttpClient with reasonable defaults (which you can update). * @param userAgent to report in your HTTP requests. * @return AndroidHttpClient for you to use for all your requests. + * + * @deprecated Please use {@link java.net.URLConnection} and friends instead. See + * {@link android.net.SSLCertificateSocketFactory} for SSL cache support. If you'd + * like to set a custom useragent, please use {@link java.net.URLConnection#setRequestProperty(String, String)} + * with {@code field} set to {@code User-Agent}. */ + @Deprecated public static AndroidHttpClient newInstance(String userAgent) { return newInstance(userAgent, null /* session cache */); } diff --git a/core/java/android/preference/ListPreference.java b/core/java/android/preference/ListPreference.java index 8081a5496399..9482a72a2f7c 100644 --- a/core/java/android/preference/ListPreference.java +++ b/core/java/android/preference/ListPreference.java @@ -162,10 +162,10 @@ public class ListPreference extends DialogPreference { @Override public CharSequence getSummary() { final CharSequence entry = getEntry(); - if (mSummary == null || entry == null) { + if (mSummary == null) { return super.getSummary(); } else { - return String.format(mSummary, entry); + return String.format(mSummary, entry == null ? "" : entry); } } diff --git a/core/java/android/preference/SeekBarVolumizer.java b/core/java/android/preference/SeekBarVolumizer.java index a680b51ee6de..3130b6465621 100644 --- a/core/java/android/preference/SeekBarVolumizer.java +++ b/core/java/android/preference/SeekBarVolumizer.java @@ -130,6 +130,7 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba } private void postStartSample() { + if (mHandler == null) return; mHandler.removeMessages(MSG_START_SAMPLE); mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_SAMPLE), isSamplePlaying() ? CHECK_RINGTONE_PLAYBACK_DELAY_MS : 0); @@ -150,7 +151,8 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba } } - void postStopSample() { + private void postStopSample() { + if (mHandler == null) return; // remove pending delayed start messages mHandler.removeMessages(MSG_START_SAMPLE); mHandler.removeMessages(MSG_STOP_SAMPLE); @@ -200,7 +202,8 @@ public class SeekBarVolumizer implements OnSeekBarChangeListener, Handler.Callba postSetVolume(progress); } - void postSetVolume(int progress) { + private void postSetVolume(int progress) { + if (mHandler == null) return; // Do the volume changing separately to give responsive UI mLastProgress = progress; mHandler.removeMessages(MSG_SET_STREAM_VOLUME); diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java index 86d96f21c60f..0d4c0b6d0152 100644 --- a/core/java/android/preference/VolumePreference.java +++ b/core/java/android/preference/VolumePreference.java @@ -117,7 +117,7 @@ public class VolumePreference extends SeekBarDialogPreference implements public void onActivityStop() { if (mSeekBarVolumizer != null) { - mSeekBarVolumizer.postStopSample(); + mSeekBarVolumizer.stopSample(); } } diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index 75c435ea2f64..a1652797a842 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -3017,7 +3017,6 @@ public final class Settings { MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_ENABLED); MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES); MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_POLL_INTERVAL); - MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_REPORT_XT_OVER_DEV); MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_SAMPLE_ENABLED); MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_TIME_CACHE_MAX_AGE); MOVED_TO_GLOBAL.add(Settings.Global.NETSTATS_UID_BUCKET_DURATION); @@ -5095,6 +5094,12 @@ public final class Settings { public static final String AIRPLANE_MODE_ON = "airplane_mode_on"; /** + * Whether Theater Mode is on. + * {@hide} + */ + public static final String THEATER_MODE_ON = "theater_mode_on"; + + /** * Constant for use in AIRPLANE_MODE_RADIOS to specify Bluetooth radio. */ public static final String RADIO_BLUETOOTH = "bluetooth"; @@ -5456,8 +5461,6 @@ public final class Settings { public static final String NETSTATS_GLOBAL_ALERT_BYTES = "netstats_global_alert_bytes"; /** {@hide} */ public static final String NETSTATS_SAMPLE_ENABLED = "netstats_sample_enabled"; - /** {@hide} */ - public static final String NETSTATS_REPORT_XT_OVER_DEV = "netstats_report_xt_over_dev"; /** {@hide} */ public static final String NETSTATS_DEV_BUCKET_DURATION = "netstats_dev_bucket_duration"; @@ -6593,7 +6596,7 @@ public final class Settings { * Type: int (0 for false, 1 for true) * @hide */ - public static final String VOLTE_VT_ENABLED = "volte_vt_enabled"; + public static final String ENHANCED_4G_MODE_ENABLED = "volte_vt_enabled"; /** * Settings to backup. This is here so that it's in the same place as the settings diff --git a/core/java/android/text/format/Time.java b/core/java/android/text/format/Time.java index aa6ad2048719..1e04eb45471d 100644 --- a/core/java/android/text/format/Time.java +++ b/core/java/android/text/format/Time.java @@ -48,7 +48,10 @@ import libcore.util.ZoneInfoDB; * <li>Much of the formatting / parsing assumes ASCII text and is therefore not suitable for * use with non-ASCII scripts.</li> * </ul> + * + * @deprecated Use {@link java.util.GregorianCalendar} instead. */ +@Deprecated public class Time { private static final String Y_M_D_T_H_M_S_000 = "%Y-%m-%dT%H:%M:%S.000"; private static final String Y_M_D_T_H_M_S_000_Z = "%Y-%m-%dT%H:%M:%S.000Z"; diff --git a/core/java/android/transition/ChangeBounds.java b/core/java/android/transition/ChangeBounds.java index 0da5fb6d91bc..c82587b76fe1 100644 --- a/core/java/android/transition/ChangeBounds.java +++ b/core/java/android/transition/ChangeBounds.java @@ -16,7 +16,9 @@ package android.transition; +import android.animation.AnimatorSet; import android.content.Context; +import android.content.res.TypedArray; import android.graphics.PointF; import android.animation.Animator; @@ -31,11 +33,12 @@ import android.graphics.Rect; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.AttributeSet; -import android.util.IntProperty; import android.util.Property; import android.view.View; import android.view.ViewGroup; +import com.android.internal.R; + import java.util.Map; /** @@ -43,17 +46,20 @@ import java.util.Map; * the scene change and animates those changes during the transition. * * <p>A ChangeBounds transition can be described in a resource file by using the - * tag <code>changeBounds</code>, along with the other standard + * tag <code>changeBounds</code>, using its attributes of + * {@link android.R.styleable#ChangeBounds} along with the other standard * attributes of {@link android.R.styleable#Transition}.</p> */ public class ChangeBounds extends Transition { private static final String PROPNAME_BOUNDS = "android:changeBounds:bounds"; + private static final String PROPNAME_CLIP = "android:changeBounds:clip"; private static final String PROPNAME_PARENT = "android:changeBounds:parent"; private static final String PROPNAME_WINDOW_X = "android:changeBounds:windowX"; private static final String PROPNAME_WINDOW_Y = "android:changeBounds:windowY"; private static final String[] sTransitionProperties = { PROPNAME_BOUNDS, + PROPNAME_CLIP, PROPNAME_PARENT, PROPNAME_WINDOW_X, PROPNAME_WINDOW_Y @@ -77,6 +83,83 @@ public class ChangeBounds extends Transition { } }; + private static final Property<ViewBounds, PointF> TOP_LEFT_PROPERTY = + new Property<ViewBounds, PointF>(PointF.class, "topLeft") { + @Override + public void set(ViewBounds viewBounds, PointF topLeft) { + viewBounds.setTopLeft(topLeft); + } + + @Override + public PointF get(ViewBounds viewBounds) { + return null; + } + }; + + private static final Property<ViewBounds, PointF> BOTTOM_RIGHT_PROPERTY = + new Property<ViewBounds, PointF>(PointF.class, "bottomRight") { + @Override + public void set(ViewBounds viewBounds, PointF bottomRight) { + viewBounds.setBottomRight(bottomRight); + } + + @Override + public PointF get(ViewBounds viewBounds) { + return null; + } + }; + + private static final Property<View, PointF> BOTTOM_RIGHT_ONLY_PROPERTY = + new Property<View, PointF>(PointF.class, "bottomRight") { + @Override + public void set(View view, PointF bottomRight) { + int left = view.getLeft(); + int top = view.getTop(); + int right = Math.round(bottomRight.x); + int bottom = Math.round(bottomRight.y); + view.setLeftTopRightBottom(left, top, right, bottom); + } + + @Override + public PointF get(View view) { + return null; + } + }; + + private static final Property<View, PointF> TOP_LEFT_ONLY_PROPERTY = + new Property<View, PointF>(PointF.class, "topLeft") { + @Override + public void set(View view, PointF topLeft) { + int left = Math.round(topLeft.x); + int top = Math.round(topLeft.y); + int right = view.getRight(); + int bottom = view.getBottom(); + view.setLeftTopRightBottom(left, top, right, bottom); + } + + @Override + public PointF get(View view) { + return null; + } + }; + + private static final Property<View, PointF> POSITION_PROPERTY = + new Property<View, PointF>(PointF.class, "position") { + @Override + public void set(View view, PointF topLeft) { + int left = Math.round(topLeft.x); + int top = Math.round(topLeft.y); + int right = left + view.getWidth(); + int bottom = top + view.getHeight(); + view.setLeftTopRightBottom(left, top, right, bottom); + } + + @Override + public PointF get(View view) { + return null; + } + }; + int[] tempLocation = new int[2]; boolean mResizeClip = false; boolean mReparent = false; @@ -88,6 +171,11 @@ public class ChangeBounds extends Transition { public ChangeBounds(Context context, AttributeSet attrs) { super(context, attrs); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ChangeBounds); + boolean resizeClip = a.getBoolean(R.styleable.ChangeBounds_resizeClip, false); + a.recycle(); + setResizeClip(resizeClip); } @Override @@ -95,11 +183,37 @@ public class ChangeBounds extends Transition { return sTransitionProperties; } + /** + * When <code>resizeClip</code> is true, ChangeBounds resizes the view using the clipBounds + * instead of changing the dimensions of the view during the animation. When + * <code>resizeClip</code> is false, ChangeBounds resizes the View by changing its dimensions. + * + * <p>When resizeClip is set to true, the clip bounds is modified by ChangeBounds. Therefore, + * {@link android.transition.ChangeClipBounds} is not compatible with ChangeBounds + * in this mode.</p> + * + * @param resizeClip Used to indicate whether the view bounds should be modified or the + * clip bounds should be modified by ChangeBounds. + * @see android.view.View#setClipBounds(android.graphics.Rect) + * @attr ref android.R.styleable#ChangeBounds_resizeClip + */ public void setResizeClip(boolean resizeClip) { mResizeClip = resizeClip; } /** + * Returns true when the ChangeBounds will resize by changing the clip bounds during the + * view animation or false when bounds are changed. The default value is false. + * + * @return true when the ChangeBounds will resize by changing the clip bounds during the + * view animation or false when bounds are changed. The default value is false. + * @attr ref android.R.styleable#ChangeBounds_resizeClip + */ + public boolean getResizeClip() { + return mResizeClip; + } + + /** * Setting this flag tells ChangeBounds to track the before/after parent * of every view using this transition. The flag is not enabled by * default because it requires the parent instances to be the same @@ -127,6 +241,9 @@ public class ChangeBounds extends Transition { values.values.put(PROPNAME_WINDOW_X, tempLocation[0]); values.values.put(PROPNAME_WINDOW_Y, tempLocation[1]); } + if (mResizeClip) { + values.values.put(PROPNAME_CLIP, view.getClipBounds()); + } } } @@ -170,158 +287,149 @@ public class ChangeBounds extends Transition { if (parentMatches(startParent, endParent)) { Rect startBounds = (Rect) startValues.values.get(PROPNAME_BOUNDS); Rect endBounds = (Rect) endValues.values.get(PROPNAME_BOUNDS); - int startLeft = startBounds.left; - int endLeft = endBounds.left; - int startTop = startBounds.top; - int endTop = endBounds.top; - int startRight = startBounds.right; - int endRight = endBounds.right; - int startBottom = startBounds.bottom; - int endBottom = endBounds.bottom; - int startWidth = startRight - startLeft; - int startHeight = startBottom - startTop; - int endWidth = endRight - endLeft; - int endHeight = endBottom - endTop; + final int startLeft = startBounds.left; + final int endLeft = endBounds.left; + final int startTop = startBounds.top; + final int endTop = endBounds.top; + final int startRight = startBounds.right; + final int endRight = endBounds.right; + final int startBottom = startBounds.bottom; + final int endBottom = endBounds.bottom; + final int startWidth = startRight - startLeft; + final int startHeight = startBottom - startTop; + final int endWidth = endRight - endLeft; + final int endHeight = endBottom - endTop; + Rect startClip = (Rect) startValues.values.get(PROPNAME_CLIP); + Rect endClip = (Rect) endValues.values.get(PROPNAME_CLIP); int numChanges = 0; if ((startWidth != 0 && startHeight != 0) || (endWidth != 0 && endHeight != 0)) { if (startLeft != endLeft || startTop != endTop) ++numChanges; if (startRight != endRight || startBottom != endBottom) ++numChanges; } + if ((startClip != null && !startClip.equals(endClip)) || + (startClip == null && endClip != null)) { + ++numChanges; + } if (numChanges > 0) { + Animator anim; if (!mResizeClip) { - Animator anim; - if (startWidth == endWidth && startHeight == endHeight) { - view.offsetLeftAndRight(startLeft - view.getLeft()); - view.offsetTopAndBottom(startTop - view.getTop()); - Path positionPath = getPathMotion().getPath(0, 0, endLeft - startLeft, - endTop - startTop); - anim = ObjectAnimator.ofInt(view, new HorizontalOffsetProperty(), - new VerticalOffsetProperty(), positionPath); - } else { - if (startLeft != endLeft) view.setLeft(startLeft); - if (startTop != endTop) view.setTop(startTop); - if (startRight != endRight) view.setRight(startRight); - if (startBottom != endBottom) view.setBottom(startBottom); - ObjectAnimator topLeftAnimator = null; - if (startLeft != endLeft || startTop != endTop) { + view.setLeftTopRightBottom(startLeft, startTop, startRight, startBottom); + if (numChanges == 2) { + if (startWidth == endWidth && startHeight == endHeight) { + Path topLeftPath = getPathMotion().getPath(startLeft, startTop, endLeft, + endTop); + anim = ObjectAnimator.ofObject(view, POSITION_PROPERTY, null, + topLeftPath); + } else { + final ViewBounds viewBounds = new ViewBounds(view); Path topLeftPath = getPathMotion().getPath(startLeft, startTop, endLeft, endTop); - topLeftAnimator = ObjectAnimator - .ofInt(view, "left", "top", topLeftPath); - } - ObjectAnimator bottomRightAnimator = null; - if (startRight != endRight || startBottom != endBottom) { + ObjectAnimator topLeftAnimator = ObjectAnimator + .ofObject(viewBounds, TOP_LEFT_PROPERTY, null, topLeftPath); + Path bottomRightPath = getPathMotion().getPath(startRight, startBottom, endRight, endBottom); - bottomRightAnimator = ObjectAnimator.ofInt(view, "right", "bottom", - bottomRightPath); + ObjectAnimator bottomRightAnimator = ObjectAnimator.ofObject(viewBounds, + BOTTOM_RIGHT_PROPERTY, null, bottomRightPath); + AnimatorSet set = new AnimatorSet(); + set.playTogether(topLeftAnimator, bottomRightAnimator); + anim = set; + set.addListener(new AnimatorListenerAdapter() { + // We need a strong reference to viewBounds until the + // animator ends. + private ViewBounds mViewBounds = viewBounds; + }); } - anim = TransitionUtils.mergeAnimators(topLeftAnimator, - bottomRightAnimator); - } - if (view.getParent() instanceof ViewGroup) { - final ViewGroup parent = (ViewGroup) view.getParent(); - parent.suppressLayout(true); - TransitionListener transitionListener = new TransitionListenerAdapter() { - boolean mCanceled = false; - - @Override - public void onTransitionCancel(Transition transition) { - parent.suppressLayout(false); - mCanceled = true; - } - - @Override - public void onTransitionEnd(Transition transition) { - if (!mCanceled) { - parent.suppressLayout(false); - } - } - - @Override - public void onTransitionPause(Transition transition) { - parent.suppressLayout(false); - } - - @Override - public void onTransitionResume(Transition transition) { - parent.suppressLayout(true); - } - }; - addListener(transitionListener); + } else if (startLeft != endLeft || startTop != endTop) { + Path topLeftPath = getPathMotion().getPath(startLeft, startTop, + endLeft, endTop); + anim = ObjectAnimator.ofObject(view, TOP_LEFT_ONLY_PROPERTY, null, + topLeftPath); + } else { + Path bottomRight = getPathMotion().getPath(startRight, startBottom, + endRight, endBottom); + anim = ObjectAnimator.ofObject(view, BOTTOM_RIGHT_ONLY_PROPERTY, null, + bottomRight); } - return anim; } else { - if (startWidth != endWidth) view.setRight(endLeft + - Math.max(startWidth, endWidth)); - if (startHeight != endHeight) view.setBottom(endTop + - Math.max(startHeight, endHeight)); - // TODO: don't clobber TX/TY - if (startLeft != endLeft) view.setTranslationX(startLeft - endLeft); - if (startTop != endTop) view.setTranslationY(startTop - endTop); - // Animate location with translationX/Y and size with clip bounds - float transXDelta = endLeft - startLeft; - float transYDelta = endTop - startTop; - int widthDelta = endWidth - startWidth; - int heightDelta = endHeight - startHeight; - numChanges = 0; - if (transXDelta != 0) numChanges++; - if (transYDelta != 0) numChanges++; - if (widthDelta != 0 || heightDelta != 0) numChanges++; - ObjectAnimator translationAnimator = null; - if (transXDelta != 0 || transYDelta != 0) { - Path topLeftPath = getPathMotion().getPath(0, 0, transXDelta, transYDelta); - translationAnimator = ObjectAnimator.ofFloat(view, View.TRANSLATION_X, - View.TRANSLATION_Y, topLeftPath); + int maxWidth = Math.max(startWidth, endWidth); + int maxHeight = Math.max(startHeight, endHeight); + + view.setLeftTopRightBottom(startLeft, startTop, startLeft + maxWidth, + startTop + maxHeight); + + ObjectAnimator positionAnimator = null; + if (startLeft != endLeft || startTop != endTop) { + Path topLeftPath = getPathMotion().getPath(startLeft, startTop, endLeft, + endTop); + positionAnimator = ObjectAnimator.ofObject(view, POSITION_PROPERTY, null, + topLeftPath); + } + final Rect finalClip = endClip; + if (startClip == null) { + startClip = new Rect(0, 0, startWidth, startHeight); + } + if (endClip == null) { + endClip = new Rect(0, 0, endWidth, endHeight); } ObjectAnimator clipAnimator = null; - if (widthDelta != 0 || heightDelta != 0) { - Rect tempStartBounds = new Rect(0, 0, startWidth, startHeight); - Rect tempEndBounds = new Rect(0, 0, endWidth, endHeight); + if (!startClip.equals(endClip)) { + view.setClipBounds(startClip); clipAnimator = ObjectAnimator.ofObject(view, "clipBounds", sRectEvaluator, - tempStartBounds, tempEndBounds); - } - Animator anim = TransitionUtils.mergeAnimators(translationAnimator, - clipAnimator); - if (view.getParent() instanceof ViewGroup) { - final ViewGroup parent = (ViewGroup) view.getParent(); - parent.suppressLayout(true); - TransitionListener transitionListener = new TransitionListenerAdapter() { - boolean mCanceled = false; + startClip, endClip); + clipAnimator.addListener(new AnimatorListenerAdapter() { + private boolean mIsCanceled; @Override - public void onTransitionCancel(Transition transition) { - parent.suppressLayout(false); - mCanceled = true; + public void onAnimationCancel(Animator animation) { + mIsCanceled = true; } @Override - public void onTransitionEnd(Transition transition) { - if (!mCanceled) { - parent.suppressLayout(false); + public void onAnimationEnd(Animator animation) { + if (!mIsCanceled) { + view.setClipBounds(finalClip); + view.setLeftTopRightBottom(endLeft, endTop, endRight, + endBottom); } } + }); + } + anim = TransitionUtils.mergeAnimators(positionAnimator, + clipAnimator); + } + if (view.getParent() instanceof ViewGroup) { + final ViewGroup parent = (ViewGroup) view.getParent(); + parent.suppressLayout(true); + TransitionListener transitionListener = new TransitionListenerAdapter() { + boolean mCanceled = false; - @Override - public void onTransitionPause(Transition transition) { + @Override + public void onTransitionCancel(Transition transition) { + parent.suppressLayout(false); + mCanceled = true; + } + + @Override + public void onTransitionEnd(Transition transition) { + if (!mCanceled) { parent.suppressLayout(false); } + } + + @Override + public void onTransitionPause(Transition transition) { + parent.suppressLayout(false); + } - @Override - public void onTransitionResume(Transition transition) { - parent.suppressLayout(true); - } - }; - addListener(transitionListener); - } - anim.addListener(new AnimatorListenerAdapter() { @Override - public void onAnimationEnd(Animator animation) { - view.setClipBounds(null); + public void onTransitionResume(Transition transition) { + parent.suppressLayout(true); } - }); - return anim; + }; + addListener(transitionListener); } + return anim; } } else { int startX = (Integer) startValues.values.get(PROPNAME_WINDOW_X); @@ -357,47 +465,41 @@ public class ChangeBounds extends Transition { return null; } - private abstract static class OffsetProperty extends IntProperty<View> { - int mPreviousValue; - - public OffsetProperty(String name) { - super(name); - } - - @Override - public void setValue(View view, int value) { - int offset = value - mPreviousValue; - offsetBy(view, offset); - mPreviousValue = value; - } - - @Override - public Integer get(View object) { - return null; - } - - protected abstract void offsetBy(View view, int by); - } - - private static class HorizontalOffsetProperty extends OffsetProperty { - public HorizontalOffsetProperty() { - super("offsetLeftAndRight"); + private static class ViewBounds { + private int mLeft; + private int mTop; + private int mRight; + private int mBottom; + private boolean mIsTopLeftSet; + private boolean mIsBottomRightSet; + private View mView; + + public ViewBounds(View view) { + mView = view; } - @Override - protected void offsetBy(View view, int by) { - view.offsetLeftAndRight(by); + public void setTopLeft(PointF topLeft) { + mLeft = Math.round(topLeft.x); + mTop = Math.round(topLeft.y); + mIsTopLeftSet = true; + if (mIsBottomRightSet) { + setLeftTopRightBottom(); + } } - } - private static class VerticalOffsetProperty extends OffsetProperty { - public VerticalOffsetProperty() { - super("offsetTopAndBottom"); + public void setBottomRight(PointF bottomRight) { + mRight = Math.round(bottomRight.x); + mBottom = Math.round(bottomRight.y); + mIsBottomRightSet = true; + if (mIsTopLeftSet) { + setLeftTopRightBottom(); + } } - @Override - protected void offsetBy(View view, int by) { - view.offsetTopAndBottom(by); + private void setLeftTopRightBottom() { + mView.setLeftTopRightBottom(mLeft, mTop, mRight, mBottom); + mIsTopLeftSet = false; + mIsBottomRightSet = false; } } } diff --git a/core/java/android/transition/Transition.java b/core/java/android/transition/Transition.java index 6dede46df311..e99c2cfeedd7 100644 --- a/core/java/android/transition/Transition.java +++ b/core/java/android/transition/Transition.java @@ -1790,6 +1790,10 @@ public abstract class Transition implements Cloneable { private static boolean isValueChanged(TransitionValues oldValues, TransitionValues newValues, String key) { + if (oldValues.values.containsKey(key) != newValues.values.containsKey(key)) { + // The transition didn't care about this particular value, so we don't care, either. + return false; + } Object oldValue = oldValues.values.get(key); Object newValue = newValues.values.get(key); boolean changed; diff --git a/core/java/android/transition/TransitionUtils.java b/core/java/android/transition/TransitionUtils.java index 03423ffefaa4..49ceb3b5365e 100644 --- a/core/java/android/transition/TransitionUtils.java +++ b/core/java/android/transition/TransitionUtils.java @@ -22,8 +22,10 @@ import android.animation.TypeEvaluator; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; +import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; @@ -109,6 +111,35 @@ public class TransitionUtils { } /** + * Get a copy of bitmap of given drawable, return null if intrinsic size is zero + */ + public static Bitmap createDrawableBitmap(Drawable drawable) { + int width = drawable.getIntrinsicWidth(); + int height = drawable.getIntrinsicHeight(); + if (width <= 0 || height <= 0) { + return null; + } + float scale = Math.min(1f, ((float)MAX_IMAGE_SIZE) / (width * height)); + if (drawable instanceof BitmapDrawable && scale == 1f) { + // return same bitmap if scale down not needed + return ((BitmapDrawable) drawable).getBitmap(); + } + int bitmapWidth = (int) (width * scale); + int bitmapHeight = (int) (height * scale); + Bitmap bitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_8888); + Canvas canvas = new Canvas(bitmap); + Rect existingBounds = drawable.getBounds(); + int left = existingBounds.left; + int top = existingBounds.top; + int right = existingBounds.right; + int bottom = existingBounds.bottom; + drawable.setBounds(0, 0, bitmapWidth, bitmapHeight); + drawable.draw(canvas); + drawable.setBounds(left, top, right, bottom); + return bitmap; + } + + /** * Creates a Bitmap of the given view, using the Matrix matrix to transform to the local * coordinates. <code>matrix</code> will be modified during the bitmap creation. * diff --git a/core/java/android/transition/Visibility.java b/core/java/android/transition/Visibility.java index f58291f48949..36bac31901fc 100644 --- a/core/java/android/transition/Visibility.java +++ b/core/java/android/transition/Visibility.java @@ -484,12 +484,19 @@ public abstract class Visibility extends Transition { @Override boolean areValuesChanged(TransitionValues oldValues, TransitionValues newValues) { - VisibilityInfo changeInfo = getVisibilityChangeInfo(oldValues, newValues); if (oldValues == null && newValues == null) { return false; } + if (oldValues != null && newValues != null && + newValues.values.containsKey(PROPNAME_VISIBILITY) != + oldValues.values.containsKey(PROPNAME_VISIBILITY)) { + // The transition wasn't targeted in either the start or end, so it couldn't + // have changed. + return false; + } + VisibilityInfo changeInfo = getVisibilityChangeInfo(oldValues, newValues); return changeInfo.visibilityChange && (changeInfo.startVisibility == View.VISIBLE || - changeInfo.endVisibility == View.VISIBLE); + changeInfo.endVisibility == View.VISIBLE); } /** diff --git a/core/java/android/util/ArraySet.java b/core/java/android/util/ArraySet.java index 423e48b610a7..68f725e688bd 100644 --- a/core/java/android/util/ArraySet.java +++ b/core/java/android/util/ArraySet.java @@ -245,13 +245,20 @@ public final class ArraySet<E> implements Collection<E>, Set<E> { /** * Create a new ArraySet with the mappings from the given ArraySet. */ - public ArraySet(ArraySet set) { + public ArraySet(ArraySet<E> set) { this(); if (set != null) { addAll(set); } } + /** {@hide} */ + public ArraySet(Collection<E> set) { + this(); + if (set != null) { + addAll(set); + } + } /** * Make the array map empty. All storage is released. diff --git a/core/java/android/util/FloatMath.java b/core/java/android/util/FloatMath.java index 0ffd5bd61098..bdcf5ca2bc9e 100644 --- a/core/java/android/util/FloatMath.java +++ b/core/java/android/util/FloatMath.java @@ -21,7 +21,10 @@ package android.util; * versions of Android with a JIT, these are significantly slower than * the equivalent {@code Math} functions, which should be used in preference * to these. + * + * @deprecated Use {@link java.lang.Math} instead. */ +@Deprecated public class FloatMath { /** Prevents instantiation. */ diff --git a/core/java/android/util/IntArray.java b/core/java/android/util/IntArray.java new file mode 100644 index 000000000000..e8d394747b2a --- /dev/null +++ b/core/java/android/util/IntArray.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2014 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.util; + +import com.android.internal.util.ArrayUtils; + +import libcore.util.EmptyArray; + +/** + * Implements a growing array of int primitives. + * + * @hide + */ +public class IntArray implements Cloneable { + private static final int MIN_CAPACITY_INCREMENT = 12; + + private int[] mValues; + private int mSize; + + /** + * Creates an empty IntArray with the default initial capacity. + */ + public IntArray() { + this(10); + } + + /** + * Creates an empty IntArray with the specified initial capacity. + */ + public IntArray(int initialCapacity) { + if (initialCapacity == 0) { + mValues = EmptyArray.INT; + } else { + mValues = ArrayUtils.newUnpaddedIntArray(initialCapacity); + } + mSize = 0; + } + + /** + * Appends the specified value to the end of this array. + */ + public void add(int value) { + add(mSize, value); + } + + /** + * Inserts a value at the specified position in this array. + * + * @throws IndexOutOfBoundsException when index < 0 || index > size() + */ + public void add(int index, int value) { + if (index < 0 || index > mSize) { + throw new IndexOutOfBoundsException(); + } + + ensureCapacity(1); + + if (mSize - index != 0) { + System.arraycopy(mValues, index, mValues, index + 1, mSize - index); + } + + mValues[index] = value; + mSize++; + } + + /** + * Adds the values in the specified array to this array. + */ + public void addAll(IntArray values) { + final int count = values.mSize; + ensureCapacity(count); + + System.arraycopy(values.mValues, 0, mValues, mSize, count); + mSize += count; + } + + /** + * Ensures capacity to append at least <code>count</code> values. + */ + private void ensureCapacity(int count) { + final int currentSize = mSize; + final int minCapacity = currentSize + count; + if (minCapacity >= mValues.length) { + final int targetCap = currentSize + (currentSize < (MIN_CAPACITY_INCREMENT / 2) ? + MIN_CAPACITY_INCREMENT : currentSize >> 1); + final int newCapacity = targetCap > minCapacity ? targetCap : minCapacity; + final int[] newValues = ArrayUtils.newUnpaddedIntArray(newCapacity); + System.arraycopy(mValues, 0, newValues, 0, currentSize); + mValues = newValues; + } + } + + /** + * Removes all values from this array. + */ + public void clear() { + mSize = 0; + } + + @Override + public IntArray clone() throws CloneNotSupportedException { + final IntArray clone = (IntArray) super.clone(); + clone.mValues = mValues.clone(); + return clone; + } + + /** + * Returns the value at the specified position in this array. + */ + public int get(int index) { + if (index >= mSize) { + throw new ArrayIndexOutOfBoundsException(mSize, index); + } + return mValues[index]; + } + + /** + * Returns the index of the first occurrence of the specified value in this + * array, or -1 if this array does not contain the value. + */ + public int indexOf(int value) { + final int n = mSize; + for (int i = 0; i < n; i++) { + if (mValues[i] == value) { + return i; + } + } + return -1; + } + + /** + * Removes the value at the specified index from this array. + */ + public void remove(int index) { + if (index >= mSize) { + throw new ArrayIndexOutOfBoundsException(mSize, index); + } + System.arraycopy(mValues, index + 1, mValues, index, mSize - index - 1); + mSize--; + } + + /** + * Returns the number of values in this array. + */ + public int size() { + return mSize; + } +} diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 3770b8a31922..562d13866984 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -87,6 +87,8 @@ public class Surface implements Parcelable { // non compatibility mode. private Matrix mCompatibleMatrix; + private HwuiContext mHwuiContext; + /** @hide */ @IntDef({ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270}) @Retention(RetentionPolicy.SOURCE) @@ -171,6 +173,10 @@ public class Surface implements Parcelable { nativeRelease(mNativeObject); setNativeObjectLocked(0); } + if (mHwuiContext != null) { + mHwuiContext.destroy(); + mHwuiContext = null; + } } } @@ -264,27 +270,63 @@ public class Surface implements Parcelable { * @param canvas The canvas previously obtained from {@link #lockCanvas}. */ public void unlockCanvasAndPost(Canvas canvas) { + synchronized (mLock) { + checkNotReleasedLocked(); + + if (mHwuiContext != null) { + mHwuiContext.unlockAndPost(canvas); + } else { + unlockSwCanvasAndPost(canvas); + } + } + } + + private void unlockSwCanvasAndPost(Canvas canvas) { if (canvas != mCanvas) { throw new IllegalArgumentException("canvas object must be the same instance that " + "was previously returned by lockCanvas"); } + if (mNativeObject != mLockedObject) { + Log.w(TAG, "WARNING: Surface's mNativeObject (0x" + + Long.toHexString(mNativeObject) + ") != mLockedObject (0x" + + Long.toHexString(mLockedObject) +")"); + } + if (mLockedObject == 0) { + throw new IllegalStateException("Surface was not locked"); + } + try { + nativeUnlockCanvasAndPost(mLockedObject, canvas); + } finally { + nativeRelease(mLockedObject); + mLockedObject = 0; + } + } + /** + * Gets a {@link Canvas} for drawing into this surface. + * + * After drawing into the provided {@link Canvas}, the caller must + * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. + * + * Unlike {@link #lockCanvas(Rect)} this will return a hardware-accelerated + * canvas. See the <a href="{@docRoot}guide/topics/graphics/hardware-accel.html#unsupported"> + * unsupported drawing operations</a> for a list of what is and isn't + * supported in a hardware-accelerated canvas. It is also required to + * fully cover the surface every time {@link #lockHardwareCanvas()} is + * called as the buffer is not preserved between frames. Partial updates + * are not supported. + * + * @return A canvas for drawing into the surface. + * + * @throws IllegalStateException If the canvas cannot be locked. + */ + public Canvas lockHardwareCanvas() { synchronized (mLock) { checkNotReleasedLocked(); - if (mNativeObject != mLockedObject) { - Log.w(TAG, "WARNING: Surface's mNativeObject (0x" + - Long.toHexString(mNativeObject) + ") != mLockedObject (0x" + - Long.toHexString(mLockedObject) +")"); - } - if (mLockedObject == 0) { - throw new IllegalStateException("Surface was not locked"); - } - try { - nativeUnlockCanvasAndPost(mLockedObject, canvas); - } finally { - nativeRelease(mLockedObject); - mLockedObject = 0; + if (mHwuiContext == null) { + mHwuiContext = new HwuiContext(); } + return mHwuiContext.lockCanvas(); } } @@ -415,6 +457,9 @@ public class Surface implements Parcelable { } mNativeObject = ptr; mGenerationId += 1; + if (mHwuiContext != null) { + mHwuiContext.updateSurface(); + } } } @@ -518,4 +563,59 @@ public class Surface implements Parcelable { mOrigMatrix.set(m); } } + + private final class HwuiContext { + private final RenderNode mRenderNode; + private long mHwuiRenderer; + private HardwareCanvas mCanvas; + + HwuiContext() { + mRenderNode = RenderNode.create("HwuiCanvas", null); + mRenderNode.setClipToBounds(false); + mHwuiRenderer = nHwuiCreate(mRenderNode.mNativeRenderNode, mNativeObject); + } + + Canvas lockCanvas() { + if (mCanvas != null) { + throw new IllegalStateException("Surface was already locked!"); + } + mCanvas = mRenderNode.start(0, 0); + return mCanvas; + } + + void unlockAndPost(Canvas canvas) { + if (canvas != mCanvas) { + throw new IllegalArgumentException("canvas object must be the same instance that " + + "was previously returned by lockCanvas"); + } + mRenderNode.end(mCanvas); + mCanvas = null; + nHwuiDraw(mHwuiRenderer); + } + + void updateSurface() { + nHwuiSetSurface(mHwuiRenderer, mNativeObject); + } + + void destroy() { + if (mHwuiRenderer != 0) { + nHwuiDestroy(mHwuiRenderer); + mHwuiRenderer = 0; + } + } + + @Override + protected void finalize() throws Throwable { + try { + destroy(); + } finally { + super.finalize(); + } + } + } + + private static native long nHwuiCreate(long rootNode, long surface); + private static native void nHwuiSetSurface(long renderer, long surface); + private static native void nHwuiDraw(long renderer); + private static native void nHwuiDestroy(long renderer); } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 8e58cd656f0c..e7b98ca4b3fd 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -5877,6 +5877,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return true; } + /** + * Adds the clickable rectangles withing the bounds of this view. They + * may overlap. This method is intended for use only by the accessibility + * layer. + * + * @param outRects List to which to add clickable areas. + */ + void addClickableRectsForAccessibility(List<RectF> outRects) { + if (isClickable() || isLongClickable()) { + RectF bounds = new RectF(); + bounds.set(0, 0, getWidth(), getHeight()); + outRects.add(bounds); + } + } + static void offsetRects(List<RectF> rects, float offsetX, float offsetY) { final int rectCount = rects.size(); for (int i = 0; i < rectCount; i++) { @@ -15676,7 +15691,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, sizeChange(newWidth, newHeight, oldWidth, oldHeight); } - if ((mViewFlags & VISIBILITY_MASK) == VISIBLE) { + if ((mViewFlags & VISIBILITY_MASK) == VISIBLE || mGhostView != null) { // If we are visible, force the DRAWN bit to on so that // this invalidate will go through (at least to our parent). // This is because someone may have invalidated this view @@ -15699,6 +15714,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback, return changed; } + /** + * Same as setFrame, but public and hidden. For use in {@link android.transition.ChangeBounds}. + * @hide + */ + public void setLeftTopRightBottom(int left, int top, int right, int bottom) { + setFrame(left, top, right, bottom); + } + private void sizeChange(int newWidth, int newHeight, int oldWidth, int oldHeight) { onSizeChanged(newWidth, newHeight, oldWidth, oldHeight); if (mOverlay != null) { diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index 134171a350aa..7c7e3e7c9b2a 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -51,8 +51,10 @@ import com.android.internal.util.Predicate; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.NoSuchElementException; import static android.os.Build.VERSION_CODES.JELLY_BEAN_MR1; @@ -468,6 +470,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager @ViewDebug.ExportedProperty(category = "layout") private int mChildCountWithTransientState = 0; + // Iterator over the children in decreasing Z order (top children first). + private OrderedChildIterator mOrderedChildIterator; + /** * Currently registered axes for nested scrolling. Flag set consisting of * {@link #SCROLL_AXIS_HORIZONTAL} {@link #SCROLL_AXIS_VERTICAL} or {@link #SCROLL_AXIS_NONE} @@ -817,19 +822,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return false; } - // Check whether any clickable siblings cover the child - // view and if so keep track of the intersections. Also - // respect Z ordering when iterating over children. - ArrayList<View> orderedList = buildOrderedChildList(); - final boolean useCustomOrder = orderedList == null - && isChildrenDrawingOrderEnabled(); - - final int childCount = mChildrenCount; - for (int i = childCount - 1; i >= 0; i--) { - final int childIndex = useCustomOrder - ? getChildDrawingOrder(childCount, i) : i; - final View sibling = (orderedList == null) - ? mChildren[childIndex] : orderedList.get(childIndex); + Iterator<View> iterator = obtainOrderedChildIterator(); + while (iterator.hasNext()) { + View sibling = iterator.next(); // We care only about siblings over the child. if (sibling == child) { @@ -837,12 +832,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } // Ignore invisible views as they are not interactive. - if (sibling.getVisibility() != View.VISIBLE) { - continue; - } - - // If sibling is not interactive we do not care. - if (!sibling.isClickable() && !sibling.isLongClickable()) { + if (!isVisible(sibling)) { continue; } @@ -850,29 +840,36 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager RectF siblingBounds = mAttachInfo.mTmpTransformRect1; siblingBounds.set(0, 0, sibling.getWidth(), sibling.getHeight()); - // Take into account the sibling transformation matrix. - if (!sibling.hasIdentityMatrix()) { - sibling.getMatrix().mapRect(siblingBounds); - } - - // Offset the sibling to our coordinates. - final int siblingDx = sibling.mLeft - mScrollX; - final int siblingDy = sibling.mTop - mScrollY; - siblingBounds.offset(siblingDx, siblingDy); + // Translate the sibling bounds to our coordinates. + offsetChildRectToMyCoords(siblingBounds, sibling); // Compute the intersection between the child and the sibling. if (siblingBounds.intersect(bounds)) { - // If an interactive sibling completely covers the child, done. - if (siblingBounds.equals(bounds)) { - if (orderedList != null) orderedList.clear(); - return false; + List<RectF> clickableRects = new ArrayList<>(); + sibling.addClickableRectsForAccessibility(clickableRects); + + final int clickableRectCount = clickableRects.size(); + for (int j = 0; j < clickableRectCount; j++) { + RectF clickableRect = clickableRects.get(j); + + // Translate the clickable rect to our coordinates. + offsetChildRectToMyCoords(clickableRect, sibling); + + // Compute the intersection between the child and the clickable rects. + if (clickableRect.intersect(bounds)) { + // If a clickable rect completely covers the child, done. + if (clickableRect.equals(bounds)) { + releaseOrderedChildIterator(); + return false; + } + // Keep track of the intersection rectangle. + intersections.add(clickableRect); + } } - // Keep track of the intersection rectangle. - RectF intersection = new RectF(siblingBounds); - intersections.add(intersection); } } - if (orderedList != null) orderedList.clear(); + + releaseOrderedChildIterator(); if (mParent instanceof ViewGroup) { ViewGroup parentGroup = (ViewGroup) mParent; @@ -883,6 +880,94 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return true; } + @Override + void addClickableRectsForAccessibility(List<RectF> outRects) { + int sizeBefore = outRects.size(); + + super.addClickableRectsForAccessibility(outRects); + + // If we added ourselves, then no need to visit children. + if (outRects.size() > sizeBefore) { + return; + } + + Iterator<View> iterator = obtainOrderedChildIterator(); + while (iterator.hasNext()) { + View child = iterator.next(); + + // Cannot click on an invisible view. + if (!isVisible(child)) { + continue; + } + + sizeBefore = outRects.size(); + + // Add clickable rects in the child bounds. + child.addClickableRectsForAccessibility(outRects); + + // Offset the clickable rects for out children to our coordinates. + final int sizeAfter = outRects.size(); + for (int j = sizeBefore; j < sizeAfter; j++) { + RectF rect = outRects.get(j); + + // Translate the clickable rect to our coordinates. + offsetChildRectToMyCoords(rect, child); + + // If a clickable rect fills the parent, done. + if ((int) rect.left == 0 && (int) rect.top == 0 + && (int) rect.right == mRight && (int) rect.bottom == mBottom) { + releaseOrderedChildIterator(); + return; + } + } + } + + releaseOrderedChildIterator(); + } + + private void offsetChildRectToMyCoords(RectF rect, View child) { + if (!child.hasIdentityMatrix()) { + child.getMatrix().mapRect(rect); + } + final int childDx = child.mLeft - mScrollX; + final int childDy = child.mTop - mScrollY; + rect.offset(childDx, childDy); + } + + private static boolean isVisible(View view) { + return (view.getAlpha() > 0 && view.getTransitionAlpha() > 0 && + view.getVisibility() == VISIBLE); + } + + /** + * Obtains the iterator to traverse the children in a descending Z order. + * Only one party can use the iterator at any given time and you cannot + * modify the children while using this iterator. Acquisition if already + * obtained is an error. + * + * @return The child iterator. + */ + OrderedChildIterator obtainOrderedChildIterator() { + if (mOrderedChildIterator == null) { + mOrderedChildIterator = new OrderedChildIterator(); + } else if (mOrderedChildIterator.isInitialized()) { + throw new IllegalStateException("Already obtained"); + } + mOrderedChildIterator.initialize(); + return mOrderedChildIterator; + } + + /** + * Releases the iterator to traverse the children in a descending Z order. + * Release if not obtained is an error. + */ + void releaseOrderedChildIterator() { + if (mOrderedChildIterator == null || !mOrderedChildIterator.isInitialized()) { + throw new IllegalStateException("Not obtained"); + } + mOrderedChildIterator.release(); + } + /** * Called when a child view has changed whether or not it is tracking transient state. */ @@ -7298,4 +7383,57 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager canvas.drawLines(sDebugLines, paint); } + + private final class OrderedChildIterator implements Iterator<View> { + private List<View> mOrderedChildList; + private boolean mUseCustomOrder; + private int mCurrentIndex; + private boolean mInitialized; + + public void initialize() { + mOrderedChildList = buildOrderedChildList(); + mUseCustomOrder = (mOrderedChildList == null) + && isChildrenDrawingOrderEnabled(); + mCurrentIndex = mChildrenCount - 1; + mInitialized = true; + } + + public void release() { + if (mOrderedChildList != null) { + mOrderedChildList.clear(); + } + mUseCustomOrder = false; + mCurrentIndex = 0; + mInitialized = false; + } + + public boolean isInitialized() { + return mInitialized; + } + + @Override + public boolean hasNext() { + return (mCurrentIndex >= 0); + } + + @Override + public View next() { + if (!hasNext()) { + throw new NoSuchElementException("No such element"); + } + return getChild(mCurrentIndex--); + } + + private View getChild(int index) { + final int childIndex = mUseCustomOrder + ? getChildDrawingOrder(mChildrenCount, index) : index; + return (mOrderedChildList == null) + ? mChildren[childIndex] : mOrderedChildList.get(childIndex); + } + + @Override + public void remove() { + throw new UnsupportedOperationException(); + } + } } diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java index 63ab7d252237..20edeb8da627 100644 --- a/core/java/android/view/Window.java +++ b/core/java/android/view/Window.java @@ -24,7 +24,6 @@ import android.content.res.TypedArray; import android.graphics.PixelFormat; import android.graphics.drawable.Drawable; import android.media.session.MediaController; -import android.media.session.MediaSession; import android.net.Uri; import android.os.Bundle; import android.os.IBinder; @@ -801,9 +800,6 @@ public abstract class Window { public void setFlags(int flags, int mask) { final WindowManager.LayoutParams attrs = getAttributes(); attrs.flags = (attrs.flags&~mask) | (flags&mask); - if ((mask&WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0) { - attrs.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY; - } mForcedWindowFlags |= mask; dispatchWindowAttributesChanged(attrs); } @@ -817,6 +813,15 @@ public abstract class Window { /** * {@hide} */ + protected void setNeedsMenuKey(int value) { + final WindowManager.LayoutParams attrs = getAttributes(); + attrs.needsMenuKey = value; + dispatchWindowAttributesChanged(attrs); + } + + /** + * {@hide} + */ protected void dispatchWindowAttributesChanged(WindowManager.LayoutParams attrs) { if (mCallback != null) { mCallback.onWindowAttributesChanged(attrs); @@ -1125,31 +1130,31 @@ public abstract class Window { * Set an explicit Drawable value for feature of this window. You must * have called requestFeature(featureId) before calling this function. * - * @param featureId The desired drawable feature to change. - * Features are constants defined by Window. + * @param featureId The desired drawable feature to change. Features are + * constants defined by Window. * @param drawable A Drawable object to display. */ public abstract void setFeatureDrawable(int featureId, Drawable drawable); /** - * Set a custom alpha value for the given drawale feature, controlling how + * Set a custom alpha value for the given drawable feature, controlling how * much the background is visible through it. * - * @param featureId The desired drawable feature to change. - * Features are constants defined by Window. + * @param featureId The desired drawable feature to change. Features are + * constants defined by Window. * @param alpha The alpha amount, 0 is completely transparent and 255 is * completely opaque. */ public abstract void setFeatureDrawableAlpha(int featureId, int alpha); /** - * Set the integer value for a feature. The range of the value depends on - * the feature being set. For FEATURE_PROGRESSS, it should go from 0 to - * 10000. At 10000 the progress is complete and the indicator hidden. + * Set the integer value for a feature. The range of the value depends on + * the feature being set. For {@link #FEATURE_PROGRESS}, it should go from + * 0 to 10000. At 10000 the progress is complete and the indicator hidden. * - * @param featureId The desired feature to change. - * Features are constants defined by Window. - * @param value The value for the feature. The interpretation of this + * @param featureId The desired feature to change. Features are constants + * defined by Window. + * @param value The value for the feature. The interpretation of this * value is feature-specific. */ public abstract void setFeatureInt(int featureId, int value); diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index 75c9ebd7940b..5b48c0d2d433 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -542,6 +542,19 @@ public interface WindowManager extends ViewManager { public static final int TYPE_VOICE_INTERACTION = FIRST_SYSTEM_WINDOW+31; /** + * Window type: Windows that are overlaid <em>only</em> by an {@link + * android.accessibilityservice.AccessibilityService} for interception of + * user interactions without changing the windows an accessibility service + * can introspect. In particular, an accessibility service can introspect + * only windows that a sighted user can interact with which is they can touch + * these windows or can type into these windows. For example, if there + * is a full screen accessibility overlay that is touchable, the windows + * below it will be introspectable by an accessibility service regardless + * they are covered by a touchable window. + */ + public static final int TYPE_ACCESSIBILITY_OVERLAY = FIRST_SYSTEM_WINDOW+32; + + /** * End of types of system windows. */ public static final int LAST_SYSTEM_WINDOW = 2999; @@ -878,9 +891,6 @@ public interface WindowManager extends ViewManager { */ public static final int FLAG_TRANSLUCENT_NAVIGATION = 0x08000000; - // ----- HIDDEN FLAGS. - // These start at the high bit and go down. - /** * Flag for a window in local focus mode. * Window in local focus mode can control focus independent of window manager using @@ -903,17 +913,12 @@ public interface WindowManager extends ViewManager { public static final int FLAG_SLIPPERY = 0x20000000; /** - * Flag for a window belonging to an activity that responds to {@link KeyEvent#KEYCODE_MENU} - * and therefore needs a Menu key. For devices where Menu is a physical button this flag is - * ignored, but on devices where the Menu key is drawn in software it may be hidden unless - * this flag is set. - * - * (Note that Action Bars, when available, are the preferred way to offer additional - * functions otherwise accessed via an options menu.) - * - * {@hide} + * Window flag: When requesting layout with an attached window, the attached window may + * overlap with the screen decorations of the parent window such as the navigation bar. By + * including this flag, the window manager will layout the attached window within the decor + * frame of the parent window such that it doesn't overlap with screen decorations. */ - public static final int FLAG_NEEDS_MENU_KEY = 0x40000000; + public static final int FLAG_LAYOUT_ATTACHED_IN_DECOR = 0x40000000; /** * Flag indicating that this Window is responsible for drawing the background for the @@ -1056,16 +1061,6 @@ public interface WindowManager extends ViewManager { */ public static final int PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS = 0x00000004; - /** - * This is set for a window that has explicitly specified its - * FLAG_NEEDS_MENU_KEY, so we know the value on this window is the - * appropriate one to use. If this is not set, we should look at - * windows behind it to determine the appropriate value. - * - * @hide - */ - public static final int PRIVATE_FLAG_SET_NEEDS_MENU_KEY = 0x00000008; - /** In a multiuser system if this flag is set and the owner is a system process then this * window will appear on all user screens. This overrides the default behavior of window * types that normally only appear on the owning user's screen. Refer to each window type @@ -1113,6 +1108,45 @@ public interface WindowManager extends ViewManager { public int privateFlags; /** + * Value for {@link #needsMenuKey} for a window that has not explicitly specified if it + * needs {@link #NEEDS_MENU_SET_TRUE} or doesn't need {@link #NEEDS_MENU_SET_FALSE} a menu + * key. For this case, we should look at windows behind it to determine the appropriate + * value. + * + * @hide + */ + public static final int NEEDS_MENU_UNSET = 0; + + /** + * Value for {@link #needsMenuKey} for a window that has explicitly specified it needs a + * menu key. + * + * @hide + */ + public static final int NEEDS_MENU_SET_TRUE = 1; + + /** + * Value for {@link #needsMenuKey} for a window that has explicitly specified it doesn't + * needs a menu key. + * + * @hide + */ + public static final int NEEDS_MENU_SET_FALSE = 2; + + /** + * State variable for a window belonging to an activity that responds to + * {@link KeyEvent#KEYCODE_MENU} and therefore needs a Menu key. For devices where Menu is a + * physical button this variable is ignored, but on devices where the Menu key is drawn in + * software it may be hidden unless this variable is set to {@link #NEEDS_MENU_SET_TRUE}. + * + * (Note that Action Bars, when available, are the preferred way to offer additional + * functions otherwise accessed via an options menu.) + * + * {@hide} + */ + public int needsMenuKey = NEEDS_MENU_UNSET; + + /** * Given a particular set of window manager flags, determine whether * such a window may be a target for an input method when it has * focus. In particular, this checks the @@ -1120,9 +1154,9 @@ public interface WindowManager extends ViewManager { * flags and returns true if the combination of the two corresponds * to a window that needs to be behind the input method so that the * user can type into it. - * + * * @param flags The current window manager flags. - * + * * @return Returns true if such a window should be behind/interact * with an input method, false if not. */ @@ -1587,14 +1621,15 @@ public interface WindowManager extends ViewManager { out.writeInt(surfaceInsets.top); out.writeInt(surfaceInsets.right); out.writeInt(surfaceInsets.bottom); + out.writeInt(needsMenuKey); } - + public static final Parcelable.Creator<LayoutParams> CREATOR = new Parcelable.Creator<LayoutParams>() { public LayoutParams createFromParcel(Parcel in) { return new LayoutParams(in); } - + public LayoutParams[] newArray(int size) { return new LayoutParams[size]; } @@ -1634,8 +1669,9 @@ public interface WindowManager extends ViewManager { surfaceInsets.top = in.readInt(); surfaceInsets.right = in.readInt(); surfaceInsets.bottom = in.readInt(); + needsMenuKey = in.readInt(); } - + @SuppressWarnings({"PointlessBitwiseExpression"}) public static final int LAYOUT_CHANGED = 1<<0; public static final int TYPE_CHANGED = 1<<1; @@ -1669,14 +1705,16 @@ public interface WindowManager extends ViewManager { /** {@hide} */ public static final int PREFERRED_REFRESH_RATE_CHANGED = 1 << 21; /** {@hide} */ + public static final int NEEDS_MENU_KEY_CHANGED = 1 << 22; + /** {@hide} */ public static final int EVERYTHING_CHANGED = 0xffffffff; // internal buffer to backup/restore parameters under compatibility mode. private int[] mCompatibilityParamsBackup = null; - + public final int copyFrom(LayoutParams o) { int changes = 0; - + if (width != o.width) { width = o.width; changes |= LAYOUT_CHANGED; @@ -1813,9 +1851,14 @@ public interface WindowManager extends ViewManager { changes |= SURFACE_INSETS_CHANGED; } + if (needsMenuKey != o.needsMenuKey) { + needsMenuKey = o.needsMenuKey; + changes |= NEEDS_MENU_KEY_CHANGED; + } + return changes; } - + @Override public String debug(String output) { output += "Contents of " + this + ":"; @@ -1919,6 +1962,10 @@ public interface WindowManager extends ViewManager { if (!surfaceInsets.equals(Insets.NONE)) { sb.append(" surfaceInsets=").append(surfaceInsets); } + if (needsMenuKey != NEEDS_MENU_UNSET) { + sb.append(" needsMenuKey="); + sb.append(needsMenuKey); + } sb.append('}'); return sb.toString(); } diff --git a/core/java/android/view/WindowManagerInternal.java b/core/java/android/view/WindowManagerInternal.java index 38e372367ac5..f557b976d535 100644 --- a/core/java/android/view/WindowManagerInternal.java +++ b/core/java/android/view/WindowManagerInternal.java @@ -173,4 +173,20 @@ public abstract class WindowManagerInternal { * redrawn. */ public abstract void waitForAllWindowsDrawn(Runnable callback, long timeout); + + /** + * Adds a window token for a given window type. + * + * @param token The token to add. + * @param type The window type. + */ + public abstract void addWindowToken(android.os.IBinder token, int type); + + /** + * Removes a window token. + * + * @param token The toke to remove. + * @param removeWindows Whether to also remove the windows associated with the token. + */ + public abstract void removeWindowToken(android.os.IBinder token, boolean removeWindows); } diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java index ad55f5f2a097..e1942beaaa0f 100644 --- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java +++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java @@ -51,11 +51,24 @@ public final class AccessibilityWindowInfo implements Parcelable { */ public static final int TYPE_SYSTEM = 3; + /** + * Window type: Windows that are overlaid <em>only</em> by an {@link + * android.accessibilityservice.AccessibilityService} for interception of + * user interactions without changing the windows an accessibility service + * can introspect. In particular, an accessibility service can introspect + * only windows that a sighted user can interact with which they can touch + * these windows or can type into these windows. For example, if there + * is a full screen accessibility overlay that is touchable, the windows + * below it will be introspectable by an accessibility service regardless + * they are covered by a touchable window. + */ + public static final int TYPE_ACCESSIBILITY_OVERLAY = 4; + private static final int UNDEFINED = -1; private static final int BOOLEAN_PROPERTY_ACTIVE = 1 << 0; private static final int BOOLEAN_PROPERTY_FOCUSED = 1 << 1; - private static final int BOOLEAN_PROPERTY_ACCESSIBLITY_FOCUSED = 1 << 2; + private static final int BOOLEAN_PROPERTY_ACCESSIBILITY_FOCUSED = 1 << 2; // Housekeeping. private static final int MAX_POOL_SIZE = 10; @@ -85,6 +98,7 @@ public final class AccessibilityWindowInfo implements Parcelable { * @see #TYPE_APPLICATION * @see #TYPE_INPUT_METHOD * @see #TYPE_SYSTEM + * @see #TYPE_ACCESSIBILITY_OVERLAY */ public int getType() { return mType; @@ -93,7 +107,7 @@ public final class AccessibilityWindowInfo implements Parcelable { /** * Sets the type of the window. * - * @param The type + * @param type The type * * @hide */ @@ -115,7 +129,7 @@ public final class AccessibilityWindowInfo implements Parcelable { * Sets the layer which determines the Z-order of the window. Windows * with greater layer appear on top of windows with lesser layer. * - * @param The window layer. + * @param layer The window layer. * * @hide */ @@ -174,7 +188,7 @@ public final class AccessibilityWindowInfo implements Parcelable { /** * Sets the unique window id. * - * @param windowId The window id. + * @param id The window id. * * @hide */ @@ -230,7 +244,7 @@ public final class AccessibilityWindowInfo implements Parcelable { * the user is currently touching or the window has input focus * and the user is not touching any window. * - * @param Whether this is the active window. + * @param active Whether this is the active window. * * @hide */ @@ -250,7 +264,7 @@ public final class AccessibilityWindowInfo implements Parcelable { /** * Sets if this window has input focus. * - * @param Whether has input focus. + * @param focused Whether has input focus. * * @hide */ @@ -264,18 +278,18 @@ public final class AccessibilityWindowInfo implements Parcelable { * @return Whether has accessibility focus. */ public boolean isAccessibilityFocused() { - return getBooleanProperty(BOOLEAN_PROPERTY_ACCESSIBLITY_FOCUSED); + return getBooleanProperty(BOOLEAN_PROPERTY_ACCESSIBILITY_FOCUSED); } /** * Sets if this window has accessibility focus. * - * @param Whether has accessibility focus. + * @param focused Whether has accessibility focus. * * @hide */ public void setAccessibilityFocused(boolean focused) { - setBooleanProperty(BOOLEAN_PROPERTY_ACCESSIBLITY_FOCUSED, focused); + setBooleanProperty(BOOLEAN_PROPERTY_ACCESSIBILITY_FOCUSED, focused); } /** @@ -534,6 +548,9 @@ public final class AccessibilityWindowInfo implements Parcelable { case TYPE_SYSTEM: { return "TYPE_SYSTEM"; } + case TYPE_ACCESSIBILITY_OVERLAY: { + return "TYPE_ACCESSIBILITY_OVERLAY"; + } default: return "<UNKNOWN>"; } diff --git a/core/java/android/view/animation/AccelerateDecelerateInterpolator.java b/core/java/android/view/animation/AccelerateDecelerateInterpolator.java index ed6949a0f3b6..21d5a5b86bf2 100644 --- a/core/java/android/view/animation/AccelerateDecelerateInterpolator.java +++ b/core/java/android/view/animation/AccelerateDecelerateInterpolator.java @@ -26,17 +26,17 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; /** * An interpolator where the rate of change starts and ends slowly but * accelerates through the middle. - * */ @HasNativeInterpolator -public class AccelerateDecelerateInterpolator implements Interpolator, NativeInterpolatorFactory { +public class AccelerateDecelerateInterpolator extends BaseInterpolator + implements NativeInterpolatorFactory { public AccelerateDecelerateInterpolator() { } - + @SuppressWarnings({"UnusedDeclaration"}) public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) { } - + public float getInterpolation(float input) { return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f; } diff --git a/core/java/android/view/animation/AccelerateInterpolator.java b/core/java/android/view/animation/AccelerateInterpolator.java index 1c75f166bf17..6c8d7b19fb15 100644 --- a/core/java/android/view/animation/AccelerateInterpolator.java +++ b/core/java/android/view/animation/AccelerateInterpolator.java @@ -33,7 +33,7 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; * */ @HasNativeInterpolator -public class AccelerateInterpolator implements Interpolator, NativeInterpolatorFactory { +public class AccelerateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { private final float mFactor; private final double mDoubleFactor; @@ -70,7 +70,7 @@ public class AccelerateInterpolator implements Interpolator, NativeInterpolatorF mFactor = a.getFloat(R.styleable.AccelerateInterpolator_factor, 1.0f); mDoubleFactor = 2 * mFactor; - + setChangingConfiguration(a.getChangingConfigurations()); a.recycle(); } diff --git a/core/java/android/view/animation/AnimationUtils.java b/core/java/android/view/animation/AnimationUtils.java index af4e04ffe3a8..606c83e39c05 100644 --- a/core/java/android/view/animation/AnimationUtils.java +++ b/core/java/android/view/animation/AnimationUtils.java @@ -321,7 +321,7 @@ public class AnimationUtils { private static Interpolator createInterpolatorFromXml(Resources res, Theme theme, XmlPullParser parser) throws XmlPullParserException, IOException { - Interpolator interpolator = null; + BaseInterpolator interpolator = null; // Make sure we are on a start tag. int type; @@ -361,10 +361,7 @@ public class AnimationUtils { } else { throw new RuntimeException("Unknown interpolator name: " + parser.getName()); } - } - return interpolator; - } } diff --git a/core/java/android/view/animation/AnticipateInterpolator.java b/core/java/android/view/animation/AnticipateInterpolator.java index fe756bd473e1..fb66c312181c 100644 --- a/core/java/android/view/animation/AnticipateInterpolator.java +++ b/core/java/android/view/animation/AnticipateInterpolator.java @@ -31,7 +31,7 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; * An interpolator where the change starts backward then flings forward. */ @HasNativeInterpolator -public class AnticipateInterpolator implements Interpolator, NativeInterpolatorFactory { +public class AnticipateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { private final float mTension; public AnticipateInterpolator() { @@ -60,9 +60,8 @@ public class AnticipateInterpolator implements Interpolator, NativeInterpolatorF a = res.obtainAttributes(attrs, R.styleable.AnticipateInterpolator); } - mTension = - a.getFloat(R.styleable.AnticipateInterpolator_tension, 2.0f); - + mTension = a.getFloat(R.styleable.AnticipateInterpolator_tension, 2.0f); + setChangingConfiguration(a.getChangingConfigurations()); a.recycle(); } diff --git a/core/java/android/view/animation/AnticipateOvershootInterpolator.java b/core/java/android/view/animation/AnticipateOvershootInterpolator.java index 78e5acf247a0..1af72da7a3a4 100644 --- a/core/java/android/view/animation/AnticipateOvershootInterpolator.java +++ b/core/java/android/view/animation/AnticipateOvershootInterpolator.java @@ -35,7 +35,8 @@ import static com.android.internal.R.styleable.AnticipateOvershootInterpolator; * the target value and finally goes back to the final value. */ @HasNativeInterpolator -public class AnticipateOvershootInterpolator implements Interpolator, NativeInterpolatorFactory { +public class AnticipateOvershootInterpolator extends BaseInterpolator + implements NativeInterpolatorFactory { private final float mTension; public AnticipateOvershootInterpolator() { @@ -78,7 +79,7 @@ public class AnticipateOvershootInterpolator implements Interpolator, NativeInte mTension = a.getFloat(AnticipateOvershootInterpolator_tension, 2.0f) * a.getFloat(AnticipateOvershootInterpolator_extraTension, 1.5f); - + setChangingConfiguration(a.getChangingConfigurations()); a.recycle(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Prefs.java b/core/java/android/view/animation/BaseInterpolator.java index f339401dce18..9c0014c951c3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/Prefs.java +++ b/core/java/android/view/animation/BaseInterpolator.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 The Android Open Source Project + * Copyright (C) 2014 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,19 +14,24 @@ * limitations under the License. */ -package com.android.systemui.statusbar.policy; +package android.view.animation; -import android.content.Context; -import android.content.SharedPreferences; - -public class Prefs { - private static final String SHARED_PREFS_NAME = "status_bar"; - - public static SharedPreferences read(Context context) { - return context.getSharedPreferences(Prefs.SHARED_PREFS_NAME, Context.MODE_PRIVATE); +/** + * An abstract class which is extended by default interpolators. + */ +abstract public class BaseInterpolator implements Interpolator { + private int mChangingConfiguration; + /** + * @hide + */ + public int getChangingConfiguration() { + return mChangingConfiguration; } - public static SharedPreferences.Editor edit(Context context) { - return context.getSharedPreferences(Prefs.SHARED_PREFS_NAME, Context.MODE_PRIVATE).edit(); + /** + * @hide + */ + void setChangingConfiguration(int changingConfiguration) { + mChangingConfiguration = changingConfiguration; } } diff --git a/core/java/android/view/animation/BounceInterpolator.java b/core/java/android/view/animation/BounceInterpolator.java index 9d8ca901f0ad..909eaa4c7c26 100644 --- a/core/java/android/view/animation/BounceInterpolator.java +++ b/core/java/android/view/animation/BounceInterpolator.java @@ -27,7 +27,7 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; * An interpolator where the change bounces at the end. */ @HasNativeInterpolator -public class BounceInterpolator implements Interpolator, NativeInterpolatorFactory { +public class BounceInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { public BounceInterpolator() { } diff --git a/core/java/android/view/animation/CycleInterpolator.java b/core/java/android/view/animation/CycleInterpolator.java index 3114aa3ca1d6..663c1091ca29 100644 --- a/core/java/android/view/animation/CycleInterpolator.java +++ b/core/java/android/view/animation/CycleInterpolator.java @@ -33,7 +33,7 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; * */ @HasNativeInterpolator -public class CycleInterpolator implements Interpolator, NativeInterpolatorFactory { +public class CycleInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { public CycleInterpolator(float cycles) { mCycles = cycles; } @@ -52,7 +52,7 @@ public class CycleInterpolator implements Interpolator, NativeInterpolatorFactor } mCycles = a.getFloat(R.styleable.CycleInterpolator_cycles, 1.0f); - + setChangingConfiguration(a.getChangingConfigurations()); a.recycle(); } diff --git a/core/java/android/view/animation/DecelerateInterpolator.java b/core/java/android/view/animation/DecelerateInterpolator.java index 674207ca7e00..f426f60dc581 100644 --- a/core/java/android/view/animation/DecelerateInterpolator.java +++ b/core/java/android/view/animation/DecelerateInterpolator.java @@ -33,7 +33,7 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; * */ @HasNativeInterpolator -public class DecelerateInterpolator implements Interpolator, NativeInterpolatorFactory { +public class DecelerateInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { public DecelerateInterpolator() { } @@ -62,7 +62,7 @@ public class DecelerateInterpolator implements Interpolator, NativeInterpolatorF } mFactor = a.getFloat(R.styleable.DecelerateInterpolator_factor, 1.0f); - + setChangingConfiguration(a.getChangingConfigurations()); a.recycle(); } diff --git a/core/java/android/view/animation/LinearInterpolator.java b/core/java/android/view/animation/LinearInterpolator.java index 552c6119513d..2a047b48cfb0 100644 --- a/core/java/android/view/animation/LinearInterpolator.java +++ b/core/java/android/view/animation/LinearInterpolator.java @@ -25,17 +25,16 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; /** * An interpolator where the rate of change is constant - * */ @HasNativeInterpolator -public class LinearInterpolator implements Interpolator, NativeInterpolatorFactory { +public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { public LinearInterpolator() { } - + public LinearInterpolator(Context context, AttributeSet attrs) { } - + public float getInterpolation(float input) { return input; } diff --git a/core/java/android/view/animation/OvershootInterpolator.java b/core/java/android/view/animation/OvershootInterpolator.java index d6c280871a99..306688a1b10b 100644 --- a/core/java/android/view/animation/OvershootInterpolator.java +++ b/core/java/android/view/animation/OvershootInterpolator.java @@ -32,7 +32,7 @@ import com.android.internal.view.animation.NativeInterpolatorFactoryHelper; * then comes back. */ @HasNativeInterpolator -public class OvershootInterpolator implements Interpolator, NativeInterpolatorFactory { +public class OvershootInterpolator extends BaseInterpolator implements NativeInterpolatorFactory { private final float mTension; public OvershootInterpolator() { @@ -61,9 +61,8 @@ public class OvershootInterpolator implements Interpolator, NativeInterpolatorFa a = res.obtainAttributes(attrs, R.styleable.OvershootInterpolator); } - mTension = - a.getFloat(R.styleable.OvershootInterpolator_tension, 2.0f); - + mTension = a.getFloat(R.styleable.OvershootInterpolator_tension, 2.0f); + setChangingConfiguration(a.getChangingConfigurations()); a.recycle(); } diff --git a/core/java/android/view/animation/PathInterpolator.java b/core/java/android/view/animation/PathInterpolator.java index 945ecf00656a..eec5555e6d79 100644 --- a/core/java/android/view/animation/PathInterpolator.java +++ b/core/java/android/view/animation/PathInterpolator.java @@ -42,7 +42,7 @@ import com.android.internal.R; * path.lineTo(1f, 1f); * </pre></blockquote></p> */ -public class PathInterpolator implements Interpolator { +public class PathInterpolator extends BaseInterpolator { // This governs how accurate the approximation of the Path is. private static final float PRECISION = 0.002f; @@ -98,7 +98,7 @@ public class PathInterpolator implements Interpolator { a = res.obtainAttributes(attrs, R.styleable.PathInterpolator); } parseInterpolatorFromTypeArray(a); - + setChangingConfiguration(a.getChangingConfigurations()); a.recycle(); } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index 043916840fad..4aebaae90b03 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -4653,7 +4653,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te if (mPositionScroller == null) { mPositionScroller = createPositionScroller(); } - mPositionScroller.startWithOffset(position, offset, offset); + mPositionScroller.startWithOffset(position, offset); } /** diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java index b9f891ce71c9..5e2394ca834e 100644 --- a/core/java/android/widget/AdapterView.java +++ b/core/java/android/widget/AdapterView.java @@ -215,7 +215,12 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup { private boolean mDesiredFocusableState; private boolean mDesiredFocusableInTouchModeState; + /** Lazily-constructed runnable for dispatching selection events. */ private SelectionNotifier mSelectionNotifier; + + /** Selection notifier that's waiting for the next layout pass. */ + private SelectionNotifier mPendingSelectionNotifier; + /** * When set to true, calls to requestLayout() will not propagate up the parent hierarchy. * This is used to layout the children during a layout pass. @@ -854,39 +859,51 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup { private class SelectionNotifier implements Runnable { public void run() { - if (mDataChanged) { - // Data has changed between when this SelectionNotifier - // was posted and now. We need to wait until the AdapterView - // has been synched to the new data. + mPendingSelectionNotifier = null; + + if (mDataChanged && getViewRootImpl() != null + && getViewRootImpl().isLayoutRequested()) { + // Data has changed between when this SelectionNotifier was + // posted and now. Postpone the notification until the next + // layout is complete and we run checkSelectionChanged(). if (getAdapter() != null) { - post(this); + mPendingSelectionNotifier = this; } } else { - fireOnSelected(); - performAccessibilityActionsOnSelected(); + dispatchOnItemSelected(); } } } void selectionChanged() { + // We're about to post or run the selection notifier, so we don't need + // a pending notifier. + mPendingSelectionNotifier = null; + if (mOnItemSelectedListener != null || AccessibilityManager.getInstance(mContext).isEnabled()) { if (mInLayout || mBlockLayoutRequests) { // If we are in a layout traversal, defer notification // by posting. This ensures that the view tree is - // in a consistent state and is able to accomodate + // in a consistent state and is able to accommodate // new layout or invalidate requests. if (mSelectionNotifier == null) { mSelectionNotifier = new SelectionNotifier(); + } else { + removeCallbacks(mSelectionNotifier); } post(mSelectionNotifier); } else { - fireOnSelected(); - performAccessibilityActionsOnSelected(); + dispatchOnItemSelected(); } } } + private void dispatchOnItemSelected() { + fireOnSelected(); + performAccessibilityActionsOnSelected(); + } + private void fireOnSelected() { if (mOnItemSelectedListener == null) { return; @@ -1042,12 +1059,22 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup { notifySubtreeAccessibilityStateChangedIfNeeded(); } + /** + * Called after layout to determine whether the selection position needs to + * be updated. Also used to fire any pending selection events. + */ void checkSelectionChanged() { if ((mSelectedPosition != mOldSelectedPosition) || (mSelectedRowId != mOldSelectedRowId)) { selectionChanged(); mOldSelectedPosition = mSelectedPosition; mOldSelectedRowId = mSelectedRowId; } + + // If we have a pending selection notification -- and we won't if we + // just fired one in selectionChanged() -- run it now. + if (mPendingSelectionNotifier != null) { + mPendingSelectionNotifier.run(); + } } /** diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index f90a9fe24e92..75dfccad3728 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -1120,6 +1120,9 @@ public class ImageView extends View { /** @hide */ public void animateTransform(Matrix matrix) { + if (mDrawable == null) { + return; + } if (matrix == null) { mDrawable.setBounds(0, 0, getWidth(), getHeight()); } else { diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index 41d3e3208ee2..54a7940a0499 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -97,9 +97,11 @@ public class PopupWindow { private boolean mAllowScrollingAnchorParent = true; private boolean mLayoutInsetDecor = false; private boolean mNotTouchModal; + private boolean mAttachedInDecor = true; + private boolean mAttachedInDecorSet = false; private OnTouchListener mTouchInterceptor; - + private int mWidthMode; private int mWidth; private int mLastWidth; @@ -316,6 +318,7 @@ public class PopupWindow { mContext = contentView.getContext(); mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); } + setContentView(contentView); setWidth(width); setHeight(height); @@ -373,16 +376,16 @@ public class PopupWindow { public int getAnimationStyle() { return mAnimationStyle; } - + /** - * Set the flag on popup to ignore cheek press eventt; by default this flag + * Set the flag on popup to ignore cheek press event; by default this flag * is set to false * which means the pop wont ignore cheek press dispatch events. - * + * * <p>If the popup is showing, calling this method will take effect only * the next time the popup is shown or through a manual call to one of * the {@link #update()} methods.</p> - * + * * @see #update() */ public void setIgnoreCheekPress() { @@ -443,6 +446,19 @@ public class PopupWindow { if (mWindowManager == null && mContentView != null) { mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); } + + // Setting the default for attachedInDecor based on SDK version here + // instead of in the constructor since we might not have the context + // object in the constructor. We only want to set default here if the + // app hasn't already set the attachedInDecor. + if (mContext != null && !mAttachedInDecorSet) { + // Attach popup window in decor frame of parent window by default for + // {@link Build.VERSION_CODES.LOLLIPOP_MR1} or greater. Keep current + // behavior of not attaching to decor frame for older SDKs. + setAttachedInDecor(mContext.getApplicationInfo().targetSdkVersion + >= Build.VERSION_CODES.LOLLIPOP_MR1); + } + } /** @@ -452,7 +468,7 @@ public class PopupWindow { public void setTouchInterceptor(OnTouchListener l) { mTouchInterceptor = l; } - + /** * <p>Indicate whether the popup window can grab the focus.</p> * @@ -702,6 +718,36 @@ public class PopupWindow { } /** + * <p>Indicates whether the popup window will be attached in the decor frame of its parent + * window. + * + * @return true if the window will be attached to the decor frame of its parent window. + * + * @see #setAttachedInDecor(boolean) + * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR + */ + public boolean isAttachedInDecor() { + return mAttachedInDecor; + } + + /** + * <p>This will attach the popup window to the decor frame of the parent window to avoid + * overlaping with screen decorations like the navigation bar. Overrides the default behavior of + * the flag {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR}. + * + * <p>By default the flag is set on SDK version {@link Build.VERSION_CODES#LOLLIPOP_MR1} or + * greater and cleared on lesser SDK versions. + * + * @param enabled true if the popup should be attached to the decor frame of its parent window. + * + * @see WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR + */ + public void setAttachedInDecor(boolean enabled) { + mAttachedInDecor = enabled; + mAttachedInDecorSet = true; + } + + /** * Allows the popup window to force the flag * {@link WindowManager.LayoutParams#FLAG_LAYOUT_INSET_DECOR}, overriding default behavior. * This will cause the popup to inset its content to account for system windows overlaying @@ -1140,9 +1186,12 @@ public class PopupWindow { if (mNotTouchModal) { curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL; } + if (mAttachedInDecor) { + curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_ATTACHED_IN_DECOR; + } return curFlags; } - + private int computeAnimationResource() { if (mAnimationStyle == -1) { if (mIsDropdown) { diff --git a/core/java/android/widget/RadialTimePickerView.java b/core/java/android/widget/RadialTimePickerView.java index d15f2d6e9e08..24fc2bb9a8d2 100644 --- a/core/java/android/widget/RadialTimePickerView.java +++ b/core/java/android/widget/RadialTimePickerView.java @@ -28,13 +28,13 @@ import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; +import android.graphics.Rect; import android.graphics.Typeface; -import android.graphics.RectF; import android.os.Bundle; -import android.text.format.DateUtils; -import android.text.format.Time; import android.util.AttributeSet; +import android.util.IntArray; import android.util.Log; +import android.util.MathUtils; import android.util.TypedValue; import android.view.HapticFeedbackConstants; import android.view.MotionEvent; @@ -42,8 +42,10 @@ import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; +import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import com.android.internal.R; +import com.android.internal.widget.ExploreByTouchHelper; import java.util.ArrayList; import java.util.Calendar; @@ -97,6 +99,9 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { private static int[] sSnapPrefer30sMap = new int[361]; + private final InvalidateUpdateListener mInvalidateUpdateListener = + new InvalidateUpdateListener(); + private final String[] mHours12Texts = new String[12]; private final String[] mOuterHours24Texts = new String[12]; private final String[] mInnerHours24Texts = new String[12]; @@ -115,7 +120,39 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { private final Paint mPaintBackground = new Paint(); private final Paint mPaintDebug = new Paint(); - private Typeface mTypeface; + private final Typeface mTypeface; + + private final float[] mCircleRadius = new float[3]; + + private final float[] mTextSize = new float[2]; + + private final float[][] mTextGridHeights = new float[2][7]; + private final float[][] mTextGridWidths = new float[2][7]; + + private final float[] mInnerTextGridHeights = new float[7]; + private final float[] mInnerTextGridWidths = new float[7]; + + private final float[] mCircleRadiusMultiplier = new float[2]; + private final float[] mNumbersRadiusMultiplier = new float[3]; + + private final float[] mTextSizeMultiplier = new float[3]; + + private final float[] mAnimationRadiusMultiplier = new float[3]; + + private final float mTransitionMidRadiusMultiplier; + private final float mTransitionEndRadiusMultiplier; + + private final int[] mLineLength = new int[3]; + private final int[] mSelectionRadius = new int[3]; + private final float mSelectionRadiusMultiplier; + private final int[] mSelectionDegrees = new int[3]; + + private final ArrayList<Animator> mHoursToMinutesAnims = new ArrayList<Animator>(); + private final ArrayList<Animator> mMinuteToHoursAnims = new ArrayList<Animator>(); + + private final RadialPickerTouchHelper mTouchHelper; + + private float mInnerTextSize; private boolean mIs24HourMode; private boolean mShowHours; @@ -129,52 +166,21 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { private int mXCenter; private int mYCenter; - private float[] mCircleRadius = new float[3]; - private int mMinHypotenuseForInnerNumber; private int mMaxHypotenuseForOuterNumber; private int mHalfwayHypotenusePoint; - private float[] mTextSize = new float[2]; - private float mInnerTextSize; - - private float[][] mTextGridHeights = new float[2][7]; - private float[][] mTextGridWidths = new float[2][7]; - - private float[] mInnerTextGridHeights = new float[7]; - private float[] mInnerTextGridWidths = new float[7]; - private String[] mOuterTextHours; private String[] mInnerTextHours; private String[] mOuterTextMinutes; - - private float[] mCircleRadiusMultiplier = new float[2]; - private float[] mNumbersRadiusMultiplier = new float[3]; - - private float[] mTextSizeMultiplier = new float[3]; - - private float[] mAnimationRadiusMultiplier = new float[3]; - - private float mTransitionMidRadiusMultiplier; - private float mTransitionEndRadiusMultiplier; - private AnimatorSet mTransition; - private InvalidateUpdateListener mInvalidateUpdateListener = new InvalidateUpdateListener(); - - private int[] mLineLength = new int[3]; - private int[] mSelectionRadius = new int[3]; - private float mSelectionRadiusMultiplier; - private int[] mSelectionDegrees = new int[3]; private int mAmOrPm; private int mDisabledAlpha; - private RectF mRectF = new RectF(); - private boolean mInputEnabled = true; private OnValueSelectedListener mListener; - private final ArrayList<Animator> mHoursToMinutesAnims = new ArrayList<Animator>(); - private final ArrayList<Animator> mMinuteToHoursAnims = new ArrayList<Animator>(); + private boolean mInputEnabled = true; public interface OnValueSelectedListener { void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance); @@ -282,11 +288,21 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { return degrees; } + @SuppressWarnings("unused") + public RadialTimePickerView(Context context) { + this(context, null); + } + public RadialTimePickerView(Context context, AttributeSet attrs) { this(context, attrs, R.attr.timePickerStyle); } - public RadialTimePickerView(Context context, AttributeSet attrs, int defStyle) { + public RadialTimePickerView(Context context, AttributeSet attrs, int defStyleAttr) { + this(context, attrs, defStyleAttr, 0); + } + + public RadialTimePickerView( + Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs); // Pull disabled alpha from theme. @@ -297,7 +313,7 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { // process style attributes final Resources res = getResources(); final TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.TimePicker, - defStyle, 0); + defStyleAttr, defStyleRes); mTypeface = Typeface.create("sans-serif", Typeface.NORMAL); @@ -382,6 +398,14 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { mIs24HourMode = false; mAmOrPm = AM; + // Set up accessibility components. + mTouchHelper = new RadialPickerTouchHelper(); + setAccessibilityDelegate(mTouchHelper); + + if (getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) { + setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); + } + initHoursAndMinutesText(); initData(); @@ -406,8 +430,8 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { final int currentHour = calendar.get(Calendar.HOUR_OF_DAY); final int currentMinute = calendar.get(Calendar.MINUTE); - setCurrentHour(currentHour); - setCurrentMinute(currentMinute); + setCurrentHourInternal(currentHour, false, false); + setCurrentMinuteInternal(currentMinute, false); setHapticFeedbackEnabled(true); } @@ -429,8 +453,9 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { public void initialize(int hour, int minute, boolean is24HourMode) { mIs24HourMode = is24HourMode; - setCurrentHour(hour); - setCurrentMinute(minute); + + setCurrentHourInternal(hour, false, false); + setCurrentMinuteInternal(minute, false); } public void setCurrentItemShowing(int item, boolean animate) { @@ -460,17 +485,39 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { * @param hour the current hour between 0 and 23 (inclusive) */ public void setCurrentHour(int hour) { + setCurrentHourInternal(hour, true, false); + } + + /** + * Sets the current hour. + * + * @param hour The current hour + * @param callback Whether the value listener should be invoked + * @param autoAdvance Whether the listener should auto-advance to the next + * selection mode, e.g. hour to minutes + */ + private void setCurrentHourInternal(int hour, boolean callback, boolean autoAdvance) { final int degrees = (hour % 12) * DEGREES_FOR_ONE_HOUR; mSelectionDegrees[HOURS] = degrees; mSelectionDegrees[HOURS_INNER] = degrees; // 0 is 12 AM (midnight) and 12 is 12 PM (noon). - mAmOrPm = (hour == 0 || (hour % 24) < 12) ? AM : PM; - mIsOnInnerCircle = mIs24HourMode && hour >= 1 && hour <= 12; + final int amOrPm = (hour == 0 || (hour % 24) < 12) ? AM : PM; + final boolean isOnInnerCircle = mIs24HourMode && hour >= 1 && hour <= 12; + if (mAmOrPm != amOrPm || mIsOnInnerCircle != isOnInnerCircle) { + mAmOrPm = amOrPm; + mIsOnInnerCircle = isOnInnerCircle; + + initData(); + updateLayoutData(); + mTouchHelper.invalidateRoot(); + } - initData(); - updateLayoutData(); invalidate(); + + if (callback && mListener != null) { + mListener.onValueSelected(HOURS, hour, autoAdvance); + } } /** @@ -479,15 +526,19 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { * @return the current hour between 0 and 23 (inclusive) */ public int getCurrentHour() { - int hour = (mSelectionDegrees[mIsOnInnerCircle ? - HOURS_INNER : HOURS] / DEGREES_FOR_ONE_HOUR) % 12; + return getHourForDegrees( + mSelectionDegrees[mIsOnInnerCircle ? HOURS_INNER : HOURS], mIsOnInnerCircle); + } + + private int getHourForDegrees(int degrees, boolean innerCircle) { + int hour = (degrees / DEGREES_FOR_ONE_HOUR) % 12; if (mIs24HourMode) { // Convert the 12-hour value into 24-hour time based on where the // selector is positioned. - if (mIsOnInnerCircle && hour == 0) { + if (innerCircle && hour == 0) { // Inner circle is 1 through 12. hour = 12; - } else if (!mIsOnInnerCircle && hour != 0) { + } else if (!innerCircle && hour != 0) { // Outer circle is 13 through 23 and 0. hour += 12; } @@ -497,19 +548,49 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { return hour; } + private int getDegreesForHour(int hour) { + // Convert to be 0-11. + if (mIs24HourMode) { + if (hour >= 12) { + hour -= 12; + } + } else if (hour == 12) { + hour = 0; + } + return hour * DEGREES_FOR_ONE_HOUR; + } + public void setCurrentMinute(int minute) { + setCurrentMinuteInternal(minute, true); + } + + private void setCurrentMinuteInternal(int minute, boolean callback) { mSelectionDegrees[MINUTES] = (minute % 60) * DEGREES_FOR_ONE_MINUTE; + invalidate(); + + if (callback && mListener != null) { + mListener.onValueSelected(MINUTES, minute, false); + } } // Returns minutes in 0-59 range public int getCurrentMinute() { - return (mSelectionDegrees[MINUTES] / DEGREES_FOR_ONE_MINUTE); + return getMinuteForDegrees(mSelectionDegrees[MINUTES]); + } + + private int getMinuteForDegrees(int degrees) { + return degrees / DEGREES_FOR_ONE_MINUTE; + } + + private int getDegreesForMinute(int minute) { + return minute * DEGREES_FOR_ONE_MINUTE; } public void setAmOrPm(int val) { mAmOrPm = (val % 2); invalidate(); + mTouchHelper.invalidateRoot(); } public int getAmOrPm() { @@ -648,6 +729,8 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { mSelectionRadius[HOURS] = (int) (mCircleRadius[HOURS] * mSelectionRadiusMultiplier); mSelectionRadius[HOURS_INNER] = mSelectionRadius[HOURS]; mSelectionRadius[MINUTES] = (int) (mCircleRadius[MINUTES] * mSelectionRadiusMultiplier); + + mTouchHelper.invalidateRoot(); } @Override @@ -769,20 +852,17 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { float top = mYCenter - outerRadius; float right = mXCenter + outerRadius; float bottom = mYCenter + outerRadius; - mRectF = new RectF(left, top, right, bottom); - canvas.drawRect(mRectF, mPaintDebug); + canvas.drawRect(left, top, right, bottom, mPaintDebug); // Draw outer rectangle for background left = mXCenter - mCircleRadius[HOURS]; top = mYCenter - mCircleRadius[HOURS]; right = mXCenter + mCircleRadius[HOURS]; bottom = mYCenter + mCircleRadius[HOURS]; - mRectF.set(left, top, right, bottom); - canvas.drawRect(mRectF, mPaintDebug); + canvas.drawRect(left, top, right, bottom, mPaintDebug); // Draw outer view rectangle - mRectF.set(0, 0, getWidth(), getHeight()); - canvas.drawRect(mRectF, mPaintDebug); + canvas.drawRect(0, 0, getWidth(), getHeight(), mPaintDebug); // Draw selected time final String selected = String.format("%02d:%02d", getCurrentHour(), getCurrentMinute()); @@ -896,12 +976,14 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { } // Used for animating the hours by changing their radius + @SuppressWarnings("unused") private void setAnimationRadiusMultiplierHours(float animationRadiusMultiplier) { mAnimationRadiusMultiplier[HOURS] = animationRadiusMultiplier; mAnimationRadiusMultiplier[HOURS_INNER] = animationRadiusMultiplier; } // Used for animating the minutes by changing their radius + @SuppressWarnings("unused") private void setAnimationRadiusMultiplierMinutes(float animationRadiusMultiplier) { mAnimationRadiusMultiplier[MINUTES] = animationRadiusMultiplier; } @@ -1094,21 +1176,25 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { } final float opposite = Math.abs(y - mYCenter); - double degrees = Math.toDegrees(Math.asin(opposite / hypotenuse)); + int degrees = (int) (Math.toDegrees(Math.asin(opposite / hypotenuse)) + 0.5); // Now we have to translate to the correct quadrant. - boolean rightSide = (x > mXCenter); - boolean topSide = (y < mYCenter); - if (rightSide && topSide) { - degrees = 90 - degrees; - } else if (rightSide && !topSide) { - degrees = 90 + degrees; - } else if (!rightSide && !topSide) { - degrees = 270 - degrees; - } else if (!rightSide && topSide) { - degrees = 270 + degrees; + final boolean rightSide = (x > mXCenter); + final boolean topSide = (y < mYCenter); + if (rightSide) { + if (topSide) { + degrees = 90 - degrees; + } else { + degrees = 90 + degrees; + } + } else { + if (topSide) { + degrees = 270 + degrees; + } else { + degrees = 270 - degrees; + } } - return (int) degrees; + return degrees; } @Override @@ -1176,109 +1262,277 @@ public class RadialTimePickerView extends View implements View.OnTouchListener { return result; } - /** - * Necessary for accessibility, to ensure we support "scrolling" forward and backward - * in the circle. - */ - @Override - public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { - super.onInitializeAccessibilityNodeInfo(info); - info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD); - info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD); - } - - /** - * Announce the currently-selected time when launched. - */ @Override - public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) { - if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) { - // Clear the event's current text so that only the current time will be spoken. - event.getText().clear(); - Time time = new Time(); - time.hour = getCurrentHour(); - time.minute = getCurrentMinute(); - long millis = time.normalize(true); - int flags = DateUtils.FORMAT_SHOW_TIME; - if (mIs24HourMode) { - flags |= DateUtils.FORMAT_24HOUR; - } - String timeString = DateUtils.formatDateTime(getContext(), millis, flags); - event.getText().add(timeString); + public boolean dispatchHoverEvent(MotionEvent event) { + // First right-of-refusal goes the touch exploration helper. + if (mTouchHelper.dispatchHoverEvent(event)) { return true; } - return super.dispatchPopulateAccessibilityEvent(event); + return super.dispatchHoverEvent(event); } - /** - * When scroll forward/backward events are received, jump the time to the higher/lower - * discrete, visible value on the circle. - */ - @Override - public boolean performAccessibilityAction(int action, Bundle arguments) { - if (super.performAccessibilityAction(action, arguments)) { - return true; + public void setInputEnabled(boolean inputEnabled) { + mInputEnabled = inputEnabled; + invalidate(); + } + + private class RadialPickerTouchHelper extends ExploreByTouchHelper { + private final Rect mTempRect = new Rect(); + + private final int TYPE_HOUR = 1; + private final int TYPE_MINUTE = 2; + + private final int SHIFT_TYPE = 0; + private final int MASK_TYPE = 0xF; + + private final int SHIFT_VALUE = 8; + private final int MASK_VALUE = 0xFF; + + /** Increment in which virtual views are exposed for minutes. */ + private final int MINUTE_INCREMENT = 5; + + public RadialPickerTouchHelper() { + super(RadialTimePickerView.this); } - int changeMultiplier = 0; - if (action == AccessibilityNodeInfo.ACTION_SCROLL_FORWARD) { - changeMultiplier = 1; - } else if (action == AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD) { - changeMultiplier = -1; + @Override + public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) { + super.onInitializeAccessibilityNodeInfo(host, info); + + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_FORWARD); + info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_SCROLL_BACKWARD); } - if (changeMultiplier != 0) { - int value; - final int stepSize; - if (mShowHours) { - stepSize = DEGREES_FOR_ONE_HOUR; - value = getCurrentHour() % 12; - } else { - stepSize = DEGREES_FOR_ONE_MINUTE; - value = getCurrentMinute(); + + @Override + public boolean performAccessibilityAction(View host, int action, Bundle arguments) { + if (super.performAccessibilityAction(host, action, arguments)) { + return true; } - int degrees = value * stepSize; - degrees = snapOnly30s(degrees, changeMultiplier); - value = degrees / stepSize; + switch (action) { + case AccessibilityNodeInfo.ACTION_SCROLL_FORWARD: + adjustPicker(1); + return true; + case AccessibilityNodeInfo.ACTION_SCROLL_BACKWARD: + adjustPicker(-1); + return true; + } + + return false; + } + + private void adjustPicker(int step) { + final int stepSize; + final int initialValue; final int maxValue; - int minValue = 0; + final int minValue; if (mShowHours) { + stepSize = DEGREES_FOR_ONE_HOUR; + initialValue = getCurrentHour() % 12; + if (mIs24HourMode) { maxValue = 23; + minValue = 0; } else { maxValue = 12; minValue = 1; } } else { + stepSize = DEGREES_FOR_ONE_MINUTE; + initialValue = getCurrentMinute(); + maxValue = 55; + minValue = 0; } - if (value > maxValue) { - // If we scrolled forward past the highest number, wrap around to the lowest. - value = minValue; - } else if (value < minValue) { - // If we scrolled backward past the lowest number, wrap around to the highest. - value = maxValue; + + final int steppedValue = snapOnly30s(initialValue * stepSize, step) / stepSize; + final int clampedValue = MathUtils.constrain(steppedValue, minValue, maxValue); + if (mShowHours) { + setCurrentHour(clampedValue); + } else { + setCurrentMinute(clampedValue); + } + } + + @Override + protected int getVirtualViewAt(float x, float y) { + final int id; + final int degrees = getDegreesFromXY(x, y); + if (degrees != -1) { + final int snapDegrees = snapOnly30s(degrees, 0) % 360; + if (mShowHours) { + final int hour = getHourForDegrees(snapDegrees, mIsOnInnerCircle); + id = makeId(TYPE_HOUR, hour); + } else { + final int current = getCurrentMinute(); + final int touched = getMinuteForDegrees(degrees); + final int snapped = getMinuteForDegrees(snapDegrees); + + // If the touched minute is closer to the current minute + // than it is to the snapped minute, return current. + final int minute; + if (Math.abs(current - touched) < Math.abs(snapped - touched)) { + minute = current; + } else { + minute = snapped; + } + id = makeId(TYPE_MINUTE, minute); + } + } else { + id = INVALID_ID; } + + return id; + } + + @Override + protected void getVisibleVirtualViews(IntArray virtualViewIds) { if (mShowHours) { - setCurrentHour(value); - if (mListener != null) { - mListener.onValueSelected(HOURS, value, false); + final int min = mIs24HourMode ? 0 : 1; + final int max = mIs24HourMode ? 23 : 12; + for (int i = min; i <= max ; i++) { + virtualViewIds.add(makeId(TYPE_HOUR, i)); } } else { - setCurrentMinute(value); - if (mListener != null) { - mListener.onValueSelected(MINUTES, value, false); + final int current = getCurrentMinute(); + for (int i = 0; i < 60; i += MINUTE_INCREMENT) { + virtualViewIds.add(makeId(TYPE_MINUTE, i)); + + // If the current minute falls between two increments, + // insert an extra node for it. + if (current > i && current < i + MINUTE_INCREMENT) { + virtualViewIds.add(makeId(TYPE_MINUTE, current)); + } } } - return true; } - return false; - } + @Override + protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) { + event.setClassName(getClass().getName()); - public void setInputEnabled(boolean inputEnabled) { - mInputEnabled = inputEnabled; - invalidate(); + final int type = getTypeFromId(virtualViewId); + final int value = getValueFromId(virtualViewId); + final CharSequence description = getVirtualViewDescription(type, value); + event.setContentDescription(description); + } + + @Override + protected void onPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfo node) { + node.setClassName(getClass().getName()); + node.addAction(AccessibilityAction.ACTION_CLICK); + + final int type = getTypeFromId(virtualViewId); + final int value = getValueFromId(virtualViewId); + final CharSequence description = getVirtualViewDescription(type, value); + node.setContentDescription(description); + + getBoundsForVirtualView(virtualViewId, mTempRect); + node.setBoundsInParent(mTempRect); + + final boolean selected = isVirtualViewSelected(type, value); + node.setSelected(selected); + } + + @Override + protected boolean onPerformActionForVirtualView(int virtualViewId, int action, + Bundle arguments) { + if (action == AccessibilityNodeInfo.ACTION_CLICK) { + final int type = getTypeFromId(virtualViewId); + final int value = getValueFromId(virtualViewId); + if (type == TYPE_HOUR) { + final int hour = mIs24HourMode ? value : hour12To24(value, mAmOrPm); + setCurrentHour(hour); + return true; + } else if (type == TYPE_MINUTE) { + setCurrentMinute(value); + return true; + } + } + return false; + } + + private int hour12To24(int hour12, int amOrPm) { + int hour24 = hour12; + if (hour12 == 12) { + if (amOrPm == AM) { + hour24 = 0; + } + } else if (amOrPm == PM) { + hour24 += 12; + } + return hour24; + } + + private void getBoundsForVirtualView(int virtualViewId, Rect bounds) { + final float radius; + final int type = getTypeFromId(virtualViewId); + final int value = getValueFromId(virtualViewId); + final float centerRadius; + final float degrees; + if (type == TYPE_HOUR) { + final boolean innerCircle = mIs24HourMode && value > 0 && value <= 12; + if (innerCircle) { + centerRadius = mCircleRadius[HOURS_INNER] * mNumbersRadiusMultiplier[HOURS_INNER]; + radius = mSelectionRadius[HOURS_INNER]; + } else { + centerRadius = mCircleRadius[HOURS] * mNumbersRadiusMultiplier[HOURS]; + radius = mSelectionRadius[HOURS]; + } + + degrees = getDegreesForHour(value); + } else if (type == TYPE_MINUTE) { + centerRadius = mCircleRadius[MINUTES] * mNumbersRadiusMultiplier[MINUTES]; + degrees = getDegreesForMinute(value); + radius = mSelectionRadius[MINUTES]; + } else { + // This should never happen. + centerRadius = 0; + degrees = 0; + radius = 0; + } + + final double radians = Math.toRadians(degrees); + final float xCenter = mXCenter + centerRadius * (float) Math.sin(radians); + final float yCenter = mYCenter - centerRadius * (float) Math.cos(radians); + + bounds.set((int) (xCenter - radius), (int) (yCenter - radius), + (int) (xCenter + radius), (int) (yCenter + radius)); + } + + private CharSequence getVirtualViewDescription(int type, int value) { + final CharSequence description; + if (type == TYPE_HOUR || type == TYPE_MINUTE) { + description = Integer.toString(value); + } else { + description = null; + } + return description; + } + + private boolean isVirtualViewSelected(int type, int value) { + final boolean selected; + if (type == TYPE_HOUR) { + selected = getCurrentHour() == value; + } else if (type == TYPE_MINUTE) { + selected = getCurrentMinute() == value; + } else { + selected = false; + } + return selected; + } + + private int makeId(int type, int value) { + return type << SHIFT_TYPE | value << SHIFT_VALUE; + } + + private int getTypeFromId(int id) { + return id >>> SHIFT_TYPE & MASK_TYPE; + } + + private int getValueFromId(int id) { + return id >>> SHIFT_VALUE & MASK_VALUE; + } } private static class IntHolder { diff --git a/core/java/android/widget/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java index a76241ed1a50..59baabaebae5 100644 --- a/core/java/android/widget/SimpleMonthView.java +++ b/core/java/android/widget/SimpleMonthView.java @@ -31,6 +31,7 @@ import android.text.format.DateFormat; import android.text.format.DateUtils; import android.text.format.Time; import android.util.AttributeSet; +import android.util.IntArray; import android.util.MathUtils; import android.view.MotionEvent; import android.view.View; @@ -610,7 +611,7 @@ class SimpleMonthView extends View { } @Override - protected void getVisibleVirtualViews(List<Integer> virtualViewIds) { + protected void getVisibleVirtualViews(IntArray virtualViewIds) { for (int day = 1; day <= mNumCells; day++) { virtualViewIds.add(day); } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 5cdee53abb15..0917b32e89d4 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -8518,6 +8518,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } return false; case AccessibilityNodeInfo.ACTION_SET_SELECTION: { if (isFocused() && canSelectText()) { + ensureIterableTextForAccessibilitySelectable(); CharSequence text = getIterableTextForAccessibility(); if (text == null) { return false; @@ -8543,6 +8544,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } } } return false; + case AccessibilityNodeInfo.ACTION_NEXT_AT_MOVEMENT_GRANULARITY: + case AccessibilityNodeInfo.ACTION_PREVIOUS_AT_MOVEMENT_GRANULARITY: { + ensureIterableTextForAccessibilitySelectable(); + return super.performAccessibilityAction(action, arguments); + } default: { return super.performAccessibilityAction(action, arguments); } @@ -9032,10 +9038,13 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener */ @Override public CharSequence getIterableTextForAccessibility() { + return mText; + } + + private void ensureIterableTextForAccessibilitySelectable() { if (!(mText instanceof Spannable)) { setText(mText, BufferType.SPANNABLE); } - return mText; } /** diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java index 85cf67b90e5e..26e02f8a3a24 100644 --- a/core/java/android/widget/TimePicker.java +++ b/core/java/android/widget/TimePicker.java @@ -86,12 +86,12 @@ public class TimePicker extends FrameLayout { switch (mode) { case MODE_CLOCK: - mDelegate = new TimePickerSpinnerDelegate( + mDelegate = new TimePickerClockDelegate( this, context, attrs, defStyleAttr, defStyleRes); break; case MODE_SPINNER: default: - mDelegate = new TimePickerClockDelegate( + mDelegate = new TimePickerSpinnerDelegate( this, context, attrs, defStyleAttr, defStyleRes); break; } diff --git a/core/java/android/widget/TimePickerClockDelegate.java b/core/java/android/widget/TimePickerClockDelegate.java index 6dfea9256bf1..78ee2471dcb1 100644 --- a/core/java/android/widget/TimePickerClockDelegate.java +++ b/core/java/android/widget/TimePickerClockDelegate.java @@ -17,365 +17,376 @@ package android.widget; import android.content.Context; +import android.content.res.ColorStateList; import android.content.res.Configuration; +import android.content.res.Resources; import android.content.res.TypedArray; import android.os.Parcel; import android.os.Parcelable; +import android.text.TextUtils; import android.text.format.DateFormat; import android.text.format.DateUtils; import android.util.AttributeSet; +import android.util.Log; +import android.util.TypedValue; +import android.view.HapticFeedbackConstants; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputMethodManager; + import com.android.internal.R; -import java.text.DateFormatSymbols; +import java.util.ArrayList; import java.util.Calendar; import java.util.Locale; -import libcore.icu.LocaleData; - -import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO; -import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES; - /** - * A delegate implementing the basic spinner-based TimePicker. + * A delegate implementing the radial clock-based TimePicker. */ -class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { +class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate implements + RadialTimePickerView.OnValueSelectedListener { + + private static final String TAG = "TimePickerClockDelegate"; + + // Index used by RadialPickerLayout + private static final int HOUR_INDEX = 0; + private static final int MINUTE_INDEX = 1; + + // NOT a real index for the purpose of what's showing. + private static final int AMPM_INDEX = 2; + + // Also NOT a real index, just used for keyboard mode. + private static final int ENABLE_PICKER_INDEX = 3; + + static final int AM = 0; + static final int PM = 1; + private static final boolean DEFAULT_ENABLED_STATE = true; + private boolean mIsEnabled = DEFAULT_ENABLED_STATE; + private static final int HOURS_IN_HALF_DAY = 12; - // state - private boolean mIs24HourView; - private boolean mIsAm; + private final View mHeaderView; + private final TextView mHourView; + private final TextView mMinuteView; + private final View mAmPmLayout; + private final CheckedTextView mAmLabel; + private final CheckedTextView mPmLabel; + private final RadialTimePickerView mRadialTimePickerView; + private final TextView mSeparatorView; - // ui components - private final NumberPicker mHourSpinner; - private final NumberPicker mMinuteSpinner; - private final NumberPicker mAmPmSpinner; - private final EditText mHourSpinnerInput; - private final EditText mMinuteSpinnerInput; - private final EditText mAmPmSpinnerInput; - private final TextView mDivider; + private final String mAmText; + private final String mPmText; - // Note that the legacy implementation of the TimePicker is - // using a button for toggling between AM/PM while the new - // version uses a NumberPicker spinner. Therefore the code - // accommodates these two cases to be backwards compatible. - private final Button mAmPmButton; + private final float mDisabledAlpha; - private final String[] mAmPmStrings; + private boolean mAllowAutoAdvance; + private int mInitialHourOfDay; + private int mInitialMinute; + private boolean mIs24HourView; + + // For hardware IME input. + private char mPlaceholderText; + private String mDoublePlaceholderText; + private String mDeletedKeyFormat; + private boolean mInKbMode; + private ArrayList<Integer> mTypedTimes = new ArrayList<Integer>(); + private Node mLegalTimesTree; + private int mAmKeyCode; + private int mPmKeyCode; + + // Accessibility strings. + private String mHourPickerDescription; + private String mSelectHours; + private String mMinutePickerDescription; + private String mSelectMinutes; + + // Most recent time announcement values for accessibility. + private CharSequence mLastAnnouncedText; + private boolean mLastAnnouncedIsHour; - private boolean mIsEnabled = DEFAULT_ENABLED_STATE; private Calendar mTempCalendar; - private boolean mHourWithTwoDigit; - private char mHourFormat; public TimePickerClockDelegate(TimePicker delegator, Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(delegator, context); // process style attributes - final TypedArray a = mContext.obtainStyledAttributes( - attrs, R.styleable.TimePicker, defStyleAttr, defStyleRes); - final int layoutResourceId = a.getResourceId( - R.styleable.TimePicker_legacyLayout, R.layout.time_picker_legacy); - a.recycle(); + final TypedArray a = mContext.obtainStyledAttributes(attrs, + R.styleable.TimePicker, defStyleAttr, defStyleRes); + final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + final Resources res = mContext.getResources(); + + mHourPickerDescription = res.getString(R.string.hour_picker_description); + mSelectHours = res.getString(R.string.select_hours); + mMinutePickerDescription = res.getString(R.string.minute_picker_description); + mSelectMinutes = res.getString(R.string.select_minutes); + + String[] amPmStrings = TimePickerSpinnerDelegate.getAmPmStrings(context); + mAmText = amPmStrings[0]; + mPmText = amPmStrings[1]; + + final int layoutResourceId = a.getResourceId(R.styleable.TimePicker_internalLayout, + R.layout.time_picker_holo); + final View mainView = inflater.inflate(layoutResourceId, delegator); + + mHeaderView = mainView.findViewById(R.id.time_header); + mHeaderView.setBackground(a.getDrawable(R.styleable.TimePicker_headerBackground)); + + // Set up hour/minute labels. + mHourView = (TextView) mHeaderView.findViewById(R.id.hours); + mHourView.setOnClickListener(mClickListener); + mSeparatorView = (TextView) mHeaderView.findViewById(R.id.separator); + mMinuteView = (TextView) mHeaderView.findViewById(R.id.minutes); + mMinuteView.setOnClickListener(mClickListener); + + final int headerTimeTextAppearance = a.getResourceId( + R.styleable.TimePicker_headerTimeTextAppearance, 0); + if (headerTimeTextAppearance != 0) { + mHourView.setTextAppearance(context, headerTimeTextAppearance); + mSeparatorView.setTextAppearance(context, headerTimeTextAppearance); + mMinuteView.setTextAppearance(context, headerTimeTextAppearance); + } - final LayoutInflater inflater = LayoutInflater.from(mContext); - inflater.inflate(layoutResourceId, mDelegator, true); - - // hour - mHourSpinner = (NumberPicker) delegator.findViewById(R.id.hour); - mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { - public void onValueChange(NumberPicker spinner, int oldVal, int newVal) { - updateInputState(); - if (!is24HourView()) { - if ((oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) || - (oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1)) { - mIsAm = !mIsAm; - updateAmPmControl(); - } - } - onTimeChanged(); - } - }); - mHourSpinnerInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input); - mHourSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT); - - // divider (only for the new widget style) - mDivider = (TextView) mDelegator.findViewById(R.id.divider); - if (mDivider != null) { - setDividerText(); - } - - // minute - mMinuteSpinner = (NumberPicker) mDelegator.findViewById(R.id.minute); - mMinuteSpinner.setMinValue(0); - mMinuteSpinner.setMaxValue(59); - mMinuteSpinner.setOnLongPressUpdateInterval(100); - mMinuteSpinner.setFormatter(NumberPicker.getTwoDigitFormatter()); - mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { - public void onValueChange(NumberPicker spinner, int oldVal, int newVal) { - updateInputState(); - int minValue = mMinuteSpinner.getMinValue(); - int maxValue = mMinuteSpinner.getMaxValue(); - if (oldVal == maxValue && newVal == minValue) { - int newHour = mHourSpinner.getValue() + 1; - if (!is24HourView() && newHour == HOURS_IN_HALF_DAY) { - mIsAm = !mIsAm; - updateAmPmControl(); - } - mHourSpinner.setValue(newHour); - } else if (oldVal == minValue && newVal == maxValue) { - int newHour = mHourSpinner.getValue() - 1; - if (!is24HourView() && newHour == HOURS_IN_HALF_DAY - 1) { - mIsAm = !mIsAm; - updateAmPmControl(); - } - mHourSpinner.setValue(newHour); - } - onTimeChanged(); - } - }); - mMinuteSpinnerInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input); - mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT); - - // Get the localized am/pm strings and use them in the spinner. - mAmPmStrings = getAmPmStrings(context); - - // am/pm - final View amPmView = mDelegator.findViewById(R.id.amPm); - if (amPmView instanceof Button) { - mAmPmSpinner = null; - mAmPmSpinnerInput = null; - mAmPmButton = (Button) amPmView; - mAmPmButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View button) { - button.requestFocus(); - mIsAm = !mIsAm; - updateAmPmControl(); - onTimeChanged(); - } - }); - } else { - mAmPmButton = null; - mAmPmSpinner = (NumberPicker) amPmView; - mAmPmSpinner.setMinValue(0); - mAmPmSpinner.setMaxValue(1); - mAmPmSpinner.setDisplayedValues(mAmPmStrings); - mAmPmSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { - public void onValueChange(NumberPicker picker, int oldVal, int newVal) { - updateInputState(); - picker.requestFocus(); - mIsAm = !mIsAm; - updateAmPmControl(); - onTimeChanged(); - } - }); - mAmPmSpinnerInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input); - mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE); - } - - if (isAmPmAtStart()) { - // Move the am/pm view to the beginning - ViewGroup amPmParent = (ViewGroup) delegator.findViewById(R.id.timePickerLayout); - amPmParent.removeView(amPmView); - amPmParent.addView(amPmView, 0); - // Swap layout margins if needed. They may be not symmetrical (Old Standard Theme - // for example and not for Holo Theme) - ViewGroup.MarginLayoutParams lp = - (ViewGroup.MarginLayoutParams) amPmView.getLayoutParams(); - final int startMargin = lp.getMarginStart(); - final int endMargin = lp.getMarginEnd(); - if (startMargin != endMargin) { - lp.setMarginStart(endMargin); - lp.setMarginEnd(startMargin); - } + // TODO: This can be removed once we support themed color state lists. + final int headerSelectedTextColor = a.getColor( + R.styleable.TimePicker_headerSelectedTextColor, + res.getColor(R.color.timepicker_default_selector_color_material)); + mHourView.setTextColor(ColorStateList.addFirstIfMissing(mHourView.getTextColors(), + R.attr.state_selected, headerSelectedTextColor)); + mMinuteView.setTextColor(ColorStateList.addFirstIfMissing(mMinuteView.getTextColors(), + R.attr.state_selected, headerSelectedTextColor)); + + // Set up AM/PM labels. + mAmPmLayout = mHeaderView.findViewById(R.id.ampm_layout); + mAmLabel = (CheckedTextView) mAmPmLayout.findViewById(R.id.am_label); + mAmLabel.setText(amPmStrings[0]); + mAmLabel.setOnClickListener(mClickListener); + mPmLabel = (CheckedTextView) mAmPmLayout.findViewById(R.id.pm_label); + mPmLabel.setText(amPmStrings[1]); + mPmLabel.setOnClickListener(mClickListener); + + final int headerAmPmTextAppearance = a.getResourceId( + R.styleable.TimePicker_headerAmPmTextAppearance, 0); + if (headerAmPmTextAppearance != 0) { + mAmLabel.setTextAppearance(context, headerAmPmTextAppearance); + mPmLabel.setTextAppearance(context, headerAmPmTextAppearance); } - getHourFormatData(); + a.recycle(); + + // Pull disabled alpha from theme. + final TypedValue outValue = new TypedValue(); + context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true); + mDisabledAlpha = outValue.getFloat(); - // update controls to initial state - updateHourControl(); - updateMinuteControl(); - updateAmPmControl(); + mRadialTimePickerView = (RadialTimePickerView) mainView.findViewById( + R.id.radial_picker); - // set to current time - setCurrentHour(mTempCalendar.get(Calendar.HOUR_OF_DAY)); - setCurrentMinute(mTempCalendar.get(Calendar.MINUTE)); + setupListeners(); - if (!isEnabled()) { - setEnabled(false); - } + mAllowAutoAdvance = true; - // set the content descriptions - setContentDescriptions(); + // Set up for keyboard mode. + mDoublePlaceholderText = res.getString(R.string.time_placeholder); + mDeletedKeyFormat = res.getString(R.string.deleted_key); + mPlaceholderText = mDoublePlaceholderText.charAt(0); + mAmKeyCode = mPmKeyCode = -1; + generateLegalTimesTree(); - // If not explicitly specified this view is important for accessibility. - if (mDelegator.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) { - mDelegator.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); - } + // Initialize with current time + final Calendar calendar = Calendar.getInstance(mCurrentLocale); + final int currentHour = calendar.get(Calendar.HOUR_OF_DAY); + final int currentMinute = calendar.get(Calendar.MINUTE); + initialize(currentHour, currentMinute, false /* 12h */, HOUR_INDEX); } - private void getHourFormatData() { - final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, - (mIs24HourView) ? "Hm" : "hm"); - final int lengthPattern = bestDateTimePattern.length(); - mHourWithTwoDigit = false; - char hourFormat = '\0'; - // Check if the returned pattern is single or double 'H', 'h', 'K', 'k'. We also save - // the hour format that we found. - for (int i = 0; i < lengthPattern; i++) { - final char c = bestDateTimePattern.charAt(i); - if (c == 'H' || c == 'h' || c == 'K' || c == 'k') { - mHourFormat = c; - if (i + 1 < lengthPattern && c == bestDateTimePattern.charAt(i + 1)) { - mHourWithTwoDigit = true; - } - break; - } - } + private void initialize(int hourOfDay, int minute, boolean is24HourView, int index) { + mInitialHourOfDay = hourOfDay; + mInitialMinute = minute; + mIs24HourView = is24HourView; + mInKbMode = false; + updateUI(index); } - private boolean isAmPmAtStart() { - final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, - "hm" /* skeleton */); + private void setupListeners() { + mHeaderView.setOnKeyListener(mKeyListener); + mHeaderView.setOnFocusChangeListener(mFocusListener); + mHeaderView.setFocusable(true); - return bestDateTimePattern.startsWith("a"); + mRadialTimePickerView.setOnValueSelectedListener(this); } - /** - * The time separator is defined in the Unicode CLDR and cannot be supposed to be ":". - * - * See http://unicode.org/cldr/trac/browser/trunk/common/main - * - * We pass the correct "skeleton" depending on 12 or 24 hours view and then extract the - * separator as the character which is just after the hour marker in the returned pattern. - */ - private void setDividerText() { - final String skeleton = (mIs24HourView) ? "Hm" : "hm"; - final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, - skeleton); - final String separatorText; - int hourIndex = bestDateTimePattern.lastIndexOf('H'); - if (hourIndex == -1) { - hourIndex = bestDateTimePattern.lastIndexOf('h'); + private void updateUI(int index) { + // Update RadialPicker values + updateRadialPicker(index); + // Enable or disable the AM/PM view. + updateHeaderAmPm(); + // Update Hour and Minutes + updateHeaderHour(mInitialHourOfDay, false); + // Update time separator + updateHeaderSeparator(); + // Update Minutes + updateHeaderMinute(mInitialMinute, false); + // Invalidate everything + mDelegator.invalidate(); + } + + private void updateRadialPicker(int index) { + mRadialTimePickerView.initialize(mInitialHourOfDay, mInitialMinute, mIs24HourView); + setCurrentItemShowing(index, false, true); + } + + private int computeMaxWidthOfNumbers(int max) { + TextView tempView = new TextView(mContext); + tempView.setTextAppearance(mContext, R.style.TextAppearance_Material_TimePicker_TimeLabel); + ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT); + tempView.setLayoutParams(lp); + int maxWidth = 0; + for (int minutes = 0; minutes < max; minutes++) { + final String text = String.format("%02d", minutes); + tempView.setText(text); + tempView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); + maxWidth = Math.max(maxWidth, tempView.getMeasuredWidth()); } - if (hourIndex == -1) { - // Default case - separatorText = ":"; + return maxWidth; + } + + private void updateHeaderAmPm() { + if (mIs24HourView) { + mAmPmLayout.setVisibility(View.GONE); } else { - int minuteIndex = bestDateTimePattern.indexOf('m', hourIndex + 1); - if (minuteIndex == -1) { - separatorText = Character.toString(bestDateTimePattern.charAt(hourIndex + 1)); + final String bestDateTimePattern = DateFormat.getBestDateTimePattern( + mCurrentLocale, "hm"); + boolean amPmOnLeft = bestDateTimePattern.startsWith("a"); + if (TextUtils.getLayoutDirectionFromLocale(mCurrentLocale) == + View.LAYOUT_DIRECTION_RTL) { + amPmOnLeft = !amPmOnLeft; + } + + final ViewGroup.MarginLayoutParams params = + (ViewGroup.MarginLayoutParams) mAmPmLayout.getLayoutParams(); + + if (amPmOnLeft) { + params.leftMargin = 0; + params.rightMargin = computeMaxWidthOfNumbers(12 /* for hours */); } else { - separatorText = bestDateTimePattern.substring(hourIndex + 1, minuteIndex); + params.leftMargin = computeMaxWidthOfNumbers(60 /* for minutes */); + params.rightMargin = 0; } + + mAmPmLayout.setLayoutParams(params); + mAmPmLayout.setVisibility(View.VISIBLE); + + updateAmPmLabelStates(mInitialHourOfDay < 12 ? AM : PM); } - mDivider.setText(separatorText); } + /** + * Set the current hour. + */ @Override public void setCurrentHour(Integer currentHour) { - setCurrentHour(currentHour, true); - } - - private void setCurrentHour(Integer currentHour, boolean notifyTimeChanged) { - // why was Integer used in the first place? - if (currentHour == null || currentHour == getCurrentHour()) { + if (mInitialHourOfDay == currentHour) { return; } - if (!is24HourView()) { - // convert [0,23] ordinal to wall clock display - if (currentHour >= HOURS_IN_HALF_DAY) { - mIsAm = false; - if (currentHour > HOURS_IN_HALF_DAY) { - currentHour = currentHour - HOURS_IN_HALF_DAY; - } - } else { - mIsAm = true; - if (currentHour == 0) { - currentHour = HOURS_IN_HALF_DAY; - } - } - updateAmPmControl(); - } - mHourSpinner.setValue(currentHour); - if (notifyTimeChanged) { - onTimeChanged(); - } + mInitialHourOfDay = currentHour; + updateHeaderHour(currentHour, true); + updateHeaderAmPm(); + mRadialTimePickerView.setCurrentHour(currentHour); + mRadialTimePickerView.setAmOrPm(mInitialHourOfDay < 12 ? AM : PM); + mDelegator.invalidate(); + onTimeChanged(); } + /** + * @return The current hour in the range (0-23). + */ @Override public Integer getCurrentHour() { - int currentHour = mHourSpinner.getValue(); - if (is24HourView()) { + int currentHour = mRadialTimePickerView.getCurrentHour(); + if (mIs24HourView) { return currentHour; - } else if (mIsAm) { - return currentHour % HOURS_IN_HALF_DAY; } else { - return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY; + switch(mRadialTimePickerView.getAmOrPm()) { + case PM: + return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY; + case AM: + default: + return currentHour % HOURS_IN_HALF_DAY; + } } } + /** + * Set the current minute (0-59). + */ @Override public void setCurrentMinute(Integer currentMinute) { - if (currentMinute == getCurrentMinute()) { + if (mInitialMinute == currentMinute) { return; } - mMinuteSpinner.setValue(currentMinute); + mInitialMinute = currentMinute; + updateHeaderMinute(currentMinute, true); + mRadialTimePickerView.setCurrentMinute(currentMinute); + mDelegator.invalidate(); onTimeChanged(); } + /** + * @return The current minute. + */ @Override public Integer getCurrentMinute() { - return mMinuteSpinner.getValue(); + return mRadialTimePickerView.getCurrentMinute(); } + /** + * Set whether in 24 hour or AM/PM mode. + * + * @param is24HourView True = 24 hour mode. False = AM/PM. + */ @Override public void setIs24HourView(Boolean is24HourView) { - if (mIs24HourView == is24HourView) { + if (is24HourView == mIs24HourView) { return; } - // cache the current hour since spinner range changes and BEFORE changing mIs24HourView!! - int currentHour = getCurrentHour(); - // Order is important here. mIs24HourView = is24HourView; - getHourFormatData(); - updateHourControl(); - // set value after spinner range is updated - setCurrentHour(currentHour, false); - updateMinuteControl(); - updateAmPmControl(); + generateLegalTimesTree(); + int hour = mRadialTimePickerView.getCurrentHour(); + mInitialHourOfDay = hour; + updateHeaderHour(hour, false); + updateHeaderAmPm(); + updateRadialPicker(mRadialTimePickerView.getCurrentItemShowing()); + mDelegator.invalidate(); } + /** + * @return true if this is in 24 hour view else false. + */ @Override public boolean is24HourView() { return mIs24HourView; } @Override - public void setOnTimeChangedListener(TimePicker.OnTimeChangedListener onTimeChangedListener) { - mOnTimeChangedListener = onTimeChangedListener; + public void setOnTimeChangedListener(TimePicker.OnTimeChangedListener callback) { + mOnTimeChangedListener = callback; } @Override public void setEnabled(boolean enabled) { - mMinuteSpinner.setEnabled(enabled); - if (mDivider != null) { - mDivider.setEnabled(enabled); - } - mHourSpinner.setEnabled(enabled); - if (mAmPmSpinner != null) { - mAmPmSpinner.setEnabled(enabled); - } else { - mAmPmButton.setEnabled(enabled); - } + mHourView.setEnabled(enabled); + mMinuteView.setEnabled(enabled); + mAmLabel.setEnabled(enabled); + mPmLabel.setEnabled(enabled); + mRadialTimePickerView.setEnabled(enabled); mIsEnabled = enabled; } @@ -386,24 +397,38 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { @Override public int getBaseline() { - return mHourSpinner.getBaseline(); + // does not support baseline alignment + return -1; } @Override public void onConfigurationChanged(Configuration newConfig) { - setCurrentLocale(newConfig.locale); + updateUI(mRadialTimePickerView.getCurrentItemShowing()); } @Override public Parcelable onSaveInstanceState(Parcelable superState) { - return new SavedState(superState, getCurrentHour(), getCurrentMinute()); + return new SavedState(superState, getCurrentHour(), getCurrentMinute(), + is24HourView(), inKbMode(), getTypedTimes(), getCurrentItemShowing()); } @Override public void onRestoreInstanceState(Parcelable state) { SavedState ss = (SavedState) state; - setCurrentHour(ss.getHour()); - setCurrentMinute(ss.getMinute()); + setInKbMode(ss.inKbMode()); + setTypedTimes(ss.getTypesTimes()); + initialize(ss.getHour(), ss.getMinute(), ss.is24HourMode(), ss.getCurrentItemShowing()); + mRadialTimePickerView.invalidate(); + if (mInKbMode) { + tryStartingKbMode(-1); + mHourView.invalidate(); + } + } + + @Override + public void setCurrentLocale(Locale locale) { + super.setCurrentLocale(locale); + mTempCalendar = Calendar.getInstance(locale); } @Override @@ -422,9 +447,9 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { } mTempCalendar.set(Calendar.HOUR_OF_DAY, getCurrentHour()); mTempCalendar.set(Calendar.MINUTE, getCurrentMinute()); - String selectedDateUtterance = DateUtils.formatDateTime(mContext, + String selectedDate = DateUtils.formatDateTime(mContext, mTempCalendar.getTimeInMillis(), flags); - event.getText().add(selectedDateUtterance); + event.getText().add(selectedDate); } @Override @@ -437,121 +462,48 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { info.setClassName(TimePicker.class.getName()); } - private void updateInputState() { - // Make sure that if the user changes the value and the IME is active - // for one of the inputs if this widget, the IME is closed. If the user - // changed the value via the IME and there is a next input the IME will - // be shown, otherwise the user chose another means of changing the - // value and having the IME up makes no sense. - InputMethodManager inputMethodManager = InputMethodManager.peekInstance(); - if (inputMethodManager != null) { - if (inputMethodManager.isActive(mHourSpinnerInput)) { - mHourSpinnerInput.clearFocus(); - inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0); - } else if (inputMethodManager.isActive(mMinuteSpinnerInput)) { - mMinuteSpinnerInput.clearFocus(); - inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0); - } else if (inputMethodManager.isActive(mAmPmSpinnerInput)) { - mAmPmSpinnerInput.clearFocus(); - inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0); - } - } - } - - private void updateAmPmControl() { - if (is24HourView()) { - if (mAmPmSpinner != null) { - mAmPmSpinner.setVisibility(View.GONE); - } else { - mAmPmButton.setVisibility(View.GONE); - } - } else { - int index = mIsAm ? Calendar.AM : Calendar.PM; - if (mAmPmSpinner != null) { - mAmPmSpinner.setValue(index); - mAmPmSpinner.setVisibility(View.VISIBLE); - } else { - mAmPmButton.setText(mAmPmStrings[index]); - mAmPmButton.setVisibility(View.VISIBLE); - } - } - mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); - } - /** - * Sets the current locale. + * Set whether in keyboard mode or not. * - * @param locale The current locale. + * @param inKbMode True means in keyboard mode. */ - @Override - public void setCurrentLocale(Locale locale) { - super.setCurrentLocale(locale); - mTempCalendar = Calendar.getInstance(locale); + private void setInKbMode(boolean inKbMode) { + mInKbMode = inKbMode; } - private void onTimeChanged() { - mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); - if (mOnTimeChangedListener != null) { - mOnTimeChangedListener.onTimeChanged(mDelegator, getCurrentHour(), - getCurrentMinute()); - } + /** + * @return true if in keyboard mode + */ + private boolean inKbMode() { + return mInKbMode; } - private void updateHourControl() { - if (is24HourView()) { - // 'k' means 1-24 hour - if (mHourFormat == 'k') { - mHourSpinner.setMinValue(1); - mHourSpinner.setMaxValue(24); - } else { - mHourSpinner.setMinValue(0); - mHourSpinner.setMaxValue(23); - } - } else { - // 'K' means 0-11 hour - if (mHourFormat == 'K') { - mHourSpinner.setMinValue(0); - mHourSpinner.setMaxValue(11); - } else { - mHourSpinner.setMinValue(1); - mHourSpinner.setMaxValue(12); - } - } - mHourSpinner.setFormatter(mHourWithTwoDigit ? NumberPicker.getTwoDigitFormatter() : null); + private void setTypedTimes(ArrayList<Integer> typeTimes) { + mTypedTimes = typeTimes; } - private void updateMinuteControl() { - if (is24HourView()) { - mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE); - } else { - mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT); - } + /** + * @return an array of typed times + */ + private ArrayList<Integer> getTypedTimes() { + return mTypedTimes; } - private void setContentDescriptions() { - // Minute - trySetContentDescription(mMinuteSpinner, R.id.increment, - R.string.time_picker_increment_minute_button); - trySetContentDescription(mMinuteSpinner, R.id.decrement, - R.string.time_picker_decrement_minute_button); - // Hour - trySetContentDescription(mHourSpinner, R.id.increment, - R.string.time_picker_increment_hour_button); - trySetContentDescription(mHourSpinner, R.id.decrement, - R.string.time_picker_decrement_hour_button); - // AM/PM - if (mAmPmSpinner != null) { - trySetContentDescription(mAmPmSpinner, R.id.increment, - R.string.time_picker_increment_set_pm_button); - trySetContentDescription(mAmPmSpinner, R.id.decrement, - R.string.time_picker_decrement_set_am_button); - } + /** + * @return the index of the current item showing + */ + private int getCurrentItemShowing() { + return mRadialTimePickerView.getCurrentItemShowing(); } - private void trySetContentDescription(View root, int viewId, int contDescResId) { - View target = root.findViewById(viewId); - if (target != null) { - target.setContentDescription(mContext.getString(contDescResId)); + /** + * Propagate the time change + */ + private void onTimeChanged() { + mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + if (mOnTimeChangedListener != null) { + mOnTimeChangedListener.onTimeChanged(mDelegator, + getCurrentHour(), getCurrentMinute()); } } @@ -559,19 +511,34 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { * Used to save / restore state of time picker */ private static class SavedState extends View.BaseSavedState { + private final int mHour; private final int mMinute; - - private SavedState(Parcelable superState, int hour, int minute) { + private final boolean mIs24HourMode; + private final boolean mInKbMode; + private final ArrayList<Integer> mTypedTimes; + private final int mCurrentItemShowing; + + private SavedState(Parcelable superState, int hour, int minute, boolean is24HourMode, + boolean isKbMode, ArrayList<Integer> typedTimes, + int currentItemShowing) { super(superState); mHour = hour; mMinute = minute; + mIs24HourMode = is24HourMode; + mInKbMode = isKbMode; + mTypedTimes = typedTimes; + mCurrentItemShowing = currentItemShowing; } private SavedState(Parcel in) { super(in); mHour = in.readInt(); mMinute = in.readInt(); + mIs24HourMode = (in.readInt() == 1); + mInKbMode = (in.readInt() == 1); + mTypedTimes = in.readArrayList(getClass().getClassLoader()); + mCurrentItemShowing = in.readInt(); } public int getHour() { @@ -582,11 +549,31 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { return mMinute; } + public boolean is24HourMode() { + return mIs24HourMode; + } + + public boolean inKbMode() { + return mInKbMode; + } + + public ArrayList<Integer> getTypesTimes() { + return mTypedTimes; + } + + public int getCurrentItemShowing() { + return mCurrentItemShowing; + } + @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeInt(mHour); dest.writeInt(mMinute); + dest.writeInt(mIs24HourMode ? 1 : 0); + dest.writeInt(mInKbMode ? 1 : 0); + dest.writeList(mTypedTimes); + dest.writeInt(mCurrentItemShowing); } @SuppressWarnings({"unused", "hiding"}) @@ -601,11 +588,696 @@ class TimePickerClockDelegate extends TimePicker.AbstractTimePickerDelegate { }; } - public static String[] getAmPmStrings(Context context) { - String[] result = new String[2]; - LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale); - result[0] = d.amPm[0].length() > 2 ? d.narrowAm : d.amPm[0]; - result[1] = d.amPm[1].length() > 2 ? d.narrowPm : d.amPm[1]; - return result; + private void tryVibrate() { + mDelegator.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK); + } + + private void updateAmPmLabelStates(int amOrPm) { + final boolean isAm = amOrPm == AM; + mAmLabel.setChecked(isAm); + mAmLabel.setAlpha(isAm ? 1 : mDisabledAlpha); + + final boolean isPm = amOrPm == PM; + mPmLabel.setChecked(isPm); + mPmLabel.setAlpha(isPm ? 1 : mDisabledAlpha); + } + + /** + * Called by the picker for updating the header display. + */ + @Override + public void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance) { + if (pickerIndex == HOUR_INDEX) { + if (mAllowAutoAdvance && autoAdvance) { + updateHeaderHour(newValue, false); + setCurrentItemShowing(MINUTE_INDEX, true, false); + mDelegator.announceForAccessibility(newValue + ". " + mSelectMinutes); + } else { + updateHeaderHour(newValue, true); + } + } else if (pickerIndex == MINUTE_INDEX){ + updateHeaderMinute(newValue, true); + } else if (pickerIndex == AMPM_INDEX) { + updateAmPmLabelStates(newValue); + } else if (pickerIndex == ENABLE_PICKER_INDEX) { + if (!isTypedTimeFullyLegal()) { + mTypedTimes.clear(); + } + finishKbMode(); + } + } + + private void updateHeaderHour(int value, boolean announce) { + final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, + (mIs24HourView) ? "Hm" : "hm"); + final int lengthPattern = bestDateTimePattern.length(); + boolean hourWithTwoDigit = false; + char hourFormat = '\0'; + // Check if the returned pattern is single or double 'H', 'h', 'K', 'k'. We also save + // the hour format that we found. + for (int i = 0; i < lengthPattern; i++) { + final char c = bestDateTimePattern.charAt(i); + if (c == 'H' || c == 'h' || c == 'K' || c == 'k') { + hourFormat = c; + if (i + 1 < lengthPattern && c == bestDateTimePattern.charAt(i + 1)) { + hourWithTwoDigit = true; + } + break; + } + } + final String format; + if (hourWithTwoDigit) { + format = "%02d"; + } else { + format = "%d"; + } + if (mIs24HourView) { + // 'k' means 1-24 hour + if (hourFormat == 'k' && value == 0) { + value = 24; + } + } else { + // 'K' means 0-11 hour + value = modulo12(value, hourFormat == 'K'); + } + CharSequence text = String.format(format, value); + mHourView.setText(text); + if (announce) { + tryAnnounceForAccessibility(text, true); + } + } + + private void tryAnnounceForAccessibility(CharSequence text, boolean isHour) { + if (mLastAnnouncedIsHour != isHour || !text.equals(mLastAnnouncedText)) { + // TODO: Find a better solution, potentially live regions? + mDelegator.announceForAccessibility(text); + mLastAnnouncedText = text; + mLastAnnouncedIsHour = isHour; + } + } + + private static int modulo12(int n, boolean startWithZero) { + int value = n % 12; + if (value == 0 && !startWithZero) { + value = 12; + } + return value; + } + + /** + * The time separator is defined in the Unicode CLDR and cannot be supposed to be ":". + * + * See http://unicode.org/cldr/trac/browser/trunk/common/main + * + * We pass the correct "skeleton" depending on 12 or 24 hours view and then extract the + * separator as the character which is just after the hour marker in the returned pattern. + */ + private void updateHeaderSeparator() { + final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, + (mIs24HourView) ? "Hm" : "hm"); + final String separatorText; + // See http://www.unicode.org/reports/tr35/tr35-dates.html for hour formats + final char[] hourFormats = {'H', 'h', 'K', 'k'}; + int hIndex = lastIndexOfAny(bestDateTimePattern, hourFormats); + if (hIndex == -1) { + // Default case + separatorText = ":"; + } else { + separatorText = Character.toString(bestDateTimePattern.charAt(hIndex + 1)); + } + mSeparatorView.setText(separatorText); + } + + static private int lastIndexOfAny(String str, char[] any) { + final int lengthAny = any.length; + if (lengthAny > 0) { + for (int i = str.length() - 1; i >= 0; i--) { + char c = str.charAt(i); + for (int j = 0; j < lengthAny; j++) { + if (c == any[j]) { + return i; + } + } + } + } + return -1; + } + + private void updateHeaderMinute(int value, boolean announceForAccessibility) { + if (value == 60) { + value = 0; + } + final CharSequence text = String.format(mCurrentLocale, "%02d", value); + mMinuteView.setText(text); + if (announceForAccessibility) { + tryAnnounceForAccessibility(text, false); + } + } + + /** + * Show either Hours or Minutes. + */ + private void setCurrentItemShowing(int index, boolean animateCircle, boolean announce) { + mRadialTimePickerView.setCurrentItemShowing(index, animateCircle); + + if (index == HOUR_INDEX) { + if (announce) { + mDelegator.announceForAccessibility(mSelectHours); + } + } else { + if (announce) { + mDelegator.announceForAccessibility(mSelectMinutes); + } + } + + mHourView.setSelected(index == HOUR_INDEX); + mMinuteView.setSelected(index == MINUTE_INDEX); + } + + private void setAmOrPm(int amOrPm) { + updateAmPmLabelStates(amOrPm); + mRadialTimePickerView.setAmOrPm(amOrPm); + } + + /** + * For keyboard mode, processes key events. + * + * @param keyCode the pressed key. + * + * @return true if the key was successfully processed, false otherwise. + */ + private boolean processKeyUp(int keyCode) { + if (keyCode == KeyEvent.KEYCODE_DEL) { + if (mInKbMode) { + if (!mTypedTimes.isEmpty()) { + int deleted = deleteLastTypedKey(); + String deletedKeyStr; + if (deleted == getAmOrPmKeyCode(AM)) { + deletedKeyStr = mAmText; + } else if (deleted == getAmOrPmKeyCode(PM)) { + deletedKeyStr = mPmText; + } else { + deletedKeyStr = String.format("%d", getValFromKeyCode(deleted)); + } + mDelegator.announceForAccessibility( + String.format(mDeletedKeyFormat, deletedKeyStr)); + updateDisplay(true); + } + } + } else if (keyCode == KeyEvent.KEYCODE_0 || keyCode == KeyEvent.KEYCODE_1 + || keyCode == KeyEvent.KEYCODE_2 || keyCode == KeyEvent.KEYCODE_3 + || keyCode == KeyEvent.KEYCODE_4 || keyCode == KeyEvent.KEYCODE_5 + || keyCode == KeyEvent.KEYCODE_6 || keyCode == KeyEvent.KEYCODE_7 + || keyCode == KeyEvent.KEYCODE_8 || keyCode == KeyEvent.KEYCODE_9 + || (!mIs24HourView && + (keyCode == getAmOrPmKeyCode(AM) || keyCode == getAmOrPmKeyCode(PM)))) { + if (!mInKbMode) { + if (mRadialTimePickerView == null) { + // Something's wrong, because time picker should definitely not be null. + Log.e(TAG, "Unable to initiate keyboard mode, TimePicker was null."); + return true; + } + mTypedTimes.clear(); + tryStartingKbMode(keyCode); + return true; + } + // We're already in keyboard mode. + if (addKeyIfLegal(keyCode)) { + updateDisplay(false); + } + return true; + } + return false; + } + + /** + * Try to start keyboard mode with the specified key. + * + * @param keyCode The key to use as the first press. Keyboard mode will not be started if the + * key is not legal to start with. Or, pass in -1 to get into keyboard mode without a starting + * key. + */ + private void tryStartingKbMode(int keyCode) { + if (keyCode == -1 || addKeyIfLegal(keyCode)) { + mInKbMode = true; + onValidationChanged(false); + updateDisplay(false); + mRadialTimePickerView.setInputEnabled(false); + } } + + private boolean addKeyIfLegal(int keyCode) { + // If we're in 24hour mode, we'll need to check if the input is full. If in AM/PM mode, + // we'll need to see if AM/PM have been typed. + if ((mIs24HourView && mTypedTimes.size() == 4) || + (!mIs24HourView && isTypedTimeFullyLegal())) { + return false; + } + + mTypedTimes.add(keyCode); + if (!isTypedTimeLegalSoFar()) { + deleteLastTypedKey(); + return false; + } + + int val = getValFromKeyCode(keyCode); + mDelegator.announceForAccessibility(String.format("%d", val)); + // Automatically fill in 0's if AM or PM was legally entered. + if (isTypedTimeFullyLegal()) { + if (!mIs24HourView && mTypedTimes.size() <= 3) { + mTypedTimes.add(mTypedTimes.size() - 1, KeyEvent.KEYCODE_0); + mTypedTimes.add(mTypedTimes.size() - 1, KeyEvent.KEYCODE_0); + } + onValidationChanged(true); + } + + return true; + } + + /** + * Traverse the tree to see if the keys that have been typed so far are legal as is, + * or may become legal as more keys are typed (excluding backspace). + */ + private boolean isTypedTimeLegalSoFar() { + Node node = mLegalTimesTree; + for (int keyCode : mTypedTimes) { + node = node.canReach(keyCode); + if (node == null) { + return false; + } + } + return true; + } + + /** + * Check if the time that has been typed so far is completely legal, as is. + */ + private boolean isTypedTimeFullyLegal() { + if (mIs24HourView) { + // For 24-hour mode, the time is legal if the hours and minutes are each legal. Note: + // getEnteredTime() will ONLY call isTypedTimeFullyLegal() when NOT in 24hour mode. + int[] values = getEnteredTime(null); + return (values[0] >= 0 && values[1] >= 0 && values[1] < 60); + } else { + // For AM/PM mode, the time is legal if it contains an AM or PM, as those can only be + // legally added at specific times based on the tree's algorithm. + return (mTypedTimes.contains(getAmOrPmKeyCode(AM)) || + mTypedTimes.contains(getAmOrPmKeyCode(PM))); + } + } + + private int deleteLastTypedKey() { + int deleted = mTypedTimes.remove(mTypedTimes.size() - 1); + if (!isTypedTimeFullyLegal()) { + onValidationChanged(false); + } + return deleted; + } + + /** + * Get out of keyboard mode. If there is nothing in typedTimes, revert to TimePicker's time. + */ + private void finishKbMode() { + mInKbMode = false; + if (!mTypedTimes.isEmpty()) { + int values[] = getEnteredTime(null); + mRadialTimePickerView.setCurrentHour(values[0]); + mRadialTimePickerView.setCurrentMinute(values[1]); + if (!mIs24HourView) { + mRadialTimePickerView.setAmOrPm(values[2]); + } + mTypedTimes.clear(); + } + updateDisplay(false); + mRadialTimePickerView.setInputEnabled(true); + } + + /** + * Update the hours, minutes, and AM/PM displays with the typed times. If the typedTimes is + * empty, either show an empty display (filled with the placeholder text), or update from the + * timepicker's values. + * + * @param allowEmptyDisplay if true, then if the typedTimes is empty, use the placeholder text. + * Otherwise, revert to the timepicker's values. + */ + private void updateDisplay(boolean allowEmptyDisplay) { + if (!allowEmptyDisplay && mTypedTimes.isEmpty()) { + int hour = mRadialTimePickerView.getCurrentHour(); + int minute = mRadialTimePickerView.getCurrentMinute(); + updateHeaderHour(hour, false); + updateHeaderMinute(minute, false); + if (!mIs24HourView) { + updateAmPmLabelStates(hour < 12 ? AM : PM); + } + setCurrentItemShowing(mRadialTimePickerView.getCurrentItemShowing(), true, true); + onValidationChanged(true); + } else { + boolean[] enteredZeros = {false, false}; + int[] values = getEnteredTime(enteredZeros); + String hourFormat = enteredZeros[0] ? "%02d" : "%2d"; + String minuteFormat = (enteredZeros[1]) ? "%02d" : "%2d"; + String hourStr = (values[0] == -1) ? mDoublePlaceholderText : + String.format(hourFormat, values[0]).replace(' ', mPlaceholderText); + String minuteStr = (values[1] == -1) ? mDoublePlaceholderText : + String.format(minuteFormat, values[1]).replace(' ', mPlaceholderText); + mHourView.setText(hourStr); + mHourView.setSelected(false); + mMinuteView.setText(minuteStr); + mMinuteView.setSelected(false); + if (!mIs24HourView) { + updateAmPmLabelStates(values[2]); + } + } + } + + private int getValFromKeyCode(int keyCode) { + switch (keyCode) { + case KeyEvent.KEYCODE_0: + return 0; + case KeyEvent.KEYCODE_1: + return 1; + case KeyEvent.KEYCODE_2: + return 2; + case KeyEvent.KEYCODE_3: + return 3; + case KeyEvent.KEYCODE_4: + return 4; + case KeyEvent.KEYCODE_5: + return 5; + case KeyEvent.KEYCODE_6: + return 6; + case KeyEvent.KEYCODE_7: + return 7; + case KeyEvent.KEYCODE_8: + return 8; + case KeyEvent.KEYCODE_9: + return 9; + default: + return -1; + } + } + + /** + * Get the currently-entered time, as integer values of the hours and minutes typed. + * + * @param enteredZeros A size-2 boolean array, which the caller should initialize, and which + * may then be used for the caller to know whether zeros had been explicitly entered as either + * hours of minutes. This is helpful for deciding whether to show the dashes, or actual 0's. + * + * @return A size-3 int array. The first value will be the hours, the second value will be the + * minutes, and the third will be either AM or PM. + */ + private int[] getEnteredTime(boolean[] enteredZeros) { + int amOrPm = -1; + int startIndex = 1; + if (!mIs24HourView && isTypedTimeFullyLegal()) { + int keyCode = mTypedTimes.get(mTypedTimes.size() - 1); + if (keyCode == getAmOrPmKeyCode(AM)) { + amOrPm = AM; + } else if (keyCode == getAmOrPmKeyCode(PM)){ + amOrPm = PM; + } + startIndex = 2; + } + int minute = -1; + int hour = -1; + for (int i = startIndex; i <= mTypedTimes.size(); i++) { + int val = getValFromKeyCode(mTypedTimes.get(mTypedTimes.size() - i)); + if (i == startIndex) { + minute = val; + } else if (i == startIndex+1) { + minute += 10 * val; + if (enteredZeros != null && val == 0) { + enteredZeros[1] = true; + } + } else if (i == startIndex+2) { + hour = val; + } else if (i == startIndex+3) { + hour += 10 * val; + if (enteredZeros != null && val == 0) { + enteredZeros[0] = true; + } + } + } + + return new int[] { hour, minute, amOrPm }; + } + + /** + * Get the keycode value for AM and PM in the current language. + */ + private int getAmOrPmKeyCode(int amOrPm) { + // Cache the codes. + if (mAmKeyCode == -1 || mPmKeyCode == -1) { + // Find the first character in the AM/PM text that is unique. + KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); + char amChar; + char pmChar; + for (int i = 0; i < Math.max(mAmText.length(), mPmText.length()); i++) { + amChar = mAmText.toLowerCase(mCurrentLocale).charAt(i); + pmChar = mPmText.toLowerCase(mCurrentLocale).charAt(i); + if (amChar != pmChar) { + KeyEvent[] events = kcm.getEvents(new char[]{amChar, pmChar}); + // There should be 4 events: a down and up for both AM and PM. + if (events != null && events.length == 4) { + mAmKeyCode = events[0].getKeyCode(); + mPmKeyCode = events[2].getKeyCode(); + } else { + Log.e(TAG, "Unable to find keycodes for AM and PM."); + } + break; + } + } + } + if (amOrPm == AM) { + return mAmKeyCode; + } else if (amOrPm == PM) { + return mPmKeyCode; + } + + return -1; + } + + /** + * Create a tree for deciding what keys can legally be typed. + */ + private void generateLegalTimesTree() { + // Create a quick cache of numbers to their keycodes. + final int k0 = KeyEvent.KEYCODE_0; + final int k1 = KeyEvent.KEYCODE_1; + final int k2 = KeyEvent.KEYCODE_2; + final int k3 = KeyEvent.KEYCODE_3; + final int k4 = KeyEvent.KEYCODE_4; + final int k5 = KeyEvent.KEYCODE_5; + final int k6 = KeyEvent.KEYCODE_6; + final int k7 = KeyEvent.KEYCODE_7; + final int k8 = KeyEvent.KEYCODE_8; + final int k9 = KeyEvent.KEYCODE_9; + + // The root of the tree doesn't contain any numbers. + mLegalTimesTree = new Node(); + if (mIs24HourView) { + // We'll be re-using these nodes, so we'll save them. + Node minuteFirstDigit = new Node(k0, k1, k2, k3, k4, k5); + Node minuteSecondDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9); + // The first digit must be followed by the second digit. + minuteFirstDigit.addChild(minuteSecondDigit); + + // The first digit may be 0-1. + Node firstDigit = new Node(k0, k1); + mLegalTimesTree.addChild(firstDigit); + + // When the first digit is 0-1, the second digit may be 0-5. + Node secondDigit = new Node(k0, k1, k2, k3, k4, k5); + firstDigit.addChild(secondDigit); + // We may now be followed by the first minute digit. E.g. 00:09, 15:58. + secondDigit.addChild(minuteFirstDigit); + + // When the first digit is 0-1, and the second digit is 0-5, the third digit may be 6-9. + Node thirdDigit = new Node(k6, k7, k8, k9); + // The time must now be finished. E.g. 0:55, 1:08. + secondDigit.addChild(thirdDigit); + + // When the first digit is 0-1, the second digit may be 6-9. + secondDigit = new Node(k6, k7, k8, k9); + firstDigit.addChild(secondDigit); + // We must now be followed by the first minute digit. E.g. 06:50, 18:20. + secondDigit.addChild(minuteFirstDigit); + + // The first digit may be 2. + firstDigit = new Node(k2); + mLegalTimesTree.addChild(firstDigit); + + // When the first digit is 2, the second digit may be 0-3. + secondDigit = new Node(k0, k1, k2, k3); + firstDigit.addChild(secondDigit); + // We must now be followed by the first minute digit. E.g. 20:50, 23:09. + secondDigit.addChild(minuteFirstDigit); + + // When the first digit is 2, the second digit may be 4-5. + secondDigit = new Node(k4, k5); + firstDigit.addChild(secondDigit); + // We must now be followd by the last minute digit. E.g. 2:40, 2:53. + secondDigit.addChild(minuteSecondDigit); + + // The first digit may be 3-9. + firstDigit = new Node(k3, k4, k5, k6, k7, k8, k9); + mLegalTimesTree.addChild(firstDigit); + // We must now be followed by the first minute digit. E.g. 3:57, 8:12. + firstDigit.addChild(minuteFirstDigit); + } else { + // We'll need to use the AM/PM node a lot. + // Set up AM and PM to respond to "a" and "p". + Node ampm = new Node(getAmOrPmKeyCode(AM), getAmOrPmKeyCode(PM)); + + // The first hour digit may be 1. + Node firstDigit = new Node(k1); + mLegalTimesTree.addChild(firstDigit); + // We'll allow quick input of on-the-hour times. E.g. 1pm. + firstDigit.addChild(ampm); + + // When the first digit is 1, the second digit may be 0-2. + Node secondDigit = new Node(k0, k1, k2); + firstDigit.addChild(secondDigit); + // Also for quick input of on-the-hour times. E.g. 10pm, 12am. + secondDigit.addChild(ampm); + + // When the first digit is 1, and the second digit is 0-2, the third digit may be 0-5. + Node thirdDigit = new Node(k0, k1, k2, k3, k4, k5); + secondDigit.addChild(thirdDigit); + // The time may be finished now. E.g. 1:02pm, 1:25am. + thirdDigit.addChild(ampm); + + // When the first digit is 1, the second digit is 0-2, and the third digit is 0-5, + // the fourth digit may be 0-9. + Node fourthDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9); + thirdDigit.addChild(fourthDigit); + // The time must be finished now. E.g. 10:49am, 12:40pm. + fourthDigit.addChild(ampm); + + // When the first digit is 1, and the second digit is 0-2, the third digit may be 6-9. + thirdDigit = new Node(k6, k7, k8, k9); + secondDigit.addChild(thirdDigit); + // The time must be finished now. E.g. 1:08am, 1:26pm. + thirdDigit.addChild(ampm); + + // When the first digit is 1, the second digit may be 3-5. + secondDigit = new Node(k3, k4, k5); + firstDigit.addChild(secondDigit); + + // When the first digit is 1, and the second digit is 3-5, the third digit may be 0-9. + thirdDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9); + secondDigit.addChild(thirdDigit); + // The time must be finished now. E.g. 1:39am, 1:50pm. + thirdDigit.addChild(ampm); + + // The hour digit may be 2-9. + firstDigit = new Node(k2, k3, k4, k5, k6, k7, k8, k9); + mLegalTimesTree.addChild(firstDigit); + // We'll allow quick input of on-the-hour-times. E.g. 2am, 5pm. + firstDigit.addChild(ampm); + + // When the first digit is 2-9, the second digit may be 0-5. + secondDigit = new Node(k0, k1, k2, k3, k4, k5); + firstDigit.addChild(secondDigit); + + // When the first digit is 2-9, and the second digit is 0-5, the third digit may be 0-9. + thirdDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9); + secondDigit.addChild(thirdDigit); + // The time must be finished now. E.g. 2:57am, 9:30pm. + thirdDigit.addChild(ampm); + } + } + + /** + * Simple node class to be used for traversal to check for legal times. + * mLegalKeys represents the keys that can be typed to get to the node. + * mChildren are the children that can be reached from this node. + */ + private class Node { + private int[] mLegalKeys; + private ArrayList<Node> mChildren; + + public Node(int... legalKeys) { + mLegalKeys = legalKeys; + mChildren = new ArrayList<Node>(); + } + + public void addChild(Node child) { + mChildren.add(child); + } + + public boolean containsKey(int key) { + for (int i = 0; i < mLegalKeys.length; i++) { + if (mLegalKeys[i] == key) { + return true; + } + } + return false; + } + + public Node canReach(int key) { + if (mChildren == null) { + return null; + } + for (Node child : mChildren) { + if (child.containsKey(key)) { + return child; + } + } + return null; + } + } + + private final View.OnClickListener mClickListener = new View.OnClickListener() { + @Override + public void onClick(View v) { + + final int amOrPm; + switch (v.getId()) { + case R.id.am_label: + setAmOrPm(AM); + break; + case R.id.pm_label: + setAmOrPm(PM); + break; + case R.id.hours: + setCurrentItemShowing(HOUR_INDEX, true, true); + break; + case R.id.minutes: + setCurrentItemShowing(MINUTE_INDEX, true, true); + break; + default: + // Failed to handle this click, don't vibrate. + return; + } + + tryVibrate(); + } + }; + + private final View.OnKeyListener mKeyListener = new View.OnKeyListener() { + @Override + public boolean onKey(View v, int keyCode, KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_UP) { + return processKeyUp(keyCode); + } + return false; + } + }; + + private final View.OnFocusChangeListener mFocusListener = new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View v, boolean hasFocus) { + if (!hasFocus && mInKbMode && isTypedTimeFullyLegal()) { + finishKbMode(); + + if (mOnTimeChangedListener != null) { + mOnTimeChangedListener.onTimeChanged(mDelegator, + mRadialTimePickerView.getCurrentHour(), + mRadialTimePickerView.getCurrentMinute()); + } + } + } + }; } diff --git a/core/java/android/widget/TimePickerSpinnerDelegate.java b/core/java/android/widget/TimePickerSpinnerDelegate.java index e4342b1e00e8..e162f4ab67e8 100644 --- a/core/java/android/widget/TimePickerSpinnerDelegate.java +++ b/core/java/android/widget/TimePickerSpinnerDelegate.java @@ -17,372 +17,365 @@ package android.widget; import android.content.Context; -import android.content.res.ColorStateList; import android.content.res.Configuration; -import android.content.res.Resources; import android.content.res.TypedArray; import android.os.Parcel; import android.os.Parcelable; -import android.text.TextUtils; import android.text.format.DateFormat; import android.text.format.DateUtils; import android.util.AttributeSet; -import android.util.Log; -import android.util.TypedValue; -import android.view.HapticFeedbackConstants; -import android.view.KeyCharacterMap; -import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityNodeInfo; - +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; import com.android.internal.R; -import java.util.ArrayList; +import java.text.DateFormatSymbols; import java.util.Calendar; import java.util.Locale; -/** - * A delegate implementing the radial clock-based TimePicker. - */ -class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate implements - RadialTimePickerView.OnValueSelectedListener { - - private static final String TAG = "TimePickerDelegate"; - - // Index used by RadialPickerLayout - private static final int HOUR_INDEX = 0; - private static final int MINUTE_INDEX = 1; - - // NOT a real index for the purpose of what's showing. - private static final int AMPM_INDEX = 2; +import libcore.icu.LocaleData; - // Also NOT a real index, just used for keyboard mode. - private static final int ENABLE_PICKER_INDEX = 3; - - static final int AM = 0; - static final int PM = 1; +import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_AUTO; +import static android.view.View.IMPORTANT_FOR_ACCESSIBILITY_YES; +/** + * A delegate implementing the basic spinner-based TimePicker. + */ +class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate { private static final boolean DEFAULT_ENABLED_STATE = true; - private boolean mIsEnabled = DEFAULT_ENABLED_STATE; - private static final int HOURS_IN_HALF_DAY = 12; - private final View mHeaderView; - private final TextView mHourView; - private final TextView mMinuteView; - private final View mAmPmLayout; - private final CheckedTextView mAmLabel; - private final CheckedTextView mPmLabel; - private final RadialTimePickerView mRadialTimePickerView; - private final TextView mSeparatorView; - - private final String mAmText; - private final String mPmText; + // state + private boolean mIs24HourView; + private boolean mIsAm; - private final float mDisabledAlpha; + // ui components + private final NumberPicker mHourSpinner; + private final NumberPicker mMinuteSpinner; + private final NumberPicker mAmPmSpinner; + private final EditText mHourSpinnerInput; + private final EditText mMinuteSpinnerInput; + private final EditText mAmPmSpinnerInput; + private final TextView mDivider; - private boolean mAllowAutoAdvance; - private int mInitialHourOfDay; - private int mInitialMinute; - private boolean mIs24HourView; + // Note that the legacy implementation of the TimePicker is + // using a button for toggling between AM/PM while the new + // version uses a NumberPicker spinner. Therefore the code + // accommodates these two cases to be backwards compatible. + private final Button mAmPmButton; - // For hardware IME input. - private char mPlaceholderText; - private String mDoublePlaceholderText; - private String mDeletedKeyFormat; - private boolean mInKbMode; - private ArrayList<Integer> mTypedTimes = new ArrayList<Integer>(); - private Node mLegalTimesTree; - private int mAmKeyCode; - private int mPmKeyCode; - - // Accessibility strings. - private String mHourPickerDescription; - private String mSelectHours; - private String mMinutePickerDescription; - private String mSelectMinutes; + private final String[] mAmPmStrings; + private boolean mIsEnabled = DEFAULT_ENABLED_STATE; private Calendar mTempCalendar; + private boolean mHourWithTwoDigit; + private char mHourFormat; public TimePickerSpinnerDelegate(TimePicker delegator, Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(delegator, context); // process style attributes - final TypedArray a = mContext.obtainStyledAttributes(attrs, - R.styleable.TimePicker, defStyleAttr, defStyleRes); - final LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( - Context.LAYOUT_INFLATER_SERVICE); - final Resources res = mContext.getResources(); - - mHourPickerDescription = res.getString(R.string.hour_picker_description); - mSelectHours = res.getString(R.string.select_hours); - mMinutePickerDescription = res.getString(R.string.minute_picker_description); - mSelectMinutes = res.getString(R.string.select_minutes); - - String[] amPmStrings = TimePickerClockDelegate.getAmPmStrings(context); - mAmText = amPmStrings[0]; - mPmText = amPmStrings[1]; - - final int layoutResourceId = a.getResourceId(R.styleable.TimePicker_internalLayout, - R.layout.time_picker_holo); - final View mainView = inflater.inflate(layoutResourceId, delegator); - - mHeaderView = mainView.findViewById(R.id.time_header); - mHeaderView.setBackground(a.getDrawable(R.styleable.TimePicker_headerBackground)); - - // Set up hour/minute labels. - mHourView = (TextView) mHeaderView.findViewById(R.id.hours); - mHourView.setOnClickListener(mClickListener); - mSeparatorView = (TextView) mHeaderView.findViewById(R.id.separator); - mMinuteView = (TextView) mHeaderView.findViewById(R.id.minutes); - mMinuteView.setOnClickListener(mClickListener); - - final int headerTimeTextAppearance = a.getResourceId( - R.styleable.TimePicker_headerTimeTextAppearance, 0); - if (headerTimeTextAppearance != 0) { - mHourView.setTextAppearance(context, headerTimeTextAppearance); - mSeparatorView.setTextAppearance(context, headerTimeTextAppearance); - mMinuteView.setTextAppearance(context, headerTimeTextAppearance); - } - - // TODO: This can be removed once we support themed color state lists. - final int headerSelectedTextColor = a.getColor( - R.styleable.TimePicker_headerSelectedTextColor, - res.getColor(R.color.timepicker_default_selector_color_material)); - mHourView.setTextColor(ColorStateList.addFirstIfMissing(mHourView.getTextColors(), - R.attr.state_selected, headerSelectedTextColor)); - mMinuteView.setTextColor(ColorStateList.addFirstIfMissing(mMinuteView.getTextColors(), - R.attr.state_selected, headerSelectedTextColor)); - - // Set up AM/PM labels. - mAmPmLayout = mHeaderView.findViewById(R.id.ampm_layout); - mAmLabel = (CheckedTextView) mAmPmLayout.findViewById(R.id.am_label); - mAmLabel.setText(amPmStrings[0]); - mAmLabel.setOnClickListener(mClickListener); - mPmLabel = (CheckedTextView) mAmPmLayout.findViewById(R.id.pm_label); - mPmLabel.setText(amPmStrings[1]); - mPmLabel.setOnClickListener(mClickListener); - - final int headerAmPmTextAppearance = a.getResourceId( - R.styleable.TimePicker_headerAmPmTextAppearance, 0); - if (headerAmPmTextAppearance != 0) { - mAmLabel.setTextAppearance(context, headerAmPmTextAppearance); - mPmLabel.setTextAppearance(context, headerAmPmTextAppearance); - } - + final TypedArray a = mContext.obtainStyledAttributes( + attrs, R.styleable.TimePicker, defStyleAttr, defStyleRes); + final int layoutResourceId = a.getResourceId( + R.styleable.TimePicker_legacyLayout, R.layout.time_picker_legacy); a.recycle(); - // Pull disabled alpha from theme. - final TypedValue outValue = new TypedValue(); - context.getTheme().resolveAttribute(android.R.attr.disabledAlpha, outValue, true); - mDisabledAlpha = outValue.getFloat(); + final LayoutInflater inflater = LayoutInflater.from(mContext); + inflater.inflate(layoutResourceId, mDelegator, true); + + // hour + mHourSpinner = (NumberPicker) delegator.findViewById(R.id.hour); + mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { + public void onValueChange(NumberPicker spinner, int oldVal, int newVal) { + updateInputState(); + if (!is24HourView()) { + if ((oldVal == HOURS_IN_HALF_DAY - 1 && newVal == HOURS_IN_HALF_DAY) || + (oldVal == HOURS_IN_HALF_DAY && newVal == HOURS_IN_HALF_DAY - 1)) { + mIsAm = !mIsAm; + updateAmPmControl(); + } + } + onTimeChanged(); + } + }); + mHourSpinnerInput = (EditText) mHourSpinner.findViewById(R.id.numberpicker_input); + mHourSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT); + + // divider (only for the new widget style) + mDivider = (TextView) mDelegator.findViewById(R.id.divider); + if (mDivider != null) { + setDividerText(); + } + + // minute + mMinuteSpinner = (NumberPicker) mDelegator.findViewById(R.id.minute); + mMinuteSpinner.setMinValue(0); + mMinuteSpinner.setMaxValue(59); + mMinuteSpinner.setOnLongPressUpdateInterval(100); + mMinuteSpinner.setFormatter(NumberPicker.getTwoDigitFormatter()); + mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { + public void onValueChange(NumberPicker spinner, int oldVal, int newVal) { + updateInputState(); + int minValue = mMinuteSpinner.getMinValue(); + int maxValue = mMinuteSpinner.getMaxValue(); + if (oldVal == maxValue && newVal == minValue) { + int newHour = mHourSpinner.getValue() + 1; + if (!is24HourView() && newHour == HOURS_IN_HALF_DAY) { + mIsAm = !mIsAm; + updateAmPmControl(); + } + mHourSpinner.setValue(newHour); + } else if (oldVal == minValue && newVal == maxValue) { + int newHour = mHourSpinner.getValue() - 1; + if (!is24HourView() && newHour == HOURS_IN_HALF_DAY - 1) { + mIsAm = !mIsAm; + updateAmPmControl(); + } + mHourSpinner.setValue(newHour); + } + onTimeChanged(); + } + }); + mMinuteSpinnerInput = (EditText) mMinuteSpinner.findViewById(R.id.numberpicker_input); + mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT); + + // Get the localized am/pm strings and use them in the spinner. + mAmPmStrings = getAmPmStrings(context); + + // am/pm + final View amPmView = mDelegator.findViewById(R.id.amPm); + if (amPmView instanceof Button) { + mAmPmSpinner = null; + mAmPmSpinnerInput = null; + mAmPmButton = (Button) amPmView; + mAmPmButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View button) { + button.requestFocus(); + mIsAm = !mIsAm; + updateAmPmControl(); + onTimeChanged(); + } + }); + } else { + mAmPmButton = null; + mAmPmSpinner = (NumberPicker) amPmView; + mAmPmSpinner.setMinValue(0); + mAmPmSpinner.setMaxValue(1); + mAmPmSpinner.setDisplayedValues(mAmPmStrings); + mAmPmSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() { + public void onValueChange(NumberPicker picker, int oldVal, int newVal) { + updateInputState(); + picker.requestFocus(); + mIsAm = !mIsAm; + updateAmPmControl(); + onTimeChanged(); + } + }); + mAmPmSpinnerInput = (EditText) mAmPmSpinner.findViewById(R.id.numberpicker_input); + mAmPmSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE); + } + + if (isAmPmAtStart()) { + // Move the am/pm view to the beginning + ViewGroup amPmParent = (ViewGroup) delegator.findViewById(R.id.timePickerLayout); + amPmParent.removeView(amPmView); + amPmParent.addView(amPmView, 0); + // Swap layout margins if needed. They may be not symmetrical (Old Standard Theme + // for example and not for Holo Theme) + ViewGroup.MarginLayoutParams lp = + (ViewGroup.MarginLayoutParams) amPmView.getLayoutParams(); + final int startMargin = lp.getMarginStart(); + final int endMargin = lp.getMarginEnd(); + if (startMargin != endMargin) { + lp.setMarginStart(endMargin); + lp.setMarginEnd(startMargin); + } + } - mRadialTimePickerView = (RadialTimePickerView) mainView.findViewById( - R.id.radial_picker); + getHourFormatData(); - setupListeners(); + // update controls to initial state + updateHourControl(); + updateMinuteControl(); + updateAmPmControl(); - mAllowAutoAdvance = true; + // set to current time + setCurrentHour(mTempCalendar.get(Calendar.HOUR_OF_DAY)); + setCurrentMinute(mTempCalendar.get(Calendar.MINUTE)); - // Set up for keyboard mode. - mDoublePlaceholderText = res.getString(R.string.time_placeholder); - mDeletedKeyFormat = res.getString(R.string.deleted_key); - mPlaceholderText = mDoublePlaceholderText.charAt(0); - mAmKeyCode = mPmKeyCode = -1; - generateLegalTimesTree(); + if (!isEnabled()) { + setEnabled(false); + } - // Initialize with current time - final Calendar calendar = Calendar.getInstance(mCurrentLocale); - final int currentHour = calendar.get(Calendar.HOUR_OF_DAY); - final int currentMinute = calendar.get(Calendar.MINUTE); - initialize(currentHour, currentMinute, false /* 12h */, HOUR_INDEX); - } + // set the content descriptions + setContentDescriptions(); - private void initialize(int hourOfDay, int minute, boolean is24HourView, int index) { - mInitialHourOfDay = hourOfDay; - mInitialMinute = minute; - mIs24HourView = is24HourView; - mInKbMode = false; - updateUI(index); + // If not explicitly specified this view is important for accessibility. + if (mDelegator.getImportantForAccessibility() == IMPORTANT_FOR_ACCESSIBILITY_AUTO) { + mDelegator.setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); + } } - private void setupListeners() { - mHeaderView.setOnKeyListener(mKeyListener); - mHeaderView.setOnFocusChangeListener(mFocusListener); - mHeaderView.setFocusable(true); - - mRadialTimePickerView.setOnValueSelectedListener(this); + private void getHourFormatData() { + final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, + (mIs24HourView) ? "Hm" : "hm"); + final int lengthPattern = bestDateTimePattern.length(); + mHourWithTwoDigit = false; + char hourFormat = '\0'; + // Check if the returned pattern is single or double 'H', 'h', 'K', 'k'. We also save + // the hour format that we found. + for (int i = 0; i < lengthPattern; i++) { + final char c = bestDateTimePattern.charAt(i); + if (c == 'H' || c == 'h' || c == 'K' || c == 'k') { + mHourFormat = c; + if (i + 1 < lengthPattern && c == bestDateTimePattern.charAt(i + 1)) { + mHourWithTwoDigit = true; + } + break; + } + } } - private void updateUI(int index) { - // Update RadialPicker values - updateRadialPicker(index); - // Enable or disable the AM/PM view. - updateHeaderAmPm(); - // Update Hour and Minutes - updateHeaderHour(mInitialHourOfDay, true); - // Update time separator - updateHeaderSeparator(); - // Update Minutes - updateHeaderMinute(mInitialMinute); - // Invalidate everything - mDelegator.invalidate(); - } + private boolean isAmPmAtStart() { + final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, + "hm" /* skeleton */); - private void updateRadialPicker(int index) { - mRadialTimePickerView.initialize(mInitialHourOfDay, mInitialMinute, mIs24HourView); - setCurrentItemShowing(index, false, true); + return bestDateTimePattern.startsWith("a"); } - private int computeMaxWidthOfNumbers(int max) { - TextView tempView = new TextView(mContext); - tempView.setTextAppearance(mContext, R.style.TextAppearance_Material_TimePicker_TimeLabel); - ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, - ViewGroup.LayoutParams.WRAP_CONTENT); - tempView.setLayoutParams(lp); - int maxWidth = 0; - for (int minutes = 0; minutes < max; minutes++) { - final String text = String.format("%02d", minutes); - tempView.setText(text); - tempView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED); - maxWidth = Math.max(maxWidth, tempView.getMeasuredWidth()); + /** + * The time separator is defined in the Unicode CLDR and cannot be supposed to be ":". + * + * See http://unicode.org/cldr/trac/browser/trunk/common/main + * + * We pass the correct "skeleton" depending on 12 or 24 hours view and then extract the + * separator as the character which is just after the hour marker in the returned pattern. + */ + private void setDividerText() { + final String skeleton = (mIs24HourView) ? "Hm" : "hm"; + final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, + skeleton); + final String separatorText; + int hourIndex = bestDateTimePattern.lastIndexOf('H'); + if (hourIndex == -1) { + hourIndex = bestDateTimePattern.lastIndexOf('h'); } - return maxWidth; - } - - private void updateHeaderAmPm() { - if (mIs24HourView) { - mAmPmLayout.setVisibility(View.GONE); + if (hourIndex == -1) { + // Default case + separatorText = ":"; } else { - final String bestDateTimePattern = DateFormat.getBestDateTimePattern( - mCurrentLocale, "hm"); - boolean amPmOnLeft = bestDateTimePattern.startsWith("a"); - if (TextUtils.getLayoutDirectionFromLocale(mCurrentLocale) == - View.LAYOUT_DIRECTION_RTL) { - amPmOnLeft = !amPmOnLeft; - } - - final ViewGroup.MarginLayoutParams params = - (ViewGroup.MarginLayoutParams) mAmPmLayout.getLayoutParams(); - - if (amPmOnLeft) { - params.leftMargin = 0; - params.rightMargin = computeMaxWidthOfNumbers(12 /* for hours */); + int minuteIndex = bestDateTimePattern.indexOf('m', hourIndex + 1); + if (minuteIndex == -1) { + separatorText = Character.toString(bestDateTimePattern.charAt(hourIndex + 1)); } else { - params.leftMargin = computeMaxWidthOfNumbers(60 /* for minutes */); - params.rightMargin = 0; + separatorText = bestDateTimePattern.substring(hourIndex + 1, minuteIndex); } - - mAmPmLayout.setLayoutParams(params); - mAmPmLayout.setVisibility(View.VISIBLE); - - updateAmPmLabelStates(mInitialHourOfDay < 12 ? AM : PM); } + mDivider.setText(separatorText); } - /** - * Set the current hour. - */ @Override public void setCurrentHour(Integer currentHour) { - if (mInitialHourOfDay == currentHour) { + setCurrentHour(currentHour, true); + } + + private void setCurrentHour(Integer currentHour, boolean notifyTimeChanged) { + // why was Integer used in the first place? + if (currentHour == null || currentHour == getCurrentHour()) { return; } - mInitialHourOfDay = currentHour; - updateHeaderHour(currentHour, true /* accessibility announce */); - updateHeaderAmPm(); - mRadialTimePickerView.setCurrentHour(currentHour); - mRadialTimePickerView.setAmOrPm(mInitialHourOfDay < 12 ? AM : PM); - mDelegator.invalidate(); - onTimeChanged(); + if (!is24HourView()) { + // convert [0,23] ordinal to wall clock display + if (currentHour >= HOURS_IN_HALF_DAY) { + mIsAm = false; + if (currentHour > HOURS_IN_HALF_DAY) { + currentHour = currentHour - HOURS_IN_HALF_DAY; + } + } else { + mIsAm = true; + if (currentHour == 0) { + currentHour = HOURS_IN_HALF_DAY; + } + } + updateAmPmControl(); + } + mHourSpinner.setValue(currentHour); + if (notifyTimeChanged) { + onTimeChanged(); + } } - /** - * @return The current hour in the range (0-23). - */ @Override public Integer getCurrentHour() { - int currentHour = mRadialTimePickerView.getCurrentHour(); - if (mIs24HourView) { + int currentHour = mHourSpinner.getValue(); + if (is24HourView()) { return currentHour; + } else if (mIsAm) { + return currentHour % HOURS_IN_HALF_DAY; } else { - switch(mRadialTimePickerView.getAmOrPm()) { - case PM: - return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY; - case AM: - default: - return currentHour % HOURS_IN_HALF_DAY; - } + return (currentHour % HOURS_IN_HALF_DAY) + HOURS_IN_HALF_DAY; } } - /** - * Set the current minute (0-59). - */ @Override public void setCurrentMinute(Integer currentMinute) { - if (mInitialMinute == currentMinute) { + if (currentMinute == getCurrentMinute()) { return; } - mInitialMinute = currentMinute; - updateHeaderMinute(currentMinute); - mRadialTimePickerView.setCurrentMinute(currentMinute); - mDelegator.invalidate(); + mMinuteSpinner.setValue(currentMinute); onTimeChanged(); } - /** - * @return The current minute. - */ @Override public Integer getCurrentMinute() { - return mRadialTimePickerView.getCurrentMinute(); + return mMinuteSpinner.getValue(); } - /** - * Set whether in 24 hour or AM/PM mode. - * - * @param is24HourView True = 24 hour mode. False = AM/PM. - */ @Override public void setIs24HourView(Boolean is24HourView) { - if (is24HourView == mIs24HourView) { + if (mIs24HourView == is24HourView) { return; } + // cache the current hour since spinner range changes and BEFORE changing mIs24HourView!! + int currentHour = getCurrentHour(); + // Order is important here. mIs24HourView = is24HourView; - generateLegalTimesTree(); - int hour = mRadialTimePickerView.getCurrentHour(); - mInitialHourOfDay = hour; - updateHeaderHour(hour, false /* no accessibility announce */); - updateHeaderAmPm(); - updateRadialPicker(mRadialTimePickerView.getCurrentItemShowing()); - mDelegator.invalidate(); + getHourFormatData(); + updateHourControl(); + // set value after spinner range is updated + setCurrentHour(currentHour, false); + updateMinuteControl(); + updateAmPmControl(); } - /** - * @return true if this is in 24 hour view else false. - */ @Override public boolean is24HourView() { return mIs24HourView; } @Override - public void setOnTimeChangedListener(TimePicker.OnTimeChangedListener callback) { - mOnTimeChangedListener = callback; + public void setOnTimeChangedListener(TimePicker.OnTimeChangedListener onTimeChangedListener) { + mOnTimeChangedListener = onTimeChangedListener; } @Override public void setEnabled(boolean enabled) { - mHourView.setEnabled(enabled); - mMinuteView.setEnabled(enabled); - mAmLabel.setEnabled(enabled); - mPmLabel.setEnabled(enabled); - mRadialTimePickerView.setEnabled(enabled); + mMinuteSpinner.setEnabled(enabled); + if (mDivider != null) { + mDivider.setEnabled(enabled); + } + mHourSpinner.setEnabled(enabled); + if (mAmPmSpinner != null) { + mAmPmSpinner.setEnabled(enabled); + } else { + mAmPmButton.setEnabled(enabled); + } mIsEnabled = enabled; } @@ -393,38 +386,24 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im @Override public int getBaseline() { - // does not support baseline alignment - return -1; + return mHourSpinner.getBaseline(); } @Override public void onConfigurationChanged(Configuration newConfig) { - updateUI(mRadialTimePickerView.getCurrentItemShowing()); + setCurrentLocale(newConfig.locale); } @Override public Parcelable onSaveInstanceState(Parcelable superState) { - return new SavedState(superState, getCurrentHour(), getCurrentMinute(), - is24HourView(), inKbMode(), getTypedTimes(), getCurrentItemShowing()); + return new SavedState(superState, getCurrentHour(), getCurrentMinute()); } @Override public void onRestoreInstanceState(Parcelable state) { SavedState ss = (SavedState) state; - setInKbMode(ss.inKbMode()); - setTypedTimes(ss.getTypesTimes()); - initialize(ss.getHour(), ss.getMinute(), ss.is24HourMode(), ss.getCurrentItemShowing()); - mRadialTimePickerView.invalidate(); - if (mInKbMode) { - tryStartingKbMode(-1); - mHourView.invalidate(); - } - } - - @Override - public void setCurrentLocale(Locale locale) { - super.setCurrentLocale(locale); - mTempCalendar = Calendar.getInstance(locale); + setCurrentHour(ss.getHour()); + setCurrentMinute(ss.getMinute()); } @Override @@ -443,9 +422,9 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im } mTempCalendar.set(Calendar.HOUR_OF_DAY, getCurrentHour()); mTempCalendar.set(Calendar.MINUTE, getCurrentMinute()); - String selectedDate = DateUtils.formatDateTime(mContext, + String selectedDateUtterance = DateUtils.formatDateTime(mContext, mTempCalendar.getTimeInMillis(), flags); - event.getText().add(selectedDate); + event.getText().add(selectedDateUtterance); } @Override @@ -458,48 +437,121 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im info.setClassName(TimePicker.class.getName()); } + private void updateInputState() { + // Make sure that if the user changes the value and the IME is active + // for one of the inputs if this widget, the IME is closed. If the user + // changed the value via the IME and there is a next input the IME will + // be shown, otherwise the user chose another means of changing the + // value and having the IME up makes no sense. + InputMethodManager inputMethodManager = InputMethodManager.peekInstance(); + if (inputMethodManager != null) { + if (inputMethodManager.isActive(mHourSpinnerInput)) { + mHourSpinnerInput.clearFocus(); + inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0); + } else if (inputMethodManager.isActive(mMinuteSpinnerInput)) { + mMinuteSpinnerInput.clearFocus(); + inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0); + } else if (inputMethodManager.isActive(mAmPmSpinnerInput)) { + mAmPmSpinnerInput.clearFocus(); + inputMethodManager.hideSoftInputFromWindow(mDelegator.getWindowToken(), 0); + } + } + } + + private void updateAmPmControl() { + if (is24HourView()) { + if (mAmPmSpinner != null) { + mAmPmSpinner.setVisibility(View.GONE); + } else { + mAmPmButton.setVisibility(View.GONE); + } + } else { + int index = mIsAm ? Calendar.AM : Calendar.PM; + if (mAmPmSpinner != null) { + mAmPmSpinner.setValue(index); + mAmPmSpinner.setVisibility(View.VISIBLE); + } else { + mAmPmButton.setText(mAmPmStrings[index]); + mAmPmButton.setVisibility(View.VISIBLE); + } + } + mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + } + /** - * Set whether in keyboard mode or not. + * Sets the current locale. * - * @param inKbMode True means in keyboard mode. + * @param locale The current locale. */ - private void setInKbMode(boolean inKbMode) { - mInKbMode = inKbMode; + @Override + public void setCurrentLocale(Locale locale) { + super.setCurrentLocale(locale); + mTempCalendar = Calendar.getInstance(locale); } - /** - * @return true if in keyboard mode - */ - private boolean inKbMode() { - return mInKbMode; + private void onTimeChanged() { + mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); + if (mOnTimeChangedListener != null) { + mOnTimeChangedListener.onTimeChanged(mDelegator, getCurrentHour(), + getCurrentMinute()); + } } - private void setTypedTimes(ArrayList<Integer> typeTimes) { - mTypedTimes = typeTimes; + private void updateHourControl() { + if (is24HourView()) { + // 'k' means 1-24 hour + if (mHourFormat == 'k') { + mHourSpinner.setMinValue(1); + mHourSpinner.setMaxValue(24); + } else { + mHourSpinner.setMinValue(0); + mHourSpinner.setMaxValue(23); + } + } else { + // 'K' means 0-11 hour + if (mHourFormat == 'K') { + mHourSpinner.setMinValue(0); + mHourSpinner.setMaxValue(11); + } else { + mHourSpinner.setMinValue(1); + mHourSpinner.setMaxValue(12); + } + } + mHourSpinner.setFormatter(mHourWithTwoDigit ? NumberPicker.getTwoDigitFormatter() : null); } - /** - * @return an array of typed times - */ - private ArrayList<Integer> getTypedTimes() { - return mTypedTimes; + private void updateMinuteControl() { + if (is24HourView()) { + mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_DONE); + } else { + mMinuteSpinnerInput.setImeOptions(EditorInfo.IME_ACTION_NEXT); + } } - /** - * @return the index of the current item showing - */ - private int getCurrentItemShowing() { - return mRadialTimePickerView.getCurrentItemShowing(); + private void setContentDescriptions() { + // Minute + trySetContentDescription(mMinuteSpinner, R.id.increment, + R.string.time_picker_increment_minute_button); + trySetContentDescription(mMinuteSpinner, R.id.decrement, + R.string.time_picker_decrement_minute_button); + // Hour + trySetContentDescription(mHourSpinner, R.id.increment, + R.string.time_picker_increment_hour_button); + trySetContentDescription(mHourSpinner, R.id.decrement, + R.string.time_picker_decrement_hour_button); + // AM/PM + if (mAmPmSpinner != null) { + trySetContentDescription(mAmPmSpinner, R.id.increment, + R.string.time_picker_increment_set_pm_button); + trySetContentDescription(mAmPmSpinner, R.id.decrement, + R.string.time_picker_decrement_set_am_button); + } } - /** - * Propagate the time change - */ - private void onTimeChanged() { - mDelegator.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED); - if (mOnTimeChangedListener != null) { - mOnTimeChangedListener.onTimeChanged(mDelegator, - getCurrentHour(), getCurrentMinute()); + private void trySetContentDescription(View root, int viewId, int contDescResId) { + View target = root.findViewById(viewId); + if (target != null) { + target.setContentDescription(mContext.getString(contDescResId)); } } @@ -507,34 +559,19 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im * Used to save / restore state of time picker */ private static class SavedState extends View.BaseSavedState { - private final int mHour; private final int mMinute; - private final boolean mIs24HourMode; - private final boolean mInKbMode; - private final ArrayList<Integer> mTypedTimes; - private final int mCurrentItemShowing; - - private SavedState(Parcelable superState, int hour, int minute, boolean is24HourMode, - boolean isKbMode, ArrayList<Integer> typedTimes, - int currentItemShowing) { + + private SavedState(Parcelable superState, int hour, int minute) { super(superState); mHour = hour; mMinute = minute; - mIs24HourMode = is24HourMode; - mInKbMode = isKbMode; - mTypedTimes = typedTimes; - mCurrentItemShowing = currentItemShowing; } private SavedState(Parcel in) { super(in); mHour = in.readInt(); mMinute = in.readInt(); - mIs24HourMode = (in.readInt() == 1); - mInKbMode = (in.readInt() == 1); - mTypedTimes = in.readArrayList(getClass().getClassLoader()); - mCurrentItemShowing = in.readInt(); } public int getHour() { @@ -545,31 +582,11 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im return mMinute; } - public boolean is24HourMode() { - return mIs24HourMode; - } - - public boolean inKbMode() { - return mInKbMode; - } - - public ArrayList<Integer> getTypesTimes() { - return mTypedTimes; - } - - public int getCurrentItemShowing() { - return mCurrentItemShowing; - } - @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); dest.writeInt(mHour); dest.writeInt(mMinute); - dest.writeInt(mIs24HourMode ? 1 : 0); - dest.writeInt(mInKbMode ? 1 : 0); - dest.writeList(mTypedTimes); - dest.writeInt(mCurrentItemShowing); } @SuppressWarnings({"unused", "hiding"}) @@ -584,697 +601,11 @@ class TimePickerSpinnerDelegate extends TimePicker.AbstractTimePickerDelegate im }; } - private void tryVibrate() { - mDelegator.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK); - } - - private void updateAmPmLabelStates(int amOrPm) { - final boolean isAm = amOrPm == AM; - mAmLabel.setChecked(isAm); - mAmLabel.setAlpha(isAm ? 1 : mDisabledAlpha); - - final boolean isPm = amOrPm == PM; - mPmLabel.setChecked(isPm); - mPmLabel.setAlpha(isPm ? 1 : mDisabledAlpha); - } - - /** - * Called by the picker for updating the header display. - */ - @Override - public void onValueSelected(int pickerIndex, int newValue, boolean autoAdvance) { - if (pickerIndex == HOUR_INDEX) { - updateHeaderHour(newValue, false); - String announcement = String.format("%d", newValue); - if (mAllowAutoAdvance && autoAdvance) { - setCurrentItemShowing(MINUTE_INDEX, true, false); - announcement += ". " + mSelectMinutes; - } else { - mRadialTimePickerView.setContentDescription( - mHourPickerDescription + ": " + newValue); - } - - mRadialTimePickerView.announceForAccessibility(announcement); - } else if (pickerIndex == MINUTE_INDEX){ - updateHeaderMinute(newValue); - mRadialTimePickerView.setContentDescription(mMinutePickerDescription + ": " + newValue); - } else if (pickerIndex == AMPM_INDEX) { - updateAmPmLabelStates(newValue); - } else if (pickerIndex == ENABLE_PICKER_INDEX) { - if (!isTypedTimeFullyLegal()) { - mTypedTimes.clear(); - } - finishKbMode(); - } - } - - private void updateHeaderHour(int value, boolean announce) { - final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, - (mIs24HourView) ? "Hm" : "hm"); - final int lengthPattern = bestDateTimePattern.length(); - boolean hourWithTwoDigit = false; - char hourFormat = '\0'; - // Check if the returned pattern is single or double 'H', 'h', 'K', 'k'. We also save - // the hour format that we found. - for (int i = 0; i < lengthPattern; i++) { - final char c = bestDateTimePattern.charAt(i); - if (c == 'H' || c == 'h' || c == 'K' || c == 'k') { - hourFormat = c; - if (i + 1 < lengthPattern && c == bestDateTimePattern.charAt(i + 1)) { - hourWithTwoDigit = true; - } - break; - } - } - final String format; - if (hourWithTwoDigit) { - format = "%02d"; - } else { - format = "%d"; - } - if (mIs24HourView) { - // 'k' means 1-24 hour - if (hourFormat == 'k' && value == 0) { - value = 24; - } - } else { - // 'K' means 0-11 hour - value = modulo12(value, hourFormat == 'K'); - } - CharSequence text = String.format(format, value); - mHourView.setText(text); - if (announce) { - mRadialTimePickerView.announceForAccessibility(text); - } - } - - private static int modulo12(int n, boolean startWithZero) { - int value = n % 12; - if (value == 0 && !startWithZero) { - value = 12; - } - return value; - } - - /** - * The time separator is defined in the Unicode CLDR and cannot be supposed to be ":". - * - * See http://unicode.org/cldr/trac/browser/trunk/common/main - * - * We pass the correct "skeleton" depending on 12 or 24 hours view and then extract the - * separator as the character which is just after the hour marker in the returned pattern. - */ - private void updateHeaderSeparator() { - final String bestDateTimePattern = DateFormat.getBestDateTimePattern(mCurrentLocale, - (mIs24HourView) ? "Hm" : "hm"); - final String separatorText; - // See http://www.unicode.org/reports/tr35/tr35-dates.html for hour formats - final char[] hourFormats = {'H', 'h', 'K', 'k'}; - int hIndex = lastIndexOfAny(bestDateTimePattern, hourFormats); - if (hIndex == -1) { - // Default case - separatorText = ":"; - } else { - separatorText = Character.toString(bestDateTimePattern.charAt(hIndex + 1)); - } - mSeparatorView.setText(separatorText); - } - - static private int lastIndexOfAny(String str, char[] any) { - final int lengthAny = any.length; - if (lengthAny > 0) { - for (int i = str.length() - 1; i >= 0; i--) { - char c = str.charAt(i); - for (int j = 0; j < lengthAny; j++) { - if (c == any[j]) { - return i; - } - } - } - } - return -1; - } - - private void updateHeaderMinute(int value) { - if (value == 60) { - value = 0; - } - CharSequence text = String.format(mCurrentLocale, "%02d", value); - mRadialTimePickerView.announceForAccessibility(text); - mMinuteView.setText(text); - } - - /** - * Show either Hours or Minutes. - */ - private void setCurrentItemShowing(int index, boolean animateCircle, boolean announce) { - mRadialTimePickerView.setCurrentItemShowing(index, animateCircle); - - if (index == HOUR_INDEX) { - int hours = mRadialTimePickerView.getCurrentHour(); - if (!mIs24HourView) { - hours = hours % 12; - } - mRadialTimePickerView.setContentDescription(mHourPickerDescription + ": " + hours); - if (announce) { - mRadialTimePickerView.announceForAccessibility(mSelectHours); - } - } else { - int minutes = mRadialTimePickerView.getCurrentMinute(); - mRadialTimePickerView.setContentDescription(mMinutePickerDescription + ": " + minutes); - if (announce) { - mRadialTimePickerView.announceForAccessibility(mSelectMinutes); - } - } - - mHourView.setSelected(index == HOUR_INDEX); - mMinuteView.setSelected(index == MINUTE_INDEX); - } - - private void setAmOrPm(int amOrPm) { - updateAmPmLabelStates(amOrPm); - mRadialTimePickerView.setAmOrPm(amOrPm); - } - - /** - * For keyboard mode, processes key events. - * - * @param keyCode the pressed key. - * - * @return true if the key was successfully processed, false otherwise. - */ - private boolean processKeyUp(int keyCode) { - if (keyCode == KeyEvent.KEYCODE_DEL) { - if (mInKbMode) { - if (!mTypedTimes.isEmpty()) { - int deleted = deleteLastTypedKey(); - String deletedKeyStr; - if (deleted == getAmOrPmKeyCode(AM)) { - deletedKeyStr = mAmText; - } else if (deleted == getAmOrPmKeyCode(PM)) { - deletedKeyStr = mPmText; - } else { - deletedKeyStr = String.format("%d", getValFromKeyCode(deleted)); - } - mRadialTimePickerView.announceForAccessibility( - String.format(mDeletedKeyFormat, deletedKeyStr)); - updateDisplay(true); - } - } - } else if (keyCode == KeyEvent.KEYCODE_0 || keyCode == KeyEvent.KEYCODE_1 - || keyCode == KeyEvent.KEYCODE_2 || keyCode == KeyEvent.KEYCODE_3 - || keyCode == KeyEvent.KEYCODE_4 || keyCode == KeyEvent.KEYCODE_5 - || keyCode == KeyEvent.KEYCODE_6 || keyCode == KeyEvent.KEYCODE_7 - || keyCode == KeyEvent.KEYCODE_8 || keyCode == KeyEvent.KEYCODE_9 - || (!mIs24HourView && - (keyCode == getAmOrPmKeyCode(AM) || keyCode == getAmOrPmKeyCode(PM)))) { - if (!mInKbMode) { - if (mRadialTimePickerView == null) { - // Something's wrong, because time picker should definitely not be null. - Log.e(TAG, "Unable to initiate keyboard mode, TimePicker was null."); - return true; - } - mTypedTimes.clear(); - tryStartingKbMode(keyCode); - return true; - } - // We're already in keyboard mode. - if (addKeyIfLegal(keyCode)) { - updateDisplay(false); - } - return true; - } - return false; - } - - /** - * Try to start keyboard mode with the specified key. - * - * @param keyCode The key to use as the first press. Keyboard mode will not be started if the - * key is not legal to start with. Or, pass in -1 to get into keyboard mode without a starting - * key. - */ - private void tryStartingKbMode(int keyCode) { - if (keyCode == -1 || addKeyIfLegal(keyCode)) { - mInKbMode = true; - onValidationChanged(false); - updateDisplay(false); - mRadialTimePickerView.setInputEnabled(false); - } - } - - private boolean addKeyIfLegal(int keyCode) { - // If we're in 24hour mode, we'll need to check if the input is full. If in AM/PM mode, - // we'll need to see if AM/PM have been typed. - if ((mIs24HourView && mTypedTimes.size() == 4) || - (!mIs24HourView && isTypedTimeFullyLegal())) { - return false; - } - - mTypedTimes.add(keyCode); - if (!isTypedTimeLegalSoFar()) { - deleteLastTypedKey(); - return false; - } - - int val = getValFromKeyCode(keyCode); - mRadialTimePickerView.announceForAccessibility(String.format("%d", val)); - // Automatically fill in 0's if AM or PM was legally entered. - if (isTypedTimeFullyLegal()) { - if (!mIs24HourView && mTypedTimes.size() <= 3) { - mTypedTimes.add(mTypedTimes.size() - 1, KeyEvent.KEYCODE_0); - mTypedTimes.add(mTypedTimes.size() - 1, KeyEvent.KEYCODE_0); - } - onValidationChanged(true); - } - - return true; - } - - /** - * Traverse the tree to see if the keys that have been typed so far are legal as is, - * or may become legal as more keys are typed (excluding backspace). - */ - private boolean isTypedTimeLegalSoFar() { - Node node = mLegalTimesTree; - for (int keyCode : mTypedTimes) { - node = node.canReach(keyCode); - if (node == null) { - return false; - } - } - return true; - } - - /** - * Check if the time that has been typed so far is completely legal, as is. - */ - private boolean isTypedTimeFullyLegal() { - if (mIs24HourView) { - // For 24-hour mode, the time is legal if the hours and minutes are each legal. Note: - // getEnteredTime() will ONLY call isTypedTimeFullyLegal() when NOT in 24hour mode. - int[] values = getEnteredTime(null); - return (values[0] >= 0 && values[1] >= 0 && values[1] < 60); - } else { - // For AM/PM mode, the time is legal if it contains an AM or PM, as those can only be - // legally added at specific times based on the tree's algorithm. - return (mTypedTimes.contains(getAmOrPmKeyCode(AM)) || - mTypedTimes.contains(getAmOrPmKeyCode(PM))); - } - } - - private int deleteLastTypedKey() { - int deleted = mTypedTimes.remove(mTypedTimes.size() - 1); - if (!isTypedTimeFullyLegal()) { - onValidationChanged(false); - } - return deleted; - } - - /** - * Get out of keyboard mode. If there is nothing in typedTimes, revert to TimePicker's time. - */ - private void finishKbMode() { - mInKbMode = false; - if (!mTypedTimes.isEmpty()) { - int values[] = getEnteredTime(null); - mRadialTimePickerView.setCurrentHour(values[0]); - mRadialTimePickerView.setCurrentMinute(values[1]); - if (!mIs24HourView) { - mRadialTimePickerView.setAmOrPm(values[2]); - } - mTypedTimes.clear(); - } - updateDisplay(false); - mRadialTimePickerView.setInputEnabled(true); - } - - /** - * Update the hours, minutes, and AM/PM displays with the typed times. If the typedTimes is - * empty, either show an empty display (filled with the placeholder text), or update from the - * timepicker's values. - * - * @param allowEmptyDisplay if true, then if the typedTimes is empty, use the placeholder text. - * Otherwise, revert to the timepicker's values. - */ - private void updateDisplay(boolean allowEmptyDisplay) { - if (!allowEmptyDisplay && mTypedTimes.isEmpty()) { - int hour = mRadialTimePickerView.getCurrentHour(); - int minute = mRadialTimePickerView.getCurrentMinute(); - updateHeaderHour(hour, true); - updateHeaderMinute(minute); - if (!mIs24HourView) { - updateAmPmLabelStates(hour < 12 ? AM : PM); - } - setCurrentItemShowing(mRadialTimePickerView.getCurrentItemShowing(), true, true); - onValidationChanged(true); - } else { - boolean[] enteredZeros = {false, false}; - int[] values = getEnteredTime(enteredZeros); - String hourFormat = enteredZeros[0] ? "%02d" : "%2d"; - String minuteFormat = (enteredZeros[1]) ? "%02d" : "%2d"; - String hourStr = (values[0] == -1) ? mDoublePlaceholderText : - String.format(hourFormat, values[0]).replace(' ', mPlaceholderText); - String minuteStr = (values[1] == -1) ? mDoublePlaceholderText : - String.format(minuteFormat, values[1]).replace(' ', mPlaceholderText); - mHourView.setText(hourStr); - mHourView.setSelected(false); - mMinuteView.setText(minuteStr); - mMinuteView.setSelected(false); - if (!mIs24HourView) { - updateAmPmLabelStates(values[2]); - } - } - } - - private int getValFromKeyCode(int keyCode) { - switch (keyCode) { - case KeyEvent.KEYCODE_0: - return 0; - case KeyEvent.KEYCODE_1: - return 1; - case KeyEvent.KEYCODE_2: - return 2; - case KeyEvent.KEYCODE_3: - return 3; - case KeyEvent.KEYCODE_4: - return 4; - case KeyEvent.KEYCODE_5: - return 5; - case KeyEvent.KEYCODE_6: - return 6; - case KeyEvent.KEYCODE_7: - return 7; - case KeyEvent.KEYCODE_8: - return 8; - case KeyEvent.KEYCODE_9: - return 9; - default: - return -1; - } + public static String[] getAmPmStrings(Context context) { + String[] result = new String[2]; + LocaleData d = LocaleData.get(context.getResources().getConfiguration().locale); + result[0] = d.amPm[0].length() > 2 ? d.narrowAm : d.amPm[0]; + result[1] = d.amPm[1].length() > 2 ? d.narrowPm : d.amPm[1]; + return result; } - - /** - * Get the currently-entered time, as integer values of the hours and minutes typed. - * - * @param enteredZeros A size-2 boolean array, which the caller should initialize, and which - * may then be used for the caller to know whether zeros had been explicitly entered as either - * hours of minutes. This is helpful for deciding whether to show the dashes, or actual 0's. - * - * @return A size-3 int array. The first value will be the hours, the second value will be the - * minutes, and the third will be either AM or PM. - */ - private int[] getEnteredTime(boolean[] enteredZeros) { - int amOrPm = -1; - int startIndex = 1; - if (!mIs24HourView && isTypedTimeFullyLegal()) { - int keyCode = mTypedTimes.get(mTypedTimes.size() - 1); - if (keyCode == getAmOrPmKeyCode(AM)) { - amOrPm = AM; - } else if (keyCode == getAmOrPmKeyCode(PM)){ - amOrPm = PM; - } - startIndex = 2; - } - int minute = -1; - int hour = -1; - for (int i = startIndex; i <= mTypedTimes.size(); i++) { - int val = getValFromKeyCode(mTypedTimes.get(mTypedTimes.size() - i)); - if (i == startIndex) { - minute = val; - } else if (i == startIndex+1) { - minute += 10 * val; - if (enteredZeros != null && val == 0) { - enteredZeros[1] = true; - } - } else if (i == startIndex+2) { - hour = val; - } else if (i == startIndex+3) { - hour += 10 * val; - if (enteredZeros != null && val == 0) { - enteredZeros[0] = true; - } - } - } - - return new int[] { hour, minute, amOrPm }; - } - - /** - * Get the keycode value for AM and PM in the current language. - */ - private int getAmOrPmKeyCode(int amOrPm) { - // Cache the codes. - if (mAmKeyCode == -1 || mPmKeyCode == -1) { - // Find the first character in the AM/PM text that is unique. - KeyCharacterMap kcm = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD); - char amChar; - char pmChar; - for (int i = 0; i < Math.max(mAmText.length(), mPmText.length()); i++) { - amChar = mAmText.toLowerCase(mCurrentLocale).charAt(i); - pmChar = mPmText.toLowerCase(mCurrentLocale).charAt(i); - if (amChar != pmChar) { - KeyEvent[] events = kcm.getEvents(new char[]{amChar, pmChar}); - // There should be 4 events: a down and up for both AM and PM. - if (events != null && events.length == 4) { - mAmKeyCode = events[0].getKeyCode(); - mPmKeyCode = events[2].getKeyCode(); - } else { - Log.e(TAG, "Unable to find keycodes for AM and PM."); - } - break; - } - } - } - if (amOrPm == AM) { - return mAmKeyCode; - } else if (amOrPm == PM) { - return mPmKeyCode; - } - - return -1; - } - - /** - * Create a tree for deciding what keys can legally be typed. - */ - private void generateLegalTimesTree() { - // Create a quick cache of numbers to their keycodes. - final int k0 = KeyEvent.KEYCODE_0; - final int k1 = KeyEvent.KEYCODE_1; - final int k2 = KeyEvent.KEYCODE_2; - final int k3 = KeyEvent.KEYCODE_3; - final int k4 = KeyEvent.KEYCODE_4; - final int k5 = KeyEvent.KEYCODE_5; - final int k6 = KeyEvent.KEYCODE_6; - final int k7 = KeyEvent.KEYCODE_7; - final int k8 = KeyEvent.KEYCODE_8; - final int k9 = KeyEvent.KEYCODE_9; - - // The root of the tree doesn't contain any numbers. - mLegalTimesTree = new Node(); - if (mIs24HourView) { - // We'll be re-using these nodes, so we'll save them. - Node minuteFirstDigit = new Node(k0, k1, k2, k3, k4, k5); - Node minuteSecondDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9); - // The first digit must be followed by the second digit. - minuteFirstDigit.addChild(minuteSecondDigit); - - // The first digit may be 0-1. - Node firstDigit = new Node(k0, k1); - mLegalTimesTree.addChild(firstDigit); - - // When the first digit is 0-1, the second digit may be 0-5. - Node secondDigit = new Node(k0, k1, k2, k3, k4, k5); - firstDigit.addChild(secondDigit); - // We may now be followed by the first minute digit. E.g. 00:09, 15:58. - secondDigit.addChild(minuteFirstDigit); - - // When the first digit is 0-1, and the second digit is 0-5, the third digit may be 6-9. - Node thirdDigit = new Node(k6, k7, k8, k9); - // The time must now be finished. E.g. 0:55, 1:08. - secondDigit.addChild(thirdDigit); - - // When the first digit is 0-1, the second digit may be 6-9. - secondDigit = new Node(k6, k7, k8, k9); - firstDigit.addChild(secondDigit); - // We must now be followed by the first minute digit. E.g. 06:50, 18:20. - secondDigit.addChild(minuteFirstDigit); - - // The first digit may be 2. - firstDigit = new Node(k2); - mLegalTimesTree.addChild(firstDigit); - - // When the first digit is 2, the second digit may be 0-3. - secondDigit = new Node(k0, k1, k2, k3); - firstDigit.addChild(secondDigit); - // We must now be followed by the first minute digit. E.g. 20:50, 23:09. - secondDigit.addChild(minuteFirstDigit); - - // When the first digit is 2, the second digit may be 4-5. - secondDigit = new Node(k4, k5); - firstDigit.addChild(secondDigit); - // We must now be followd by the last minute digit. E.g. 2:40, 2:53. - secondDigit.addChild(minuteSecondDigit); - - // The first digit may be 3-9. - firstDigit = new Node(k3, k4, k5, k6, k7, k8, k9); - mLegalTimesTree.addChild(firstDigit); - // We must now be followed by the first minute digit. E.g. 3:57, 8:12. - firstDigit.addChild(minuteFirstDigit); - } else { - // We'll need to use the AM/PM node a lot. - // Set up AM and PM to respond to "a" and "p". - Node ampm = new Node(getAmOrPmKeyCode(AM), getAmOrPmKeyCode(PM)); - - // The first hour digit may be 1. - Node firstDigit = new Node(k1); - mLegalTimesTree.addChild(firstDigit); - // We'll allow quick input of on-the-hour times. E.g. 1pm. - firstDigit.addChild(ampm); - - // When the first digit is 1, the second digit may be 0-2. - Node secondDigit = new Node(k0, k1, k2); - firstDigit.addChild(secondDigit); - // Also for quick input of on-the-hour times. E.g. 10pm, 12am. - secondDigit.addChild(ampm); - - // When the first digit is 1, and the second digit is 0-2, the third digit may be 0-5. - Node thirdDigit = new Node(k0, k1, k2, k3, k4, k5); - secondDigit.addChild(thirdDigit); - // The time may be finished now. E.g. 1:02pm, 1:25am. - thirdDigit.addChild(ampm); - - // When the first digit is 1, the second digit is 0-2, and the third digit is 0-5, - // the fourth digit may be 0-9. - Node fourthDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9); - thirdDigit.addChild(fourthDigit); - // The time must be finished now. E.g. 10:49am, 12:40pm. - fourthDigit.addChild(ampm); - - // When the first digit is 1, and the second digit is 0-2, the third digit may be 6-9. - thirdDigit = new Node(k6, k7, k8, k9); - secondDigit.addChild(thirdDigit); - // The time must be finished now. E.g. 1:08am, 1:26pm. - thirdDigit.addChild(ampm); - - // When the first digit is 1, the second digit may be 3-5. - secondDigit = new Node(k3, k4, k5); - firstDigit.addChild(secondDigit); - - // When the first digit is 1, and the second digit is 3-5, the third digit may be 0-9. - thirdDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9); - secondDigit.addChild(thirdDigit); - // The time must be finished now. E.g. 1:39am, 1:50pm. - thirdDigit.addChild(ampm); - - // The hour digit may be 2-9. - firstDigit = new Node(k2, k3, k4, k5, k6, k7, k8, k9); - mLegalTimesTree.addChild(firstDigit); - // We'll allow quick input of on-the-hour-times. E.g. 2am, 5pm. - firstDigit.addChild(ampm); - - // When the first digit is 2-9, the second digit may be 0-5. - secondDigit = new Node(k0, k1, k2, k3, k4, k5); - firstDigit.addChild(secondDigit); - - // When the first digit is 2-9, and the second digit is 0-5, the third digit may be 0-9. - thirdDigit = new Node(k0, k1, k2, k3, k4, k5, k6, k7, k8, k9); - secondDigit.addChild(thirdDigit); - // The time must be finished now. E.g. 2:57am, 9:30pm. - thirdDigit.addChild(ampm); - } - } - - /** - * Simple node class to be used for traversal to check for legal times. - * mLegalKeys represents the keys that can be typed to get to the node. - * mChildren are the children that can be reached from this node. - */ - private class Node { - private int[] mLegalKeys; - private ArrayList<Node> mChildren; - - public Node(int... legalKeys) { - mLegalKeys = legalKeys; - mChildren = new ArrayList<Node>(); - } - - public void addChild(Node child) { - mChildren.add(child); - } - - public boolean containsKey(int key) { - for (int i = 0; i < mLegalKeys.length; i++) { - if (mLegalKeys[i] == key) { - return true; - } - } - return false; - } - - public Node canReach(int key) { - if (mChildren == null) { - return null; - } - for (Node child : mChildren) { - if (child.containsKey(key)) { - return child; - } - } - return null; - } - } - - private final View.OnClickListener mClickListener = new View.OnClickListener() { - @Override - public void onClick(View v) { - - final int amOrPm; - switch (v.getId()) { - case R.id.am_label: - setAmOrPm(AM); - break; - case R.id.pm_label: - setAmOrPm(PM); - break; - case R.id.hours: - setCurrentItemShowing(HOUR_INDEX, true, true); - break; - case R.id.minutes: - setCurrentItemShowing(MINUTE_INDEX, true, true); - break; - default: - // Failed to handle this click, don't vibrate. - return; - } - - tryVibrate(); - } - }; - - private final View.OnKeyListener mKeyListener = new View.OnKeyListener() { - @Override - public boolean onKey(View v, int keyCode, KeyEvent event) { - if (event.getAction() == KeyEvent.ACTION_UP) { - return processKeyUp(keyCode); - } - return false; - } - }; - - private final View.OnFocusChangeListener mFocusListener = new View.OnFocusChangeListener() { - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (!hasFocus && mInKbMode && isTypedTimeFullyLegal()) { - finishKbMode(); - - if (mOnTimeChangedListener != null) { - mOnTimeChangedListener.onTimeChanged(mDelegator, - mRadialTimePickerView.getCurrentHour(), - mRadialTimePickerView.getCurrentMinute()); - } - } - } - }; } diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java index dd165ae94ecb..be4cdc16e1d3 100644 --- a/core/java/android/widget/Toast.java +++ b/core/java/android/widget/Toast.java @@ -235,6 +235,14 @@ public class Toast { public int getYOffset() { return mTN.mY; } + + /** + * Gets the LayoutParams for the Toast window. + * @hide + */ + public WindowManager.LayoutParams getWindowParams() { + return mTN.mParams; + } /** * Make a standard toast that just contains a text view. diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java index 526781175b6c..0bc1a8d4e5fd 100644 --- a/core/java/com/android/internal/app/ChooserActivity.java +++ b/core/java/com/android/internal/app/ChooserActivity.java @@ -16,13 +16,20 @@ package com.android.internal.app; +import android.app.Activity; +import android.content.ComponentName; import android.content.Intent; +import android.content.IntentSender; import android.os.Bundle; import android.os.Parcelable; import android.util.Log; +import android.util.Slog; public class ChooserActivity extends ResolverActivity { + private static final String TAG = "ChooserActivity"; + private Bundle mReplacementExtras; + private IntentSender mChosenComponentSender; @Override protected void onCreate(Bundle savedInstanceState) { @@ -60,11 +67,14 @@ public class ChooserActivity extends ResolverActivity { initialIntents[i] = in; } } + mChosenComponentSender = intent.getParcelableExtra( + Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER); setSafeForwardingMode(true); super.onCreate(savedInstanceState, target, title, defaultTitleRes, initialIntents, null, false); } + @Override public Intent getReplacementIntent(String packageName, Intent defIntent) { if (mReplacementExtras != null) { final Bundle replExtras = mReplacementExtras.getBundle(packageName); @@ -77,6 +87,22 @@ public class ChooserActivity extends ResolverActivity { return defIntent; } + @Override + public void onActivityStarted(Intent intent) { + if (mChosenComponentSender != null) { + final ComponentName target = intent.getComponent(); + if (target != null) { + final Intent fillIn = new Intent().putExtra(Intent.EXTRA_CHOSEN_COMPONENT, target); + try { + mChosenComponentSender.sendIntent(this, Activity.RESULT_OK, fillIn, null, null); + } catch (IntentSender.SendIntentException e) { + Slog.e(TAG, "Unable to launch supplied IntentSender to report " + + "the chosen component: " + e); + } + } + } + } + private void modifyTargetIntent(Intent in) { final String action = in.getAction(); if (Intent.ACTION_SEND.equals(action) || diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java index b9cbc62e0aaa..ccffa1985dbc 100644 --- a/core/java/com/android/internal/app/ResolverActivity.java +++ b/core/java/com/android/internal/app/ResolverActivity.java @@ -644,10 +644,12 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic public void safelyStartActivity(Intent intent) { if (!mSafeForwardingMode) { startActivity(intent); + onActivityStarted(intent); return; } try { startActivityAsCaller(intent, null, UserHandle.USER_NULL); + onActivityStarted(intent); } catch (RuntimeException e) { String launchedFromPackage; try { @@ -662,6 +664,10 @@ public class ResolverActivity extends Activity implements AdapterView.OnItemClic } } + public void onActivityStarted(Intent intent) { + // Do nothing + } + void showAppDetails(ResolveInfo ri) { Intent in = new Intent().setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) .setData(Uri.fromParts("package", ri.activityInfo.packageName, null)) diff --git a/core/java/com/android/internal/http/multipart/FilePart.java b/core/java/com/android/internal/http/multipart/FilePart.java index bfcda0074f0f..45e4be68dd16 100644 --- a/core/java/com/android/internal/http/multipart/FilePart.java +++ b/core/java/com/android/internal/http/multipart/FilePart.java @@ -51,9 +51,14 @@ import org.apache.commons.logging.LogFactory; * @author <a href="mailto:mbowler@GargoyleSoftware.com">Mike Bowler</a> * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> * - * @since 2.0 + * @since 2.0 * + * @deprecated Please use {@link java.net.URLConnection} and friends instead. + * The Apache HTTP client is no longer maintained and may be removed in a future + * release. Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> + * for further details. */ +@Deprecated public class FilePart extends PartBase { /** Default content encoding of file attachments. */ diff --git a/core/java/com/android/internal/http/multipart/MultipartEntity.java b/core/java/com/android/internal/http/multipart/MultipartEntity.java index 2c5e7f64e33e..531925174453 100644 --- a/core/java/com/android/internal/http/multipart/MultipartEntity.java +++ b/core/java/com/android/internal/http/multipart/MultipartEntity.java @@ -80,7 +80,13 @@ import org.apache.commons.logging.LogFactory; * </pre> * * @since 3.0 + * + * @deprecated Please use {@link java.net.URLConnection} and friends instead. + * The Apache HTTP client is no longer maintained and may be removed in a future + * release. Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> + * for further details. */ +@Deprecated public class MultipartEntity extends AbstractHttpEntity { private static final Log log = LogFactory.getLog(MultipartEntity.class); diff --git a/core/java/com/android/internal/http/multipart/Part.java b/core/java/com/android/internal/http/multipart/Part.java index cb1b5465389f..1d66dc674331 100644 --- a/core/java/com/android/internal/http/multipart/Part.java +++ b/core/java/com/android/internal/http/multipart/Part.java @@ -48,7 +48,13 @@ import org.apache.commons.logging.LogFactory; * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> * * @since 2.0 + * + * @deprecated Please use {@link java.net.URLConnection} and friends instead. + * The Apache HTTP client is no longer maintained and may be removed in a future + * release. Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> + * for further details. */ +@Deprecated public abstract class Part { /** Log object for this class. */ diff --git a/core/java/com/android/internal/http/multipart/StringPart.java b/core/java/com/android/internal/http/multipart/StringPart.java index c98257e27041..73d0f908ac2a 100644 --- a/core/java/com/android/internal/http/multipart/StringPart.java +++ b/core/java/com/android/internal/http/multipart/StringPart.java @@ -46,7 +46,13 @@ import org.apache.commons.logging.LogFactory; * @author <a href="mailto:oleg@ural.ru">Oleg Kalnichevski</a> * * @since 2.0 + * + * @deprecated Please use {@link java.net.URLConnection} and friends instead. + * The Apache HTTP client is no longer maintained and may be removed in a future + * release. Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> + * for further details. */ +@Deprecated public class StringPart extends PartBase { /** Log object for this class. */ diff --git a/core/java/com/android/internal/statusbar/IStatusBarService.aidl b/core/java/com/android/internal/statusbar/IStatusBarService.aidl index 8794d319e179..e6bcea1eb4ab 100644 --- a/core/java/com/android/internal/statusbar/IStatusBarService.aidl +++ b/core/java/com/android/internal/statusbar/IStatusBarService.aidl @@ -43,6 +43,7 @@ interface IStatusBarService void onPanelRevealed(); void onPanelHidden(); void onNotificationClick(String key); + void onNotificationActionClick(String key, int actionIndex); void onNotificationError(String pkg, String tag, int id, int uid, int initialPid, String message, int userId); void onClearAllNotifications(int userId); diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java index 91e53307d997..b9a85e59eb96 100644 --- a/core/java/com/android/internal/widget/ActionBarView.java +++ b/core/java/com/android/internal/widget/ActionBarView.java @@ -19,8 +19,6 @@ package com.android.internal.widget; import android.animation.LayoutTransition; import android.app.ActionBar; import android.content.Context; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.TypedArray; import android.graphics.drawable.Drawable; @@ -29,9 +27,7 @@ import android.os.Parcelable; import android.text.Layout; import android.text.TextUtils; import android.util.AttributeSet; -import android.util.TypedValue; import android.view.CollapsibleActionView; -import android.view.ContextThemeWrapper; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; @@ -111,10 +107,10 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar { private int mProgressBarPadding; private int mItemPadding; - private int mTitleStyleRes; - private int mSubtitleStyleRes; - private int mProgressStyle; - private int mIndeterminateProgressStyle; + private final int mTitleStyleRes; + private final int mSubtitleStyleRes; + private final int mProgressStyle; + private final int mIndeterminateProgressStyle; private boolean mUserTitle; private boolean mIncludeTabs; diff --git a/core/java/com/android/internal/widget/ExploreByTouchHelper.java b/core/java/com/android/internal/widget/ExploreByTouchHelper.java index 4689179835cc..0e046cb21609 100644 --- a/core/java/com/android/internal/widget/ExploreByTouchHelper.java +++ b/core/java/com/android/internal/widget/ExploreByTouchHelper.java @@ -19,6 +19,7 @@ package com.android.internal.widget; import android.content.Context; import android.graphics.Rect; import android.os.Bundle; +import android.util.IntArray; import android.view.accessibility.*; import android.view.MotionEvent; import android.view.View; @@ -26,11 +27,9 @@ import android.view.ViewParent; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.view.accessibility.AccessibilityNodeInfo; +import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction; import android.view.accessibility.AccessibilityNodeProvider; -import java.util.LinkedList; -import java.util.List; - /** * ExploreByTouchHelper is a utility class for implementing accessibility * support in custom {@link android.view.View}s that represent a collection of View-like @@ -58,14 +57,16 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate { private static final Rect INVALID_PARENT_BOUNDS = new Rect( Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); - // Temporary, reusable data structures. - private final Rect mTempScreenRect = new Rect(); - private final Rect mTempParentRect = new Rect(); - private final Rect mTempVisibleRect = new Rect(); - private final int[] mTempGlobalRect = new int[2]; + // Lazily-created temporary data structures used when creating nodes. + private Rect mTempScreenRect; + private Rect mTempParentRect; + private int[] mTempGlobalRect; + + /** Lazily-created temporary data structure used to compute visibility. */ + private Rect mTempVisibleRect; - /** View's context **/ - private Context mContext; + /** Lazily-created temporary data structure used to obtain child IDs. */ + private IntArray mTempArray; /** System accessibility manager, used to check state and send events. */ private final AccessibilityManager mManager; @@ -73,6 +74,9 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate { /** View whose internal structure is exposed through this helper. */ private final View mView; + /** Context of the host view. **/ + private final Context mContext; + /** Node provider that handles creating nodes and performing actions. */ private ExploreByTouchNodeProvider mNodeProvider; @@ -332,11 +336,17 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate { onInitializeAccessibilityNodeInfo(mView, node); // Add the virtual descendants. - final LinkedList<Integer> virtualViewIds = new LinkedList<Integer>(); + if (mTempArray == null) { + mTempArray = new IntArray(); + } else { + mTempArray.clear(); + } + final IntArray virtualViewIds = mTempArray; getVisibleVirtualViews(virtualViewIds); - for (Integer childVirtualViewId : virtualViewIds) { - node.addChild(mView, childVirtualViewId); + final int N = virtualViewIds.size(); + for (int i = 0; i < N; i++) { + node.addChild(mView, virtualViewIds.get(i)); } return node; @@ -371,6 +381,11 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate { * @return An {@link AccessibilityNodeInfo} for the specified item. */ private AccessibilityNodeInfo createNodeForChild(int virtualViewId) { + ensureTempRects(); + final Rect tempParentRect = mTempParentRect; + final int[] tempGlobalRect = mTempGlobalRect; + final Rect tempScreenRect = mTempScreenRect; + final AccessibilityNodeInfo node = AccessibilityNodeInfo.obtain(); // Ensure the client has good defaults. @@ -387,8 +402,8 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate { + "populateNodeForVirtualViewId()"); } - node.getBoundsInParent(mTempParentRect); - if (mTempParentRect.equals(INVALID_PARENT_BOUNDS)) { + node.getBoundsInParent(tempParentRect); + if (tempParentRect.equals(INVALID_PARENT_BOUNDS)) { throw new RuntimeException("Callbacks must set parent bounds in " + "populateNodeForVirtualViewId()"); } @@ -411,29 +426,35 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate { // Manage internal accessibility focus state. if (mFocusedVirtualViewId == virtualViewId) { node.setAccessibilityFocused(true); - node.addAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS); + node.addAction(AccessibilityAction.ACTION_CLEAR_ACCESSIBILITY_FOCUS); } else { node.setAccessibilityFocused(false); - node.addAction(AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS); + node.addAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS); } // Set the visibility based on the parent bound. - if (intersectVisibleToUser(mTempParentRect)) { + if (intersectVisibleToUser(tempParentRect)) { node.setVisibleToUser(true); - node.setBoundsInParent(mTempParentRect); + node.setBoundsInParent(tempParentRect); } // Calculate screen-relative bound. - mView.getLocationOnScreen(mTempGlobalRect); - final int offsetX = mTempGlobalRect[0]; - final int offsetY = mTempGlobalRect[1]; - mTempScreenRect.set(mTempParentRect); - mTempScreenRect.offset(offsetX, offsetY); - node.setBoundsInScreen(mTempScreenRect); + mView.getLocationOnScreen(tempGlobalRect); + final int offsetX = tempGlobalRect[0]; + final int offsetY = tempGlobalRect[1]; + tempScreenRect.set(tempParentRect); + tempScreenRect.offset(offsetX, offsetY); + node.setBoundsInScreen(tempScreenRect); return node; } + private void ensureTempRects() { + mTempGlobalRect = new int[2]; + mTempParentRect = new Rect(); + mTempScreenRect = new Rect(); + } + private boolean performAction(int virtualViewId, int action, Bundle arguments) { switch (virtualViewId) { case View.NO_ID: @@ -451,13 +472,13 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate { switch (action) { case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: case AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS: - return manageFocusForChild(virtualViewId, action, arguments); + return manageFocusForChild(virtualViewId, action); default: return onPerformActionForVirtualView(virtualViewId, action, arguments); } } - private boolean manageFocusForChild(int virtualViewId, int action, Bundle arguments) { + private boolean manageFocusForChild(int virtualViewId, int action) { switch (action) { case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS: return requestAccessibilityFocus(virtualViewId); @@ -503,12 +524,16 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate { } // If no portion of the parent is visible, this view is not visible. - if (!mView.getLocalVisibleRect(mTempVisibleRect)) { + if (mTempVisibleRect == null) { + mTempVisibleRect = new Rect(); + } + final Rect tempVisibleRect = mTempVisibleRect; + if (!mView.getLocalVisibleRect(tempVisibleRect)) { return false; } // Check if the view intersects the visible portion of the parent. - return localRect.intersect(mTempVisibleRect); + return localRect.intersect(tempVisibleRect); } /** @@ -588,7 +613,7 @@ public abstract class ExploreByTouchHelper extends View.AccessibilityDelegate { * * @param virtualViewIds The list to populate with visible items */ - protected abstract void getVisibleVirtualViews(List<Integer> virtualViewIds); + protected abstract void getVisibleVirtualViews(IntArray virtualViewIds); /** * Populates an {@link AccessibilityEvent} with information about the diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java index 97b1634f99cc..99b1baef132c 100644 --- a/core/java/com/android/internal/widget/SwipeDismissLayout.java +++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java @@ -17,6 +17,7 @@ package com.android.internal.widget; import android.animation.TimeInterpolator; +import android.app.Activity; import android.content.Context; import android.util.AttributeSet; import android.util.Log; @@ -102,6 +103,13 @@ public class SwipeDismissLayout extends FrameLayout { android.R.integer.config_shortAnimTime); mCancelInterpolator = new DecelerateInterpolator(1.5f); mDismissInterpolator = new AccelerateInterpolator(1.5f); + // SwipeDismissLayout assumes that the host Activity is translucent + // and temporarily disables translucency when it is fully visible. + // As soon as the user starts swiping, we will re-enable + // translucency. + if (context instanceof Activity) { + ((Activity) context).convertFromTranslucent(); + } } public void setOnDismissedListener(OnDismissedListener listener) { @@ -197,6 +205,9 @@ public class SwipeDismissLayout extends FrameLayout { mLastX = ev.getRawX(); updateSwiping(ev); if (mSwiping) { + if (getContext() instanceof Activity) { + ((Activity) getContext()).convertToTranslucent(null, null); + } setProgress(ev.getRawX() - mDownX); break; } @@ -218,6 +229,9 @@ public class SwipeDismissLayout extends FrameLayout { } protected void cancel() { + if (getContext() instanceof Activity) { + ((Activity) getContext()).convertFromTranslucent(); + } if (mProgressListener != null) { mProgressListener.onSwipeCancelled(this); } diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index e0abc24c42c5..a578b5db7d91 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -315,7 +315,8 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding } SkBitmap decodingBitmap; - if (!decoder->decode(stream, &decodingBitmap, prefColorType, decodeMode)) { + if (decoder->decode(stream, &decodingBitmap, prefColorType, decodeMode) + != SkImageDecoder::kSuccess) { return nullObjectReturn("decoder->decode returned false"); } diff --git a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp index b64ab0d9d3ea..a67740c7f89c 100644 --- a/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp +++ b/core/jni/android/graphics/CreateJavaOutputStreamAdaptor.cpp @@ -78,6 +78,8 @@ private: env->ExceptionDescribe(); env->ExceptionClear(); SkDebugf("---- read threw an exception\n"); + // Consider the stream to be at the end, since there was an error. + fIsAtEnd = true; return 0; } @@ -92,6 +94,9 @@ private: env->ExceptionDescribe(); env->ExceptionClear(); SkDebugf("---- read:GetByteArrayRegion threw an exception\n"); + // The error was not with the stream itself, but consider it to be at the + // end, since we do not have a way to recover. + fIsAtEnd = true; return 0; } diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 9bb8195b8901..a0b2ca830b65 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -47,6 +47,11 @@ #include <ScopedUtfChars.h> +#include <AnimationContext.h> +#include <DisplayListRenderer.h> +#include <RenderNode.h> +#include <renderthread/RenderProxy.h> + // ---------------------------------------------------------------------------- namespace android { @@ -352,8 +357,54 @@ static void nativeWriteToParcel(JNIEnv* env, jclass clazz, parcel->writeStrongBinder( self != 0 ? self->getIGraphicBufferProducer()->asBinder() : NULL); } +namespace uirenderer { + +using namespace android::uirenderer::renderthread; + +class ContextFactory : public IContextFactory { +public: + virtual AnimationContext* createAnimationContext(renderthread::TimeLord& clock) { + return new AnimationContext(clock); + } +}; + +static jlong create(JNIEnv* env, jclass clazz, jlong rootNodePtr, jlong surfacePtr) { + RenderNode* rootNode = reinterpret_cast<RenderNode*>(rootNodePtr); + sp<Surface> surface(reinterpret_cast<Surface*>(surfacePtr)); + ContextFactory factory; + RenderProxy* proxy = new RenderProxy(false, rootNode, &factory); + proxy->loadSystemProperties(); + proxy->setSwapBehavior(kSwap_discardBuffer); + proxy->initialize(surface); + // Shadows can't be used via this interface, so just set the light source + // to all 0s. (and width & height are unused, TODO remove them) + proxy->setup(0, 0, (Vector3){0, 0, 0}, 0, 0, 0); + return (jlong) proxy; +} + +static void setSurface(JNIEnv* env, jclass clazz, jlong rendererPtr, jlong surfacePtr) { + RenderProxy* proxy = reinterpret_cast<RenderProxy*>(rendererPtr); + sp<Surface> surface(reinterpret_cast<Surface*>(surfacePtr)); + proxy->updateSurface(surface); +} + +static void draw(JNIEnv* env, jclass clazz, jlong rendererPtr) { + RenderProxy* proxy = reinterpret_cast<RenderProxy*>(rendererPtr); + nsecs_t frameTimeNs = systemTime(CLOCK_MONOTONIC); + proxy->syncAndDrawFrame(frameTimeNs, 0, 1.0f); +} + +static void destroy(JNIEnv* env, jclass clazz, jlong rendererPtr) { + RenderProxy* proxy = reinterpret_cast<RenderProxy*>(rendererPtr); + delete proxy; +} + +} // uirenderer + // ---------------------------------------------------------------------------- +namespace hwui = android::uirenderer; + static JNINativeMethod gSurfaceMethods[] = { {"nativeCreateFromSurfaceTexture", "(Landroid/graphics/SurfaceTexture;)J", (void*)nativeCreateFromSurfaceTexture }, @@ -375,6 +426,12 @@ static JNINativeMethod gSurfaceMethods[] = { (void*)nativeReadFromParcel }, {"nativeWriteToParcel", "(JLandroid/os/Parcel;)V", (void*)nativeWriteToParcel }, + + // HWUI context + {"nHwuiCreate", "(JJ)J", (void*) hwui::create }, + {"nHwuiSetSurface", "(JJ)V", (void*) hwui::setSurface }, + {"nHwuiDraw", "(J)V", (void*) hwui::draw }, + {"nHwuiDestroy", "(J)V", (void*) hwui::destroy }, }; int register_android_view_Surface(JNIEnv* env) diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 15b56c3ae209..8e0cd5266090 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1269,6 +1269,18 @@ android:description="@string/permdesc_use_sip" android:label="@string/permlab_use_sip" /> + <!-- Protects the ability to register any PhoneAccount with a capability flags of either + PhoneAccount#CAPABILITY_CALL_PROVIDER or PhoneAccount#CAPABILITY_SIM_SUBSCRIPTION. --> + <permission android:name="android.permission.REGISTER_PROVIDER_OR_SUBSCRIPTION" + android:permissionGroup="android.permission-group.PHONE_CALLS" + android:description="@string/permdesc_register_provider" + android:label="@string/permlab_register_provider" /> + + <permission android:name="android.permission.REGISTER_CONNECTION_MANAGER" + android:permissionGroup="android.permission-group.PHONE_CALLS" + android:description="@string/permdesc_connection_manager" + android:label="@string/permlab_connection_manager" /> + <!-- @SystemApi Allows an application to bind to InCallService implementations. @hide --> <permission android:name="android.permission.BIND_INCALL_SERVICE" diff --git a/core/res/res/layout/time_header_label.xml b/core/res/res/layout/time_header_label.xml index 84b2b0cdcb88..efb362847df4 100644 --- a/core/res/res/layout/time_header_label.xml +++ b/core/res/res/layout/time_header_label.xml @@ -56,7 +56,9 @@ android:paddingStart="@dimen/timepicker_ampm_horizontal_padding" android:paddingTop="@dimen/timepicker_ampm_vertical_padding" android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding" - android:paddingBottom="@dimen/timepicker_am_bottom_padding" /> + android:paddingBottom="@dimen/timepicker_am_bottom_padding" + android:lines="1" + android:ellipsize="none" /> <CheckedTextView android:id="@+id/pm_label" android:layout_width="wrap_content" @@ -64,7 +66,9 @@ android:paddingStart="@dimen/timepicker_ampm_horizontal_padding" android:paddingTop="@dimen/timepicker_pm_top_padding" android:paddingEnd="@dimen/timepicker_ampm_horizontal_padding" - android:paddingBottom="@dimen/timepicker_ampm_vertical_padding" /> + android:paddingBottom="@dimen/timepicker_ampm_vertical_padding" + android:lines="1" + android:ellipsize="none" /> </LinearLayout> </RelativeLayout> </FrameLayout> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index d3004a59a23d..a0c93b9398f1 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"verander jou eie kontakkaart"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Laat die program toe om persoonlike profielinligting, soos jou naam en kontakinligting, wat op jou toestel gestoor is, te verander of daarby te voeg. Dit beteken dat die program jou kan identifiseer en moontlik jou profielinligting na ander mense kan stuur."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"liggaamsensors (soos hartklopmonitors)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Laat die program toe om toegang tot data te verkry vanaf sensors wat jy gebruik om te meet wat binne jou liggaam aangaan, soos hartklop."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Laat die program toe om toegang te verkry tot data van sensors af wat jou fisieke toestand, soos jou polsslag, monitor."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lees jou sosiale stroom"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Laat die program toe om toegang tot sosiale opdaterings van jou en jou vriende te verkry en dit te sinkroniseer. Wees versigtig wanneer jy inligting deel -- dit laat die program toe om kommunikasie tussen jou en jou vriende op sosiale netwerke te lees, ongeag vertroulikheid. Let wel: hierdie toestemming mag dalk nie op alle sosiale netwerke afgedwing word nie."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skryf aan jou sosiale stroom"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index c2e2e394fe79..16d4c380e8ac 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"የራስዎን የዕውቂያ ካርድ ያስተካክሉ"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"መተግበሪያው ልክ እንደ ስምዎ እና የእውቂያ መረጃዎ ያሉ በመሳሪያዎ ላይ የተከማቹ የግል መገለጫ መረጃዎችን እንዲቀይር ወይም እንዲያክልባቸው ይፈቅድለታል። ይህም ማለት መተግበሪያው ለይቶ ሊያውቅዎ እና የመገለጫ መረጃዎን ለሌሎች ሊልክ ይችላል።"</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"የሰውነት መመርመሪያዎች (እንደ የልብ ምት መቆጣጠሪያዎች)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"መተግበሪያው እርስዎ በሰውነትዎ ውስጥ እየተካሄዱ ያሉ እንደ የልብ ምት የመሳሰሉ ነገሮችን ለመለካት የሚጠቀሙበትን ውሂብ ከመመርመሪያዎቹ ላይ እንዲደርስ ይፈቅድለታል።"</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"እንደ የእርስዎ የልብ ምት የመሳሰሉ ያሉበትን አካላዊ ሁኔታ ከሚቆጣጠሩ ሰውነት ዳሳሾች ውሂብ ላይ እንዲደርስ ለመተግበሪያው ይፈቅደለታል።"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"የእርስዎን ማህበራዊ የውይይት ክፍሎች ያንብቡ"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"መተግበሪያው የአንተንና የጓኞችህን ማህበራዊ ዝማኔዎችን እንዲደርስባቸው እና እንዲያመሳስላቸው ይፈቅድለታል። መረጃ ስታጋራ ተጠንቀቅ -- ይህ መተግበሪያው ሚስጥራዊነትን ከግምት ሳያስገባ በማህበራዊ አውታረ መረቦች በአንተ እና በጓደኞችህ መካከል የሚደረጉ ግንኙነቶችን እንዲያነብ ይፈቅድለታል። ማስታወሻ፦ ይህ ፈቃድ ለሁሉም ማህበራዊ አውታር መረቦች ላይ ላይፈጸም ይችላል።"</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ወደ የእርስዎ ማህበራዊ የውይይት ክፍሎች ይጻፉ"</string> @@ -1761,7 +1761,7 @@ <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"ይህን ማያ ገጽ ለመንቀል አጠቃላይ እይታን ይንኩትና ይያዙት።"</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"ማያ ገጽ ተሰክቷል። መንቀል በድርጅትዎ አይፈቀድም።"</string> <string name="lock_to_app_title" msgid="1682643873107812874">"ማያ ገጽ መሰካትን ይጠቀሙ?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"ማያ ገጽ መሰካን ማሳያውን በአንዲ እይታ ውስጥ ይቆልፈዋል።\n\nለመንቀል ተመለስን እና አጠቃላይ እይታን በተመሳሳይ ይንኳቸውና ይያዟቸው።"</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"ማያ ገጽ መሰካትን ማሳያውን በነጠላ እይታ ውስጥ ይቆልፈዋል።\n\nለመንቀል ተመለስን እና አጠቃላይ እይታን በተመሳሳይ ይንኳቸውና ይያዟቸው።"</string> <string name="lock_to_app_description_accessible" msgid="199664191087836099">"ማያ ገጽ መሰካት ማሳያውን በአንዲት እይታ ውስጥ ይቆልፈዋል።\n\nለመንቀል አጠቃላይ እይታን ይንኩትና ይያዙት።"</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"አይ፣ አመሰግናለሁ"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"ጀምር"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 092cb29e129d..891c9404a5b4 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"تعديل بطاقة جهة الاتصال الخاصة"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"للسماح للتطبيق بتغيير المعلومات الشخصية في الملف الشخصي المخزنة على الجهاز أو الإضافة إليها، مثل اسمك ومعلومات جهات الاتصال. ويعني ذلك أنه يمكن للتطبيق التعرف عليك كما يمكنه إرسال معلومات ملفك الشخصي إلى الآخرين."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"أجهزة استشعار الجسم (مثل شاشات معدل ضربات القلب)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"للسماح للتطبيق بالدخول إلى البيانات من أجهزة الاستشعار التي تستخدمها لقياس ما يجري داخل جسمك، مثل معدل ضربات القلب."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"للسماح للتطبيق بالدخول إلى البيانات من المستشعرات التي تراقب الحالة البدنية، مثل معدل نبضات القلب."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"قراءة المشاركات الاجتماعية"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"للسماح للتطبيق بالدخول إلى التحديثات الاجتماعية منك ومن أصدقائك ومزامنتها. توخ الحذر عند مشاركة المعلومات، حيث يتيح هذا للتطبيق قراءة عمليات التواصل بينك وبين أصدقائك على الشبكات الاجتماعية، بغض النظر عن مدى السرية. ملاحظة: لا يجوز فرض هذا الإذن على جميع الشبكات الاجتماعية."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"كتابة إلى المشاركات الاجتماعية"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"تم تحديد <xliff:g id="ITEM">%1$s</xliff:g>"</string> <string name="deleted_key" msgid="7659477886625566590">"تم حذف <xliff:g id="KEY">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> المخصص للعمل"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"لإلغاء تثبيت هذه الشاشة، يمكنك لمس \"رجوع\" و\"عرض عام\" في آن واحد مع الاستمرار."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"لإلغاء تثبيت هذه الشاشة، يمكنك لمس \"عرض عام\" مع الاستمرار."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"لإلغاء تثبيت هذه الشاشة، يمكنك لمس \"رجوع\" و\"نظرة عامة\" في آن واحد مع الاستمرار."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"لإلغاء تثبيت هذه الشاشة، يمكنك لمس \"نظرة عامة\" مع الاستمرار."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"الشاشة مثبتة. لا تسمح منظمتك بإلغاء التثبيت."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"هل تريد استخدام تثبيت الشاشة؟"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"يؤدي تثبيت الشاشة إلى تأمين الشاشة في العرض المفرد.\n\nلإلغاء التثبيت، المس \"رجوع\" و\"عرض عام\" في آن واحد مع الاستمرار."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"يؤدي تثبيت الشاشة إلى قفل الشاشة في العرض المفرد.\n\nلإلغاء التثبيت، يمكنك لمس \"عرض عام\" مع الاستمرار."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"يؤدي تثبيت الشاشة إلى تأمين الشاشة في العرض المفرد.\n\nلإلغاء التثبيت، المس \"رجوع\" و\"نظرة عامة\" في آن واحد مع الاستمرار."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"يؤدي تثبيت الشاشة إلى قفل الشاشة في العرض المفرد.\n\nلإلغاء التثبيت، يمكنك لمس \"نظرة عامة\" مع الاستمرار."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"لا، شكرًا"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"بدء"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"تم تثبيت الشاشة"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 696e901de54b..7671cb1018df 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"промяна на собств. ви карт. с данни за контакт"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Разрешава на приложението да променя или добавя към личния потребителски профил информация, съхранена на устройството ви, като например вашето име и данни за връзка. Това означава, че приложението може да ви идентифицира и да изпраща данните за потребителския ви профил на други хора."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"телесни сензори (като монитори за сърдечния ритъм)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Разрешава на приложението да осъществява достъп до данни от използваните от вас сензори, за да измери какво се случва в тялото ви, като например сърдечен ритъм."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Разрешава на приложението да осъществява достъп до данните от сензорите, които следят физическото ви състояние, като например сърдечния ви ритъм."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"четене на социалния ви поток"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Разрешава на приложението да осъществява достъп и да синхронизира социални актуализации от вас и приятелите ви. Бъдете внимателни при споделянето на информация – това позволява на приложението да чете съобщения помежду ви в социалните мрежи независимо от поверителността. Забележка: Възможно е ограниченията на това разрешение да не могат да бъдат наложени във всички социални мрежи."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"писане в социалния ви поток"</string> @@ -1758,11 +1758,11 @@ <string name="deleted_key" msgid="7659477886625566590">"Изтрихте <xliff:g id="KEY">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> за работа"</string> <string name="lock_to_app_toast" msgid="7570091317001980053">"За да освободите екрана, докоснете и задръжте едновременно бутона за връщане назад и този за общ преглед."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"За да освободите този екран, докоснете и задръжте бутона за общ преглед."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"За да освободите този екран, докоснете и задръжте бутона „Общ преглед“."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Екранът е фиксиран. Освобождаването не е разрешено от организацията ви."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Да се използва ли функцията за фиксиране на екрана?"</string> <string name="lock_to_app_description" msgid="4120623404152035221">"Фиксирането на екрана заключва дисплея в един изглед.\n\nЗа да го освободите, докоснете и задръжте едновременно бутона за връщане назад и този за общ преглед."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Фиксирането на екрана заключва дисплея в един изглед.\n\nЗа да го освободите, докоснете и задръжте бутона за общ преглед."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Фиксирането на екрана заключва дисплея в един изглед.\n\nЗа да го освободите, докоснете и задръжте бутона „Общ преглед“."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"НЕ, БЛАГОДАРЯ"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"СТАРТИРАНЕ"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Екранът е фиксиран"</string> diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml index e6ea6c928b53..401bd7f4cd73 100644 --- a/core/res/res/values-bn-rBD/strings.xml +++ b/core/res/res/values-bn-rBD/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"আপনার নিজস্ব পরিচিতি কার্ড সংশোধন করুন"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"অ্যাপ্লিকেশানটিকে আপনার ডিভাইসে সংরক্ষিত ব্যক্তিগত প্রোফাইলের তথ্য যেমন আপনার নাম এবং পরিচিতি তথ্য পড়ার অনুমতি দেয়৷ এর মানে হল এই অ্যাপ্লিকেশানটি আপনাকে শনাক্ত করতে পারে এবং আপনার প্রোফাইলের তথ্য অন্যদের পাঠাতে পারে৷"</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"শরীরের সেন্সর (হার্ট রেট মনিটারের মত)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"অ্যাপ্লিকেশানকে, হৃদস্পন্দনের মতো, আপনার শরীরের ভেতর কি ঘটছে তা পরিমাপ করার জন্য ব্যবহৃত সেন্সর থেকে তথ্য অ্যাক্সেস করার অনুমতি দেয়৷"</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"অ্যাপ্লিকেশানটিকে আপনার শারীরিক অবস্থা যেমন, আপনার হৃৎস্পন্দন পর্যবেক্ষণ করে এমন সেন্সরগুলি অ্যাক্সেস করতে মঞ্জুরি দেয়।"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"আপনার সামাজিক স্ট্রীম পড়ে"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"অ্যাপ্লিকেশানটিকে আপনার এবং আপনার বন্ধুদের থেকে সামাজিক আপডেটগুলিতে অ্যাক্সেস এবং সিঙ্ক করতে দেয়৷ তথ্য ভাগ করার সময় সতর্ক থাকুন -- এই অ্যাপ্লিকেশানটিকে গোপনীয়তা নির্বিশেষে সামাজিক নেটওয়ার্কগুলিতে আপনি এবং আপনার বন্ধুদের মধ্যে যোগাযোগগুলি পড়তে দেয়৷ দ্রষ্টব্য: এই অনুমতি সমস্ত সামাজিক নেটওয়ার্কে বলবৎ নাও হতে পারে৷"</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"আপনার সামাজিক স্ট্রীমে লেখে"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> নির্বাচন করা হয়েছে"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> মুছে ফেলা হয়েছে"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"কর্মক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"এই স্ক্রীনটিকে আনপিন করতে, \'ফিরুন\' এবং \'ওভারভিউ\' একসাথে স্পর্শ করুন এবং ধরে রাখুন৷"</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"এই স্ক্রীনটিকে আনপিন করতে, \'ওভারভিউ\' স্পর্শ করুন এবং ধরে রাখুন৷"</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"এই স্ক্রীনটিকে আনপিন করতে, \'ফিরুন\' এবং \'এক নজরে\' একসাথে স্পর্শ করুন এবং ধরে রাখুন৷"</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"এই স্ক্রীনটিকে আনপিন করতে, \'এক নজরে\' স্পর্শ করুন এবং ধরে রাখুন৷"</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"স্ক্রীন পিন করা আছে। আপনার প্রতিষ্ঠান এটিকে পিনমুক্ত করার অনুমতি দেয়নি।"</string> <string name="lock_to_app_title" msgid="1682643873107812874">"স্ক্রীন পিন করা ব্যবহার করবেন?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"পিন করে রাখলে তা স্ক্রীনের প্রদর্শনকে একটি নির্দিষ্ট অবস্থায় লক করবে৷\n\nআনপিন করার জন্য, \'ফিরুন\' এবং \'ওভারভিউ\' একসাথে স্পর্শ করুন এবং ধরে রাখুন৷"</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"পিন করে রাখলে তা স্ক্রীনের প্রদর্শনকে একটি নির্দিষ্ট অবস্থায় লক করবে৷\n\n আনপিন করার জন্য, \'ওভারভিউ\' স্পর্শ করুন এবং ধরে রাখুন৷"</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"পিন করে রাখলে তা স্ক্রীনের প্রদর্শনকে একটি নির্দিষ্ট অবস্থায় লক করবে৷\n\nআনপিন করার জন্য, \'ফিরুন\' এবং \'এক নজরে\' একসাথে স্পর্শ করুন এবং ধরে রাখুন৷"</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"পিন করে রাখলে তা স্ক্রীনের প্রদর্শনকে একটি নির্দিষ্ট অবস্থায় লক করবে৷\n\n আনপিন করার জন্য, \'এক নজরে\' স্পর্শ করুন এবং ধরে রাখুন৷"</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"না, থাক"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"চালু করুন"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"স্ক্রীন পিন করা হয়েছে"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 40dd5f4600ad..ef5103f553d2 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"modificació targeta contacte"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permet que l\'aplicació pugui canviar o afegir informació del perfil personal emmagatzemada al dispositiu, com ara el teu nom i la teva informació de contacte. Això significa que l\'aplicació et pot identificar i enviar la informació del teu perfil a altres persones."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"sensors corp. (monitors freq. cardíaca)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Permet que l\'aplicació accedeixi a les dades dels sensors que utilitzes per mesurar els signes vitals del teu cos, com ara la freqüència cardíaca."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permet que l\'aplicació accedeixi a les dades dels sensors que supervisen el teu estat físic, com ara la freqüència cardíaca."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"llegeix el teu tauler d\'activitat social"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permet que l\'aplicació accedeixi i sincronitzi actualitzacions socials teves i dels teus amics. Vés amb compte en compartir informació: això permet que l\'aplicació llegeixi comunicacions entre tu i els teus amics a les xarxes socials, independentment de la confidencialitat. Nota: És possible que aquest permís no s\'apliqui a totes les xarxes socials."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escriu al tauler d\'activitat social"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index df6a0f427df9..771222fea1f1 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"úprava vaší vlastní vizitky"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Umožňuje aplikaci změnit nebo přidat údaje osobního profilu uložené v zařízení, například jméno nebo kontaktní údaje. Znamená to, že vás aplikace může identifikovat a odeslat údaje z profilu dalším aplikacím."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"tělesné senzory (například snímače tepu)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Umožňuje aplikaci přistupovat k datům ze senzorů, pomocí kterých měříte činnost svého těla, například tep."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Umožňuje aplikaci používat data ze senzorů, které sledují vaši fyzickou kondici, například tepovou frekvenci."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"čtení vašeho sociálního streamu"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Umožňuje aplikaci získat přístup k sociálním aktualizacím od vašich přátel a synchronizaci těchto aktualizací. Při sdílení informací buďte opatrní – toto oprávnění umožňuje aplikaci číst komunikaci mezi vámi a vašimi přáteli v sociálních sítích bez ohledu na její důvěrnost. Poznámka: Toto oprávnění nemusí platit pro všechny sociální sítě."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"zápis do sociálního streamu"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index c2481dee0238..1543eeeff99e 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"ændre dit eget kontaktkort"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Tillader, at appen kan ændre eller tilføje oplysninger i din personlige profil, der er gemt på din enhed, f.eks. dit navn eller dine kontaktoplysninger. Dette betyder, at andre apps kan identificere dig og sende profiloplysninger til andre."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"kropssensorer (f.eks. pulsmålere)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Tillader, at appen får adgang til data fra sensorer, du bruger til at måle, hvad der sker inde i din krop, f.eks. din puls."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Giver appen adgang til data fra sensorer, der overvåger din fysiske tilstand, f.eks. din puls."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"læse din sociale strøm"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Tillader, at appen kan få adgang til og synkronisere sociale opdateringer fra dig og dine venner. Vær forsigtig, når du deler oplysninger – med denne tilladelse kan appen læse kommunikation mellem dig og dine venner på sociale netværk, uanset fortrolighed. Bemærk! Denne tilladelse håndhæves muligvis ikke på alle sociale netværk."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skrive i din sociale strøm"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 780c0b9ee42c..6aad2893903c 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"Ihre Kontaktkarten ändern"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ermöglicht der App, auf Ihrem Gerät gespeicherte personenbezogene Profildaten zu ändern, einschließlich Ihres Namens und Ihrer Kontaktdaten, sowie Daten hinzuzufügen. Die App kann Sie so identifizieren und Ihre Profildaten an andere senden."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"Körpersensoren (wie Herzfrequenzmesser)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Ermöglicht der App den Zugriff auf Daten von Sensoren, mit denen Ihre Vitalfunktionen, etwa die Herzfrequenz, gemessen werden."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ermöglicht der App, auf Daten von Sensoren zuzugreifen, die Ihre körperliche Verfassung überwachen, beispielsweise Ihre Herzfrequenz"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"In sozialem Stream lesen"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Ermöglicht der App, auf Updates aus sozialen Netzwerken von Ihnen und Ihren Freunden zuzugreifen und diese zu synchronisieren. Seien Sie vorsichtig, wenn Sie Informationen teilen: Der App wird erlaubt, die Kommunikation zwischen Ihnen und Ihren Freunden in sozialen Netzwerken zu lesen, unabhängig von der Vertraulichkeit der kommunizierten Informationen. Hinweis: Diese Berechtigung kann möglicherweise nicht in allen sozialen Netzwerken erzwungen werden."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"In sozialem Stream schreiben"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index f02cac1f94d0..c86d4a328093 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"τροποποίηση κάρτας επαφής"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Επιτρέπει στην εφαρμογή την αλλαγή ή την προσθήκη προσωπικών πληροφοριών προφίλ οι οποίες είναι αποθηκευμένες στη συσκευή σας, όπως το όνομα και τα στοιχεία επικοινωνίας σας. Αυτό σημαίνει ότι η εφαρμογή μπορεί να σας αναγνωρίσει και να στείλει τις πληροφορίες του προφίλ σας σε άλλα άτομα."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"αισθητήρες λειτουργιών (π.χ. καρδιακό ρυθμό)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Επιτρέπει στην εφαρμογή την πρόσβαση στα δεδομένα από τους αισθητήρες που χρησιμοποιείτε για να παρακολουθείτε τις εσωτερικές λειτουργίες σας, όπως τον καρδιακό ρυθμό."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Επιτρέπει στην εφαρμογή να αποκτήσει πρόσβαση στα δεδομένα των αισθητήρων που παρακολουθούν τη φυσική σας κατάσταση, όπως τον καρδιακό ρυθμό σας."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"διαβάστε τη ροή σας κοινωνικών δικτύων"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Επιτρέπει στην εφαρμογή την πρόσβαση και το συγχρονισμό κοινωνικών ενημερώσεων από εσάς και τους φίλους σας. Θα πρέπει να είστε προσεκτικοί όταν μοιράζεστε πληροφορίες -- αυτό δίνει τη δυνατότητα στην εφαρμογή να διαβάζει τις επικοινωνίες ανάμεσα σε εσάς και τους φίλους σας σε κοινωνικά δίκτυα, ανεξάρτητα από το επίπεδο εμπιστευτικότητας. Σημείωση: αυτή η άδεια ίσως να μην μπορεί να εφαρμοστεί σε όλα τα κοινωνικά δίκτυα."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"γράψτε στη ροή σας κοινωνικών δικτύων"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index ccf4ffa632da..fa1d952b8618 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"modify your own contact card"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Allows the app to change or add to personal profile information stored on your device, such as your name and contact information. This means that the app can identify you and may send your profile information to others."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"body sensors (like heart rate monitors)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Allows the app to access data from sensors that you use to measure what’s happening inside your body, such as heart rate."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Allows the app to access data from sensors that monitor your physical condition, such as your heart rate."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"read your social stream"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Allows the app to access and sync social updates from you and your friends. Be careful when sharing information - this allows the app to read communications between you and your friends on social networks, regardless of confidentiality. Note: this permission may not be enforced on all social networks."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"write to your social stream"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index ccf4ffa632da..fa1d952b8618 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"modify your own contact card"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Allows the app to change or add to personal profile information stored on your device, such as your name and contact information. This means that the app can identify you and may send your profile information to others."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"body sensors (like heart rate monitors)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Allows the app to access data from sensors that you use to measure what’s happening inside your body, such as heart rate."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Allows the app to access data from sensors that monitor your physical condition, such as your heart rate."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"read your social stream"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Allows the app to access and sync social updates from you and your friends. Be careful when sharing information - this allows the app to read communications between you and your friends on social networks, regardless of confidentiality. Note: this permission may not be enforced on all social networks."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"write to your social stream"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index bf39973f8284..9e0d284f6c54 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"modif. tarjeta contacto propia"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permite que la aplicación modifique la información del perfil personal almacenada en el dispositivo, como el nombre o la información de contacto, o que agregue contenido a esa información. Esto significa que puede identificarte y enviar la información de tu perfil a otros usuarios."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"sensores corporales (frec. card)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Permite que la aplicación acceda a datos de sensores que utilizas para medir lo que sucede en tu cuerpo, como la frecuencia cardíaca."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite que la aplicación acceda a datos de sensores que controlan tu condición física, como el ritmo cardíaco."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"Lectura de tu muro social"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permite que la aplicación acceda a las actualizaciones de tus redes sociales y las de tus amigos, y que las sincronice. Ten cuidado al compartir información, ya que la aplicación puede utilizar este permiso para leer las conversaciones que tengas con tus amigos en las redes sociales sin tener en cuenta si son confidenciales. Nota: Este permiso no se puede utilizar en todas las redes sociales."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Escritura en tu muro social"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionado"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> borrado"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Para dejar de fijar esta pantalla, mantén presionados los botones para volver y Descripción general al mismo tiempo."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Para dejar de fijar esta pantalla, mantén presionado el botón Descripción general."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Para dejar de fijar esta pantalla, mantén presionados los botones para volver y Recientes al mismo tiempo."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Para dejar de fijar esta pantalla, mantén presionado el botón Recientes."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"La pantalla está fija. La organización no permite dejar de fijar la pantalla."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"¿Utilizar función para fijar la pantalla?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"La función para fijar la pantalla bloquea la pantalla en una vista única.\n\nPara dejar de fijar la pantalla, mantén presionados los botones para volver y Descripción general al mismo tiempo."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"La función para fijar la pantalla bloquea la pantalla en una vista única.\n\nPara dejar de fijar la pantalla, mantén presionado el botón Descripción general."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"La función para fijar la pantalla bloquea la pantalla en una vista única.\n\nPara dejar de fijar la pantalla, mantén presionados los botones para volver y Recientes al mismo tiempo."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"La función para fijar la pantalla bloquea la pantalla en una vista única.\n\nPara dejar de fijar la pantalla, mantén presionado el botón Recientes."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"NO, GRACIAS"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"INICIAR"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fija"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index c85c9b7301d5..26fa2996efd4 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"modificar tu propia tarjeta de contacto"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permite que la aplicación modifique la información del perfil personal almacenada en el dispositivo (como el nombre o la información de contacto) o que añada contenido a esa información, lo que significa que puede identificar al usuario y enviar la información de su perfil a otros usuarios."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"sens. corp. (mon. frec. card.)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Permite que la aplicación acceda a datos de sensores que utilizas para medir lo que sucede en tu cuerpo, como la frecuencia cardíaca."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite que la aplicación acceda a datos de sensores que controlan tu condición física, como la frecuencia cardíaca."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"consulta tu actividad social"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permite que la aplicación acceda a novedades de redes sociales tuyas y de tus amigos y las sincronice. Ten cuidado al compartir información, ya que la aplicación puede utilizar este permiso para leer conversaciones privadas con tus amigos en las redes sociales sin tener en cuenta si son confidenciales. Nota: este permiso no se puede utilizar en todas las redes sociales."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escribir en tu actividad social"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionado"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Para desactivar esta pantalla, mantén pulsados los botones de retroceso e información general al mismo tiempo."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Para desactivar esta pantalla, mantén pulsado el botón de información general."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Para desactivar esta pantalla, mantén pulsados los botones de retroceso y Visión general al mismo tiempo."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Para desactivar esta pantalla, mantén pulsado Visión general."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Se ha activado la pantalla. Tu organización no puede desactivarla."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"¿Quieres fijar esta pantalla?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"Si activas la pantalla, esta se bloqueará en una vista única.\n\nPara desactivarla, mantén pulsados los botones de retroceso e información general al mismo tiempo."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Si activas la pantalla, esta se bloqueará en una vista única.\n\nPara desactivarla, mantén pulsado el botón de información general."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"Si activas la pantalla, esta se bloqueará en una vista única.\n\nPara desactivarla, mantén pulsados los botones de retroceso y Visión general al mismo tiempo."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Si activas la pantalla, esta se bloqueará en una vista única.\n\nPara desactivarla, mantén pulsado el botón Visión general."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"NO, GRACIAS"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"INICIAR"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fijada"</string> diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml index f342fb0ddc56..31346a64578c 100644 --- a/core/res/res/values-et-rEE/strings.xml +++ b/core/res/res/values-et-rEE/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"muutke oma kontaktikaarti"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Võimaldab rakendusel muuta või lisada seadmesse salvestatud isiklikku profiiliteavet, näiteks teie nime ja kontaktteavet. See tähendab, et rakendus saab teid tuvastada ja saata teie profiiliteavet teistele."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"kehaandurid (nt pulsilugeja)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Lubab rakendusel saada juurdepääsu selliste andurite andmetele, mida kasutate kehas toimuva (nt pulsi) mõõtmiseks."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Lubab rakendusel hankida juurdepääsu andmetele anduritest, mis jälgivad teie füüsilist seisundit, nt südame löögisagedust."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"Sotsiaalvoo lugemine"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Annab rakendusele juurdepääsu ja võimaldab sünkroonida teie ja teie sõprade sotsiaalseid värskendusi. Olge teabe jagamisel ettevaatlik – see võimaldab rakendusel lugeda teie suhtlusi sõpradega suhtlusvõrgustikes konfidentsiaalsusest hoolimata. Märkus: see luba ei pruugi jõustuda kõigis suhtlusvõrgustikes."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Sotsiaalvoogu kirjutamine"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> on valitud"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> on kustutatud"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"Töö <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Ekraani vabastamiseks puudutage pikalt samal ajal nuppe Tagasi ja Ülevaade."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Ekraani vabastamiseks puudutage pikalt nuppu Ülevaade."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Ekraanikuva vabastamiseks puudutage pikalt samal ajal nuppe Tagasi ja Ülevaade."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Ekraanikuva vabastamiseks puudutage pikalt nuppu Ülevaade."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Ekraan on kinnitatud. Teie organisatsioon ei luba vabastamist."</string> - <string name="lock_to_app_title" msgid="1682643873107812874">"Kas kasutada ekraani kinnitamist?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"Ekraani kinnitamine lukustab kuva ühele vaatele.\n\nVabastamiseks puudutage pikalt samal ajal nuppe Tagasi ja Ülevaade."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Ekraani kinnitamine lukustab kuva ühele vaatele.\n\nVabastamiseks puudutage pikalt nuppu Ülevaade."</string> + <string name="lock_to_app_title" msgid="1682643873107812874">"Kas kasutada ekraanikuva kinnitamist?"</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"Ekraanikuva kinnitamine lukustab ekraani ühele vaatele.\n\nVabastamiseks puudutage pikalt samal ajal nuppe Tagasi ja Ülevaade."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Ekraanikuva kinnitamine lukustab ekraani ühele vaatele.\n\nVabastamiseks puudutage pikalt nuppu Ülevaade."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"TÄNAN, EI"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"KÄIVITA"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Ekraan on kinnitatud"</string> diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml index 1ff59e4f7ca4..a05e9c616573 100644 --- a/core/res/res/values-eu-rES/strings.xml +++ b/core/res/res/values-eu-rES/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"zeure kontaktu-txartela aldatzea"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Gailuan gordetako profil pertsonalaren informazioa aldatzeko baimena ematen dio; esaterako, zure izena eta harremanetan jartzeko informazioa. Horrek esan nahi du aplikazioak identifikatu egin zaitzakeela eta zure profil-informazioa besteei bidal diezaiekeela."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"Gorputzaren sentsoreak (adibidez, bihotz-erritmoaren monitoreak)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Zure gorputzaren barnean gertatzen ari dena (adibidez, bihotz-erritmoa) neurtzeko sentsoreen datuak atzitzea baimentzen die aplikazioei."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Zure egoera fisikoa kontrolatzen duten sentsoreetako datuak (adibidez, maiztasun kardiakoa) atzitzea baimentzen die aplikazioei."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"irakurri sare sozialetako korronteak"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Zure eta zure lagunen sare sozialetako eguneratzeak atzitzeko baimena ematen die aplikazioei. Kontuz partekatu informazioa; baimen honekin aplikazioak zure eta zure lagunen arteko sare sozialetako komunikazioak irakur ditzake, isilpekotasuna kontuan izan gabe. Oharra: baliteke baimen hori sare sozial guztiek ez aplikatzea."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"idatzi sare sozialetako korronteetan"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index b66d0ae03781..615d1e41efc5 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"اصلاح کارت تماس شما"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"به برنامه اجازه میدهد تا اطلاعات نمایه شخصی ذخیره شده در دستگاه شما، مانند نام و اطلاعات تماس شما را تغییر دهد یا اضافه کند. یعنی برنامه میتواند شما را شناسایی کند و ممکن است اطلاعات نمایهٔ شما را برای دیگران ارسال کند."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"حسگرهای بدن (مانند پایشگرهای ضربان قلب)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"به برنامه امکان میدهد به اطلاعات حسگرهایی که استفاده میکنید، دسترسی پیدا کند تا اندازهگیریهای مربوط به آنچه که درون بدنتان رخ میدهد، مانند ضربان قلب، را انجام دهد."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"به برنامه امکان میدهد به اطلاعات حسگرهایی که بر شرایط فیزیکی شما مانند ضربان قلبتان، نظارت دارند، دسترسی داشته باشد."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"خواندن جریان اجتماعی شما"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"به برنامه اجازه میدهد به بهروزرسانیهای اجتماعی از طرف شما و دوستان شما دسترسی پیدا کرده و آنها را همگامسازی کند. دقت کنید که هنگام اشتراکگذاری -- این ویژگی به برنامه اجازه میدهد ارتباطات بین شما و دوستان شما را در شبکههای اجتماعی، صرفنظر از محرمانه بودن آنها بخواند. توجه: این مجوز ممکن است در همه شبکههای اجتماعی اجرا نشود."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"نوشتن در جریان اجتماعی شما"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index d0c9bd91f02c..7566ec68a228 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"muokkaa omia yhteystietoja"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Antaa sovelluksen muuttaa laitteelle tallennettuja henkilökohtaisia tietoja, kuten nimeä ja yhteystietoja, tai lisätä niitä. Sovellus voi tunnistaa sinut ja lähettää profiilitietojasi muille."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"kehon anturit (kuten sykemittarit)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Antaa sovelluksen käyttää tietoja antureista, joita käytetään kehon toimintojen kuten sykkeen mittaamiseen."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Antaa sovelluksen käyttää kehosi tilaa seuraavien anturien tietoja, esimerkiksi sykettä."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lue sosiaalista streamia"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Antaa sovelluksen käyttää ja synkronoida sinun tai kavereidesi päivityksiä sosiaalisista palveluista. Mieti tarkkaan ennen tietojen jakamista: tämän luvan saaneet sovellukset voivat lukea sinun ja kavereidesi välisiä viestejä sosiaalisissa verkkopalveluissa huolimatta viestien arkaluonteisuudesta. Huom: tätä lupaa ei saa ottaa käyttöön kaikissa sosiaalisissa verkkopalveluissa."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"kirjoita sosiaaliseen streamiin"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> on valittu"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> poistettiin"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (työ)"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Poista näytön kiinnitys painamalla Edellinen- ja Yleistä-kohtaa samanaikaisesti pitkään."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Poista näytön kiinnitys painamalla Yleistä-kohtaa pitkään."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Poista näytön kiinnitys painamalla Edellinen- ja Viimeisimmät-kohtaa samanaikaisesti pitkään."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Poista näytön kiinnitys painamalla Viimeisimmät-kohtaa pitkään."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Näyttö on kiinnitetty. Irrottaminen ei ole sallittu organisaatiossasi."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Käytetäänkö näytön kiinnitystä?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"Näytön kiinnitys lukitsee näytön yhteen näkymään.\n\nVoit poistaa kiinnityksen painamalla Edellinen- ja Yleistä-kohtaa samanaikaisesti pitkään."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Näytön lukitus lukitsee näytön yhteen näkymään.\n\nVoit poistaa kiinnityksen painamalla Yleistä-kohtaa pitkään."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"Näytön kiinnitys lukitsee näytön yhteen näkymään.\n\nVoit poistaa kiinnityksen painamalla Edellinen- ja Viimeisimmät-kohtaa samanaikaisesti pitkään."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Näytön lukitus lukitsee näytön yhteen näkymään.\n\nVoit poistaa kiinnityksen painamalla Viimeisimmät-kohtaa pitkään."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"EI KIITOS"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"ALOITA"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Näyttö kiinnitetty"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index bd394ee4b179..45ceddee3dec 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"modifier votre fiche de contact"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permet à l\'application de modifier les données de profil enregistrées sur votre appareil, telles que votre nom et vos coordonnées, ou d\'en ajouter. Elle peut alors vous identifier et envoyer vos données de profil à des tiers."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"capteurs corporels (tels que les moniteurs de fréquence cardiaque)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Permet à l\'application d\'accéder aux données des capteurs utilisés pour mesurer des valeurs physiologiques, telles que votre fréquence cardiaque."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permet à l\'application d\'accéder aux données des capteurs qui surveillent votre condition physique, comme votre rythme cardiaque."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lire les flux de réseaux sociaux"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permet à l\'application d\'accéder à vos mises à jour sur les réseaux sociaux, ainsi qu\'à celles de vos amis, et de les synchroniser. Soyez prudent lorsque vous partagez de l\'information. Cette autorisation permet à l\'application de lire les communications entre vous et vos amis sur les réseaux sociaux, indépendamment de leur caractère confidentiel. Remarque : Il est possible que cette autorisation ne soit pas appliquée sur tous les réseaux sociaux."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"modifier vos flux de réseaux sociaux"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"« <xliff:g id="ITEM">%1$s</xliff:g> » a été sélectionné"</string> <string name="deleted_key" msgid="7659477886625566590">"« <xliff:g id="KEY">%1$s</xliff:g> » a été supprimé"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (travail)"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Pour annuler l\'épinglage de cet écran, maintenez enfoncées les touches Retour et Aperçu simultanément."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Pour annuler l\'épinglage de cet écran, maintenez enfoncée la touche Aperçu."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Pour annuler l\'épinglage de cet écran, appuyez de manière prolongée sur Retour et Aperçu simultanément."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Pour annuler l\'épinglage, appuyez de manière prolongée sur Aperçu."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"L\'écran est épinglé. Votre organisation n\'autorise pas l\'annulation d\'épinglage."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Utiliser l\'épinglage d\'écran?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"Lorsque vous épinglez l\'écran, celui-ci n\'affiche plus qu\'une seule vue.\n\nPour annuler l\'épinglage, maintenez le doigt sur Retour et Aperçu simultanément."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Lorsque vous épinglez l\'écran, celui-ci n\'affiche plus qu\'une seule vue.\n\nPour annuler l\'épinglage, maintenez le doigt sur Aperçu."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"Lorsque vous épinglez l\'écran, celui-ci n\'affiche plus qu\'une seule vue.\n\nPour annuler l\'épinglage, appuyez de manière prolongée sur Retour et Aperçu simultanément."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Lorsque vous épinglez l\'écran, celui-ci n\'affiche plus qu\'une seule vue.\n\nPour annuler l\'épinglage, appuyez de manière prolongée sur Aperçu."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"NON, MERCI"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"COMMENCER"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Écran épinglé"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 1fee6677e55b..627d2dbe7f63 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"modifier votre fiche de contact"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permet à l\'application de modifier les informations de profil stockées sur votre appareil, telles que votre nom et vos coordonnées, ou d\'en ajouter. Elle peut alors vous identifier et envoyer vos informations de profil à des tiers."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"capteurs corporels (tels que les cardiofréquencemètres)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Permet à l\'application d\'accéder aux données des capteurs utilisés pour mesurer des valeurs physiologiques, telles que votre fréquence cardiaque."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permet à l\'application d\'accéder aux données des capteurs qui contrôlent votre condition physique, comme votre rythme cardiaque."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lire votre flux de réseau social"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permet à l\'application d\'accéder à vos mises à jour sur les réseaux sociaux, ainsi qu\'à celles de vos amis, et de les synchroniser. Soyez prudent lorsque vous partagez des informations. Cette autorisation permet à l\'application de lire les communications entre vous et vos amis sur les réseaux sociaux, indépendamment de leur caractère confidentiel. Remarque : il est possible que cette autorisation ne soit pas appliquée sur tous les réseaux sociaux."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"écrire sur votre flux social"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"\"<xliff:g id="ITEM">%1$s</xliff:g>\" sélectionné"</string> <string name="deleted_key" msgid="7659477886625566590">"\"<xliff:g id="KEY">%1$s</xliff:g>\" supprimé"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (travail)"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Pour annuler l\'épinglage, appuyez de manière prolongée et simultanée sur \"Retour\" et \"Vue d\'ensemble\"."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Pour annuler l\'épinglage, appuyez de manière prolongée sur \"Vue d\'ensemble\"."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Pour annuler l\'épinglage, appuyez de manière prolongée et simultanée sur \"Retour\" et \"Aperçu\"."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Pour annuler l\'épinglage, appuyez de manière prolongée sur \"Aperçu\"."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"L\'écran est épinglé. L\'annulation de l\'épinglage n\'est pas autorisée par votre organisation."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Utiliser l\'épinglage d\'écran ?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"Lorsque vous épinglez l\'écran, celui-ci n\'affiche plus qu\'une seule vue.\n\nPour annuler l\'épinglage, appuyez de manière prolongée et simultanée sur \"Retour\" et \"Vue d\'ensemble\"."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Lorsque vous épinglez l\'écran, celui-ci n\'affiche plus qu\'une seule vue.\n\nPour annuler l\'épinglage, appuyez de manière prolongée sur \"Vue d\'ensemble\"."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"Lorsque vous épinglez l\'écran, celui-ci n\'affiche plus qu\'une seule vue.\n\nPour annuler l\'épinglage, appuyez de manière prolongée et simultanée sur \"Retour\" et \"Aperçu\"."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Lorsque vous épinglez l\'écran, celui-ci n\'affiche plus qu\'une seule vue.\n\nPour annuler l\'épinglage, appuyez de manière prolongée sur \"Aperçu\"."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"NON, MERCI"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"ACTIVER"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Écran épinglé."</string> diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml index dcc464bf1193..6e910d8a740e 100644 --- a/core/res/res/values-gl-rES/strings.xml +++ b/core/res/res/values-gl-rES/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"modificar tarxeta de contacto"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permite á aplicación cambiar ou engadir á información do perfil persoal almacenada no teu dispositivo, como o teu nome e información de contacto. Isto significa que a aplicación pode identificarte e enviar a información do teu perfil a outros usuarios."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"sensores de corpo (como monitores de ritmo cardíaco)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Permite á aplicación acceder a datos de sensores que utilizas para medir o que está pasando dentro do teu corpo, como o ritmo cardíaco."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite que a aplicación acceda aos datos dos sensores que controlan o teu estado físico, como o ritmo cardíaco."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ler a túa actividade social"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permite á aplicación acceder ás túas actualizacións nas redes sociais, e sincronizalas, e ás dos teus amigos. Ten coidado ao compartir información (esta acción permite á aplicación ler comunicacións entre ti e os teus amigos efectuadas a través das redes sociais, independentemente da súa confidencialidade). Nota: É posible que este permiso non se execute en todas as redes sociais."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escribir na túa actividade social"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> seleccionado"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> do traballo"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Para soltar a pantalla, mantén premido Atrás e Vista xeral ao mesmo tempo."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Para soltar a pantalla, mantén premido Vista xeral."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Para soltar a pantalla, mantén premido Atrás e Visión xeral ao mesmo tempo."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Para soltar a pantalla, mantén premido Visión xeral."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"A pantalla está fixada. A túa organización non permite desactivar a pantalla."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Queres usar a fixación de pantalla?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"A fixación de pantalla bloquea a pantalla nunha única vista.\n\nPara soltar a pantalla, mantén premido Atrás e Vista xeral ao mesmo tempo."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"A fixación de pantalla bloquea a pantalla nunha única vista.\n\nPara soltar a pantalla, mantén premido e Vista xeral."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"A fixación de pantalla bloquea a pantalla nunha única vista.\n\nPara soltar a pantalla, mantén premido Atrás e Visión xeral ao mesmo tempo."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"A fixación de pantalla bloquea a pantalla nunha única vista.\n\nPara soltar a pantalla, mantén premido e Visión xeral."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"NON, GRAZAS"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"SI"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fixada"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 21820aae0655..66670f2676e9 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"स्वयं का संपर्क कार्ड बदलें"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ऐप्स को आपके डिवाइस में संग्रहीत निजी प्रोफ़ाइल जानकारी, जैसे आपका नाम और संपर्क जानकारी को बदलने या उसमें कुछ जोड़ने देता है. इसका अर्थ है कि ऐप्स आपको पहचान सकता है और आपकी प्रोफ़ाइल जानकारी अन्य लोगों को भेज सकता है."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"बॉडी सेंसर (जैसे हृदय गति मॉनीटर)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"ऐप्लिकेशन को ऐसे सेंसर का डेटा एक्सेस करने देती है जिनका उपयोग आप यह मापने के लिए करते हैं कि आपके शरीर के भीतर क्या चल रहा है, जैसे हृदय गति."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ऐप को आपकी शारीरिक स्थिति, जैसे आपकी हृदय गति पर नज़र रखने वाले संवेदकों का डेटा एक्सेस करने देती है."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"अपनी सामाजिक स्ट्रीम पढ़ें"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"एप को आपके और आपके मित्रों की नई सामाजिक जानकारी तक पहुंचने और उन्हें समन्वयित करने देता है. जानकारी साझा करते समय सावधान रहें - इससे गोपनीयता पर ध्यान दिए बिना, एप सामाजिक नेटवर्क पर आपके और आपके मित्रों के बीच संचारों को पढ़ सकता है. ध्यान दें: यह अनुमति सभी सामाजिक नेटवर्क पर लागू नहीं की जा सकती."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"सामाजिक स्ट्रीम में लिखें"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> चयनित"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> को हटा दिया गया"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"कार्यस्थल का <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"इस स्क्रीन को अनपिन करने के लिए, एक ही समय में वापस जाएं और ओवरव्यू को स्पर्श करके रखें."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"इस स्क्रीन को अनपिन करने के लिए, ओवरव्यू को स्पर्श करके रखें."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"इस स्क्रीन को अनपिन करने के लिए, एक ही समय में वापस जाएं और अवलोकन को स्पर्श करके रखें."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"इस स्क्रीन को अनपिन करने के लिए, अवलोकन को स्पर्श करके रखें."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"स्क्रीन पिन की गई है. आपके संगठन के द्वारा अनपिन करने की अनुमति नहीं है."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"स्क्रीन पिन करने का उपयोग करें?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"स्क्रीन पिनिंग एकल दृश्य में डिस्प्ले को लॉक कर देती है.\n\nअनपिन करने के लिए, एक ही समय में वापस जाएं और ओवरव्यू स्पर्श करके रखें."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"स्क्रीन पिनिंग एकल दृश्य में डिस्प्ले को लॉक कर देती है.\n\nअनपिन करने के लिए, ओवरव्यू को स्पर्श करके रखें."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"स्क्रीन पिनिंग एकल दृश्य में डिस्प्ले को लॉक कर देती है.\n\nअनपिन करने के लिए, एक ही समय में वापस जाएं और अवलोकन स्पर्श करके रखें."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"स्क्रीन पिनिंग एकल दृश्य में डिस्प्ले को लॉक कर देती है.\n\nअनपिन करने के लिए, अवलोकन को स्पर्श करके रखें."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"रहने दें"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"प्रारंभ करें"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"स्क्रीन पिन की गई"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index aa93037f2642..fcdef47dc584 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"izmjena vaše kontaktne kartice"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Aplikaciji omogućuje promjenu ili dodavanje osobnih podataka profila pohranjenih na uređaju, kao što su vaše ime i kontaktni podaci. To znači da vas aplikacija može identificirati i slati informacije s vašeg profila drugima."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"senzori tjelesnih funkcija (npr. monitori otkucaja srca)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Aplikaciji omogućuje pristup podacima iz senzora koje upotrebljavate za mjerenje onoga što se odvija u vašem tijelu, poput otkucaja srca."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Omogućuje aplikaciji pristup podacima sa senzora koji nadziru vaše fizičko stanje, na primjer, broj otkucaja srca."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"čitanje društvenog streama"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Aplikaciji omogućuje pristup vašim ažuriranjima na društvenim mrežama i ažuriranjima vaših prijatelja, kao i sinkronizaciju tih ažuriranja. Budite oprezni kad dijelite informacije – to aplikaciji omogućuje čitanje poruka između vas i vaših prijatelja na društvenim mrežama, neovisno o povjerljivosti. Napomena: ta se dozvola možda ne primjenjuje na svim društvenim mrežama."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"pisanje društvenog streama"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index a39e2f0d7e1f..f676da459271 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"saját névjegykártya módosítása"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Lehetővé teszi az alkalmazás számára az eszközön tárolt személyes profiladatok, például a név és az elérhetőségek módosítását vagy hozzáadását. Ez azt jelenti, hogy az alkalmazás azonosíthatja Önt, és elküldheti másoknak profiladatait."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"testérzékelők (pl. pulzusmérő)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Lehetővé teszi, hogy az alkalmazás hozzáférjen az olyan érzékelők által észlelt adatokhoz, amelyek az Ön életfunkcióit – például a pulzusszámát – figyelik."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Engedélyezi az alkalmazásnak, hogy hozzáférjen az Ön fizikai állapotát – például a pulzusszámát – figyelő érzékelők adataihoz."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"közösségi adatfolyam olvasása"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Lehetővé teszi az alkalmazás számára, hogy hozzáférjen az Ön és ismerősei közösségi oldalakon szereplő frissítéseihez. Legyen elővigyázatos, amikor információt tesz közzé -- így az alkalmazás hozzáférhet az ismerőseivel a közösségi hálózatokon folytatott magánbeszélgetésekhez, a tartalom titkos jellegétől függetlenül. Megjegyzés: előfordulhat, hogy ez nincs minden közösségi hálózaton engedélyezve."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"írás a közösség adatfolyamra"</string> diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml index a40ade993c47..a53ea2850321 100644 --- a/core/res/res/values-hy-rAM/strings.xml +++ b/core/res/res/values-hy-rAM/strings.xml @@ -472,7 +472,7 @@ <string name="permlab_writeGservices" msgid="2149426664226152185">"փոփոխել Google ծառայությունների քարտեզը"</string> <string name="permdesc_writeGservices" msgid="1287309437638380229">"Թույլ է տալիս հավելվածին փոփոխել Google-ի ծառայությունների քարտեզը: Սովորական հավելվածների օգտագործման համար չէ:"</string> <string name="permlab_receiveBootCompleted" msgid="5312965565987800025">"աշխատել մեկնարկային ռեժիմով"</string> - <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Թույլ է տալիս հավելվածին ինքնուրույն մեկնարկել համակարգի բեռնման ավարտից հետո: Սա կարող է երկարացնել գրասալիկի մեկնարկը և թույլ տալ հավելավածին դանդաղեցնել ամբողջ գրասալիկի աշխատանքը` միշտ աշխատելով:"</string> + <string name="permdesc_receiveBootCompleted" product="tablet" msgid="7390304664116880704">"Թույլ է տալիս հավելվածին ինքնաշխատ մեկնարկել համակարգի բեռնման ավարտից հետո: Սա կարող է երկարացնել գրասալիկի մեկնարկը և թույլ տալ հավելավածին դանդաղեցնել ամբողջ գրասալիկի աշխատանքը` միշտ աշխատելով:"</string> <string name="permdesc_receiveBootCompleted" product="default" msgid="513950589102617504">"Թույլ է տալիս հավելվածին ինքն իրեն սկսել` համակարգի բեռնումն ավարտվելուն պես: Սա կարող է հեռախոսի մեկնարկը դարձնել ավելի երկար և թույլ տալ, որ հավելվածը դանդաղեցնի ընդհանուր հեռախոսի աշխատանքը` միշտ աշխատելով:"</string> <string name="permlab_broadcastSticky" msgid="7919126372606881614">"ուղարկել կպչուն հաղորդում"</string> <string name="permdesc_broadcastSticky" product="tablet" msgid="7749760494399915651">"Թույլ է տալիս հավելվածին ուղարկել կպչուն հաղորդումներ, որոնք մնում են հաղորդման ավարտից հետո: Չափազանց շատ օգտագործումը կարող է գրասալիկի աշխատանքը դանդաղեցնել կամ դարձնել անկայուն` պատճառ դառնալով չափազանց մեծ հիշողության օգտագործման:"</string> @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"փոփոխել ձեր սեփական կոնտակտային քարտը"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Թույլ է տալիս հավելվածին փոխել կամ ավելացնել ձեր սարքում պահված անհատական պրոֆիլի տվյալները, ինչպիսիք են ձեր անունը և կոնտակտային տվյալները: Սա նշանակում է, որ հավելվածը կարող է ձեզ ճանաչել և ուղարկել ձեր պրոֆիլի տվյալները ուրիշներին:"</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"մարմնի սենսորներ (օր.` սրտի)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Ծրագրին թույլ է տալիս մատչել ձեր կողմից օգտագործվող սենսորների տվյալները՝ չափելու, թե ինչ է տեղի ունենում ձեր մարմնի ներսում, ինչպես օրինակ՝ սրտի զարկերը:"</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Հավելվածին թույլ է տալիս մուտք ունենալ սենսորների տվյալներին, որոնք վերահսկում են ձեր ֆիզիկական վիճակը, օրինակ՝ ձեր սրտի զարկերը:"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"կարդալ ձեր սոցիալական հոսքը"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Թույլ է տալիս հավելվածին մուտք գործել և համաժամեցնել ձեր և ձեր ընկերների սոցիալական թարմացումները: Զգույշ եղեք տեղեկություններ տարածելիս. այն թույլ է տալիս հավելվածին կարդալ ձեր և ձեր ընկերների միջև անձնական հաղորդագրությունները սոցիալական ցանցերում` անկախ գաղտնիությունից: Նշում. այս թույլտվությունը չի կարող գործածվել բոլոր սոցիալական ցանցերում:"</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"գրել ձեր սոցիալական հոսքում"</string> @@ -1758,7 +1758,7 @@ <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> թիվը ջնջված է"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"Աշխատանքային <xliff:g id="LABEL">%1$s</xliff:g>"</string> <string name="lock_to_app_toast" msgid="7570091317001980053">"Այս էկրան ապամրացնելու համար միաժամանակ հպեք և պահեք Հետ և Համատեսք կոճակները:"</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Այս էկրան ապամրացնելու համար հպեք և պահեք Համատեսքի կոճակին:"</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Այս էկրանն ապամրացնելու համար հպեք և պահեք Համատեսքի կոճակը:"</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Էկրանն ամրացված է: Ապամրացումը չի թույլատրվում ձեր կազմակերպության կողմից:"</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Օգտագործե՞լ էկրանի ամրացումը:"</string> <string name="lock_to_app_description" msgid="4120623404152035221">"Էկրանի ամրացումը կողպում է էկրանը ընթացիկ տեսքով:\n\nԱպամրացնելու համար միաժամանակ հպեք և պահեք Հետ և Համատեսք կոճակները:"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index a7207474b806..ab5ff0d19568 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"ubah kartu kontak Anda"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Memungkinkan aplikasi mengubah atau menambah informasi profil pribadi yang tersimpan di perangkat Anda, seperti nama dan informasi kontak. Ini berarti aplikasi tersebut dapat mengenali Anda dan mengirim informasi profil Anda ke orang lain."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"sensor tubuh (misal: monitor detak jantung)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Memungkinkan aplikasi mengakses data dari sensor yang Anda gunakan untuk mengukur yang terjadi di dalam tubuh, misalnya detak jantung."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Mengizinkan aplikasi untuk mengakses data dari sensor yang memantau kondisi fisik Anda, seperti denyut jantung."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"membaca aliran sosial Anda"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Memungkinkan aplikasi mengakses dan menyinkronkan pembaruan sosial dari Anda dan teman. Hati-hati ketika berbagi informasi -- izin ini memungkinkan aplikasi membaca komunikasi antara Anda dan teman di jejaring sosial, terlepas dari kerahasiaan. Catatan: izin ini tidak dapat diberlakukan di semua jejaring sosial."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"menulis ke aliran sosial Anda"</string> @@ -1492,7 +1492,7 @@ <string name="add_account_button_label" msgid="3611982894853435874">"Tambahkan akun"</string> <string name="number_picker_increment_button" msgid="2412072272832284313">"Tambah"</string> <string name="number_picker_decrement_button" msgid="476050778386779067">"Kurangi"</string> - <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> sentuh dan tahan."</string> + <string name="number_picker_increment_scroll_mode" msgid="3073101067441638428">"<xliff:g id="VALUE">%s</xliff:g> sentuh lama."</string> <string name="number_picker_increment_scroll_action" msgid="9101473045891835490">"Geser ke atas untuk menambah dan ke bawah untuk mengurangi."</string> <string name="time_picker_increment_minute_button" msgid="8865885114028614321">"Tambah menit"</string> <string name="time_picker_decrement_minute_button" msgid="6246834937080684791">"Kurangi menit"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> dipilih"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> dihapus"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"Kantor <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Untuk melepas pin layar ini, sentuh dan tahan tombol Kembali dan Ikhtisar secara bersamaan."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Untuk melepas pin layar ini, sentuh dan tahan tombol Ikhtisar."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Untuk melepas pin layar ini, sentuh lama tombol Kembali dan Ringkasan secara bersamaan."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Untuk melepas pin layar ini, sentuh lama tombol Ringkasan."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Layar disematkan. Pelepasan sematan tidak diizinkan oleh organisasi Anda."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Gunakan penyematan layar?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"Pemasangan pin pada layar mengunci layar dalam satu tampilan.\n\nUntuk melepas pin, sentuh dan tahan tombol Kembali dan Ikhtisar secara bersamaan."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Pemasangan pin pada layar mengunci layar dalam satu tampilan.\n\nUntuk melepas pin, sentuh dan tahan tombol Ikhtisar."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"Pemasangan pin pada layar mengunci layar dalam satu tampilan.\n\nUntuk melepas pin, sentuh lama tombol Kembali dan Ringkasan secara bersamaan."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Pemasangan pin pada layar mengunci layar dalam satu tampilan.\n\nUntuk melepas pin, sentuh lama tombol Ringkasan."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"TIDAK, TERIMA KASIH"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"MULAI"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Layar disematkan"</string> diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml index 02cfa67ac7c9..1735136f5fe2 100644 --- a/core/res/res/values-is-rIS/strings.xml +++ b/core/res/res/values-is-rIS/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"breyta tengiliðaspjaldinu þínu"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Leyfir forriti að breyta eða bæta við persónulegum prófílupplýsingum sem vistaðar eru í tækinu, t.d. nafni og samskiptaupplýsingum. Þetta þýðir að forritið veit hver þú ert og getur sent prófílupplýsingarnar þínar til annarra."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"líkamsskynjarar (s.s. hjartsláttarmælar)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Leyfir forriti að fá aðgang að gögnum frá skynjurum sem þú notar til að mæla líkamsstarfsemi þína, svo sem hjartslátt."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Veitir forritinu aðgang að gögnum frá skynjurum sem fylgjast með líkamsstarfsemi þinni, svo sem hjartslætti."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lesa samfélagsstrauminn þinn"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Leyfir forriti að fá aðgang að og samstilla samfélagsuppfærslur þínar og vina þinna. Sýndu aðgát þegar þú deilir upplýsingum; þetta gerir forritinu kleift að lesa samskipti þín og vina þinna í netsamfélögum. Athugaðu: Ekki er víst að þessi heimild sé virt í öllum netsamfélögum."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skrifa í samfélagsstrauminn þinn"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 7778b9310df5..df6980942f07 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"modifica scheda contatti"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Consente all\'applicazione di modificare o aggiungere informazioni ai dati del profilo personale memorizzati sul dispositivo, come il tuo nome e le tue informazioni di contatto. Significa che l\'applicazione può identificarti e inviare le informazioni del tuo profilo ad altri."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"sensori per il corpo (come il cardiofrequenzimetro)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Consente all\'app di accedere a dati derivanti dai sensori utilizzati per rilevare cosa sta accadendo nel tuo corpo, ad esempio la frequenza cardiaca."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Consente all\'app di accedere ai dati relativi ai sensori che monitorano le tue condizioni fisiche, ad esempio la frequenza cardiaca."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lettura del tuo stream sociale"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Consente all\'applicazione di accedere agli aggiornamenti dei social network tra te e i tuoi amici e di sincronizzarli. Fai attenzione quando condividi informazioni: questa autorizzazione consente all\'applicazione di leggere le comunicazioni tra te e i tuoi amici sui social network, indipendentemente dal livello di riservatezza. Nota. È possibile che questa autorizzazione non sia applicabile su tutti i social network."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"scrittura nel tuo stream sociale"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 074f252f814b..8e4e2abc4f6a 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"שינוי כרטיס איש הקשר שלך"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"מאפשר לאפליקציה לשנות או להוסיף נתונים לפרטי הפרופיל האישי המאוחסנים במכשיר, כגון שמך ופרטי הקשר שלך. משמעות הדבר שהאפליקציה יכולה לזהות אותך ועשוי לשלוח את פרטי הפרופיל שלך לאנשים אחרים."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"חיישני גוף (כמו מוניטורים עבור קצב לב)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"מאפשר לאפליקציה לגשת לנתוני חיישנים שבהם אתה משתמש כדי למדוד פעילות המתרחשת בתוך הגוף, כמו קצב לב."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"מאפשר לאפליקציה לגשת אל נתוני חיישנים העוקבים אחר מצבך הגופני, כמו קצב הלב."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"קריאת הזרם החברתי שלך"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"מאפשר לאפליקציה גישה ויכולת סנכרון של עדכונים חברתיים שאתה וחבריך מבצעים. היזהר בעת שיתוף מידע -- הדבר מתיר לאפליקציה לקרוא התכתבויות בינך ובין חבריך ברשתות חברתיות, ללא התחשבות בסודיות. שים לב: ייתכן שאישור זה לא נאכף בכל הרשתות החברתיות."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"כתיבה בזרם החברתי שלך"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index b0fa67d12d20..e20947d8f70d 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"自分の連絡先カードの変更"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"端末に保存されている個人のプロフィール情報(名前、連絡先情報など)の変更と追加をアプリに許可します。これにより、アプリがユーザーの身元を特定できるようになり、プロフィール情報を第三者に転送する可能性があります。"</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"ボディーセンサー(心拍数モニターなど)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"心拍数など、体内の変化の測定に使用するセンサーからのデータにアクセスすることをアプリに許可します。"</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"心拍数など、身体状態を監視するセンサーからのデータにアクセスすることをアプリに許可します。"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ソーシャルストリームを読む"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"あなたや友だちのソーシャル更新情報へのアクセスと同期をアプリに許可します。情報の共有は慎重に行ってください。これを許可すると、あなたと友だちがソーシャルネットワークで行ったやり取りを、機密性に関係なくアプリから読み取ることができるようになります。注: この許可は、一部のソーシャルネットワークでは適用されない場合があります。"</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ソーシャルストリームに書く"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g>を選択しました"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g>を削除しました"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"仕事の<xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"この画面の固定を解除するには[戻る]と[概要]を同時に押し続けます。"</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"この画面の固定を解除するには[概要]を押し続けます。"</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"この画面の固定を解除するには[戻る]と[最近]を同時に押し続けます。"</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"この画面の固定を解除するには[最近]を押し続けます。"</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"画面が固定されています。会社/組織により解除は許可されていません。"</string> <string name="lock_to_app_title" msgid="1682643873107812874">"画面固定を使用しますか?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"画面の固定では、1つの画面が表示されたままになります。\n\n解除するには、[戻る]と[概要]を同時に押し続けます。"</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"画面の固定では、1つの画面が表示されたままになります。\n\n解除するには、[概要]を押し続けます。"</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"画面の固定では、1つの画面が表示されたままになります。\n\n解除するには、[戻る]と[最近]を同時に押し続けます。"</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"画面の固定では、1つの画面が表示されたままになります。\n\n解除するには、[最近]を押し続けます。"</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"いいえ"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"開始する"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"画面を固定しました"</string> diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml index 27f9fbdd9f32..6765fd24b456 100644 --- a/core/res/res/values-ka-rGE/strings.xml +++ b/core/res/res/values-ka-rGE/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"თქვენი საკონტაქტო ინფორმაციის შეცვლა"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"აპს შეეძლება მოწყობილობაზე შენახული პირადი პროფილის ინფორმაციის შეცვლა ან დამატება, მაგალითად, თქვენი სახელისა და საკონტაქტო ინფორმაციის. ეს ნიშნავს, რომ აპს შეუძლია თქვენი იდენტიფიცირება და თქვენი პირადი ინფორმაციის სხვებისთვის გაგზავნა."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"სხეულის სენსორები (მაგ. გულისცემის მონიტორები)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"საშუალებას აძლევს აპს იქონიოს წვდომა თქვენ მიერ გამოყენებული სენსორებიდან, რათა გაზომოთ, რა ხდება თქვენ სხეულში, მაგ. გულის ცემის რითმი."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"აპისთვის ნების დართვა იქონიოს წვდომა თქვენი ფიზიკური მდგომარეობის მონიტორინგის სენსორების მონაცემებზე."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"სოციალური ნაკადის წაკითხვა"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"აპს შეეძლება თქვენი და თქვენი მეგობრების სოციალური განახლებებთან წვდომა და სინქრონიზაცია. ინფორმაციის გაზიარებისას იყავით ფრთხიად - აპს ექნება შესაძლებლობა, რომ წაიკითხოს სოციალურ ქსელებში კომუნიკაცია თქვენსა და თქვენს მეგობრებს შორის კონფიდენციალურობის მიუხედავად. შენიშვნა: ეს უფლება შესაძლოა ვერ იყოს გამოყენებული ყველა სოციალურ ქსელში."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"თქვენს სოციალურ მაუწყებლობაზე დაწერა"</string> diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml index 7bfafe64f7e9..d698acda4b17 100644 --- a/core/res/res/values-kk-rKZ/strings.xml +++ b/core/res/res/values-kk-rKZ/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"өзіңіздің байланыс картаңызды өзгерту"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Қолданбаға құрылғыда сақталған сіздің аты-жөніңіз және байланыс ақпаратыңыз сияқты жеке ақпаратты өзгерту немесе қосу мүмкіндігін береді. Бұл - қолданба сізді анықтап, сіз туралы жеке ақпаратты басқаларға жібере алады дегенді білдіреді."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"дене сен-ры (жүрек соғу жиіл. мон-ры сияқты)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Қолданбаларға сіз жүрек соғу жиілігі сияқты дене ішінде болып жатқан нәрселерді өлшеу үшін пайдаланатын сенсорлардан алынған деректерге қатынасуға рұқсат береді."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Қолданбаға жүрек соғу жиілігіңіз сияқты дене күйіңізді бақылайтын сенсорлардың деректеріне қатынасуға рұқсат етеді."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"әлеуметтік ағымды оқу"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Қолданбаға сіз және достарыңыздың әлеуметтік жаңартуларына кіру және синхрондау мүмкіндігін береді. Ақпарат бөліскенде абай болыңыз -- бұл қолданбаға сіз және достарыңызды әлеуметтік желілердегі қарым-қатынасты, құпиялығына қарамастан, оқу мүмкіндігін берді. Есіңізде болсын: бұл рұқсатты барлық әлеуметтік желілер қолданбайды."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"әлеуметтік ағынға жазу"</string> diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml index 19f31ae9b805..a0fd3e7c1dca 100644 --- a/core/res/res/values-km-rKH/strings.xml +++ b/core/res/res/values-km-rKH/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"កែកាតទំនាក់ទំនងផ្ទាល់ខ្លួនរបស់អ្នក"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ឲ្យកម្មវិធីប្ដូរ ឬបន្ថែមព័ត៌មានប្រវត្តិរូបផ្ទាល់ខ្លួនដែលបានរក្សាទុកក្នុងឧបករណ៍របស់អ្នក ដូចជា ឈ្មោះ និងព័ត៌មានទំនាក់ទំនងរបស់អ្នក។ នេះមានន័យថាកម្មវិធីអាចកំណត់អ្នក និងផ្ញើព័ត៌មានប្រវត្តិរូបរបស់អ្នកទៅអ្នកផ្សេង។"</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"ឧបករណ៍ចាប់សញ្ញារាងកាយ(ដូចជាម៉ាស៊ីនវាស់ចង្វាក់បេះដូង)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"ឲ្យកម្មវិធីដើម្បីចូលដំណើរការទិន្នន័យពីឧបករណ៍ចាប់សញ្ញាដែលអ្នកប្រើ ដើម្បីវាស់ពីអ្វីដែលកំពុងកើតឡើងនៅខាងក្នុងខ្លួនរបស់អ្នកដូចជាចង្វាក់បេះដូង។"</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ឲ្យកម្មវិធីចូលដំណើរការទិន្នន័យពីឧបករណ៍ចាប់សញ្ញាដែលតាមដានលក្ខខណ្ឌសុខភាពរបស់អ្នក ដូចជាចង្វាក់បេះដូង។"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"អានចរន្តសង្គមរបស់អ្នក"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ឲ្យកម្មវិធីចូលដំណើរការ និងធ្វើសមកាលកម្មបច្ចុប្បន្នភាពសង្គមពីអ្នក និងមិត្តភ័ក្ដិ។ ប្រយ័ត្នពេលចែករំលែកព័ត៌មាន វាអនុញ្ញាតឲ្យកម្មវិធីអានការទាក់ទងរវាងអ្នក និងមិត្តភ័ក្ដិលើបណ្ដាញសង្គម ទាក់ទងនឹងព័ត៌មានសម្ងាត់។ ចំណាំ៖ សិទ្ធិនេះមិនអាចត្រូវបានអនុវត្តលើបណ្ដាញសង្គមទាំងអស់បានទេ។"</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"សរសេរទៅចរន្តសង្គមរបស់អ្នក"</string> @@ -1615,7 +1615,7 @@ <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"កូដ PIN មិនដូចគ្នា"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ព្យាយាមលំនាំច្រើនពេក"</string> <string name="kg_login_instructions" msgid="1100551261265506448">"ដើម្បីដោះសោ ចូលក្នុងគណនី Google ។"</string> - <string name="kg_login_username_hint" msgid="5718534272070920364">"ឈ្មោះអ្នកប្រើ (អ៊ីម៉ែល)"</string> + <string name="kg_login_username_hint" msgid="5718534272070920364">"ឈ្មោះអ្នកប្រើ (អ៊ីមែល)"</string> <string name="kg_login_password_hint" msgid="9057289103827298549">"ពាក្យសម្ងាត់"</string> <string name="kg_login_submit_button" msgid="5355904582674054702">"ចូល"</string> <string name="kg_login_invalid_input" msgid="5754664119319872197">"ឈ្មោះអ្នកប្រើ ឬពាក្យសម្ងាត់មិនត្រឹមត្រូវ។"</string> diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml index ea9db0c6d654..8692a4f6a7c7 100644 --- a/core/res/res/values-kn-rIN/strings.xml +++ b/core/res/res/values-kn-rIN/strings.xml @@ -54,17 +54,17 @@ <string name="serviceErased" msgid="1288584695297200972">"ಅಳಿಸುವಿಕೆ ಯಶಸ್ವಿಯಾಗಿದೆ."</string> <string name="passwordIncorrect" msgid="7612208839450128715">"ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್."</string> <string name="mmiComplete" msgid="8232527495411698359">"MMI ಪೂರ್ಣಗೊಂಡಿದೆ."</string> - <string name="badPin" msgid="9015277645546710014">"ನೀವು ಟೈಪ್ ಮಾಡಿದ ಹಳೆಯ PIN ಸರಿಯಾಗಿಲ್ಲ."</string> + <string name="badPin" msgid="9015277645546710014">"ನೀವು ಟೈಪ್ ಮಾಡಿದ ಹಳೆಯ ಪಿನ್ ಸರಿಯಾಗಿಲ್ಲ."</string> <string name="badPuk" msgid="5487257647081132201">"ನೀವು ಟೈಪ್ ಮಾಡಿದ PUK ಸರಿಯಾಗಿಲ್ಲ."</string> - <string name="mismatchPin" msgid="609379054496863419">"ನೀವು ಟೈಪ್ ಮಾಡಿದ PIN ಗಳು ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ."</string> - <string name="invalidPin" msgid="3850018445187475377">"4 ರಿಂದ 8 ಸಂಖ್ಯೆಗಳಿರುವ PIN ಟೈಪ್ ಮಾಡಿ."</string> + <string name="mismatchPin" msgid="609379054496863419">"ನೀವು ಟೈಪ್ ಮಾಡಿದ ಪಿನ್ ಗಳು ಹೊಂದಿಕೆಯಾಗುವುದಿಲ್ಲ."</string> + <string name="invalidPin" msgid="3850018445187475377">"4 ರಿಂದ 8 ಸಂಖ್ಯೆಗಳಿರುವ ಪಿನ್ ಟೈಪ್ ಮಾಡಿ."</string> <string name="invalidPuk" msgid="8761456210898036513">"8 ಅಥವಾ ಅದಕ್ಕಿಂತ ಹೆಚ್ಚು ಸಂಖ್ಯೆಗಳಿರುವ PUK ಟೈಪ್ ಮಾಡಿ."</string> - <string name="needPuk" msgid="919668385956251611">"ನಿಮ್ಮ SIM ಕಾರ್ಡ್ PUK-ಲಾಕ್ ಆಗಿದೆ. ಅದನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು PUK ಕೋಡ್ ಟೈಪ್ ಮಾಡಿ."</string> - <string name="needPuk2" msgid="4526033371987193070">"SIM ಕಾರ್ಡ್ ಅನ್ಲಾಕ್ ಮಾಡಲು PUK2 ಟೈಪ್ ಮಾಡಿ."</string> - <string name="enablePin" msgid="209412020907207950">"ಯಶಸ್ವಿಯಾಗಿಲ್ಲ, SIM/RUIM ಲಾಕ್ ಸಕ್ರಿಯಗೊಳಿಸಿ."</string> + <string name="needPuk" msgid="919668385956251611">"ನಿಮ್ಮ ಸಿಮ್ ಕಾರ್ಡ್ PUK-ಲಾಕ್ ಆಗಿದೆ. ಅದನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು PUK ಕೋಡ್ ಟೈಪ್ ಮಾಡಿ."</string> + <string name="needPuk2" msgid="4526033371987193070">"ಸಿಮ್ ಕಾರ್ಡ್ ಅನ್ಲಾಕ್ ಮಾಡಲು PUK2 ಟೈಪ್ ಮಾಡಿ."</string> + <string name="enablePin" msgid="209412020907207950">"ಯಶಸ್ವಿಯಾಗಿಲ್ಲ, ಸಿಮ್/RUIM ಲಾಕ್ ಸಕ್ರಿಯಗೊಳಿಸಿ."</string> <plurals name="pinpuk_attempts"> - <item quantity="one" msgid="6596245285809790142">"SIM ಲಾಕ್ ಆಗುವುದಕ್ಕಿಂತ ಮೊದಲು ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರಯತ್ನ ಬಾಕಿ ಉಳಿದಿದೆ."</item> - <item quantity="other" msgid="7530597808358774740">"SIM ಲಾಕ್ ಆಗುವುದಕ್ಕೂ ಮೊದಲು ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ."</item> + <item quantity="one" msgid="6596245285809790142">"ಸಿಮ್ ಲಾಕ್ ಆಗುವುದಕ್ಕಿಂತ ಮೊದಲು ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರಯತ್ನ ಬಾಕಿ ಉಳಿದಿದೆ."</item> + <item quantity="other" msgid="7530597808358774740">"ಸಿಮ್ ಲಾಕ್ ಆಗುವುದಕ್ಕೂ ಮೊದಲು ನಿಮ್ಮಲ್ಲಿ <xliff:g id="NUMBER">%d</xliff:g> ಪ್ರಯತ್ನಗಳು ಬಾಕಿ ಉಳಿದಿವೆ."</item> </plurals> <string name="imei" msgid="2625429890869005782">"IMEI"</string> <string name="meid" msgid="4841221237681254195">"MEID"</string> @@ -76,7 +76,7 @@ <string name="CwMmi" msgid="9129678056795016867">"ಕರೆ ನಿರೀಕ್ಷೆ"</string> <string name="BaMmi" msgid="455193067926770581">"ಕರೆ ಬಾರಿಂಗ್"</string> <string name="PwdMmi" msgid="7043715687905254199">"ಪಾಸ್ವರ್ಡ್ ಬದಲಾವಣೆ"</string> - <string name="PinMmi" msgid="3113117780361190304">"PIN ಬದಲಾವಣೆ"</string> + <string name="PinMmi" msgid="3113117780361190304">"ಪಿನ್ ಬದಲಾವಣೆ"</string> <string name="CnipMmi" msgid="3110534680557857162">"ಕರೆ ಮಾಡುತ್ತಿರುವ ಸಂಖ್ಯೆಯು ಅಸ್ತಿತ್ವದಲ್ಲಿದೆ"</string> <string name="CnirMmi" msgid="3062102121430548731">"ಕರೆ ಮಾಡುವ ಸಂಖ್ಯೆಯನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string> <string name="ThreeWCMmi" msgid="9051047170321190368">"ಮೂರು ಮಾರ್ಗದಲ್ಲಿ ಕರೆ ಮಾಡುವಿಕೆ"</string> @@ -289,11 +289,11 @@ <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"ಸಂದೇಶದ ಈವೆಂಟ್ಗಳ ಮೂಲಕ ಪ್ರತಿಕ್ರಿಯೆ ಕಳುಹಿಸಿ"</string> <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"ಒಳಬರುವ ಕರೆಗಳಿಗಾಗಿ ಸಂದೇಶದ ಈವೆಂಟ್ಗಳ ಮೂಲಕ ಪ್ರತಿಕ್ರಿಯೆಯನ್ನು ನಿರ್ವಹಿಸುವ ಸಲುವಾಗಿ ಇತರ ಸಂದೇಶದ ಅಪ್ಲಿಕೇಶನ್ಗಳಿಗೆ ವಿನಂತಿಗಳನ್ನು ಕಳುಹಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> <string name="permlab_readSms" msgid="8745086572213270480">"ನಿಮ್ಮ ಪಠ್ಯ ಸಂದೇಶಗಳನ್ನು ಓದಿ (SMS ಅಥವಾ MMS)"</string> - <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಅಥವಾ SIM ಕಾರ್ಡ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾದ SMS ಸಂದೇಶಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು ವಿಷಯ ಅಥವಾ ಗೌಪ್ಯತೆಯನ್ನು ಲೆಕ್ಕಿಸದೆಯೇ, ಎಲ್ಲಾ SMS ಸಂದೇಶಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> - <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"ನಿಮ್ಮ ಫೋನ್ ಅಥವಾ SIM ಕಾರ್ಡ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾದ SMS ಸಂದೇಶಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು ವಿಷಯ ಅಥವಾ ಗೌಪ್ಯತೆಯನ್ನು ಲೆಕ್ಕಿಸದೆಯೇ, ಎಲ್ಲಾ SMS ಸಂದೇಶಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> + <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಅಥವಾ ಸಿಮ್ ಕಾರ್ಡ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾದ SMS ಸಂದೇಶಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು ವಿಷಯ ಅಥವಾ ಗೌಪ್ಯತೆಯನ್ನು ಲೆಕ್ಕಿಸದೆಯೇ, ಎಲ್ಲಾ SMS ಸಂದೇಶಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> + <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"ನಿಮ್ಮ ಫೋನ್ ಅಥವಾ ಸಿಮ್ ಕಾರ್ಡ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾದ SMS ಸಂದೇಶಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು ವಿಷಯ ಅಥವಾ ಗೌಪ್ಯತೆಯನ್ನು ಲೆಕ್ಕಿಸದೆಯೇ, ಎಲ್ಲಾ SMS ಸಂದೇಶಗಳನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> <string name="permlab_writeSms" msgid="3216950472636214774">"ನಿಮ್ಮ ಪಠ್ಯ ಸಂದೇಶಗಳನ್ನು ಸಂಪಾದಿಸಿ (SMS ಅಥವಾ MMS)"</string> - <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಅಥವಾ SIM ಕಾರ್ಡ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ SMS ಸಂದೇಶಗಳನ್ನು ಬರೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಸಂದೇಶಗಳನ್ನು ಅಳಿಸಬಹುದು."</string> - <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"ನಿಮ್ಮ ಫೋನ್ ಅಥವಾ SIM ಕಾರ್ಡ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾದ SMS ಸಂದೇಶಗಳಲ್ಲಿ ಬರೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಸಂದೇಶಗಳನ್ನು ಅಳಿಸಬಹುದು."</string> + <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಅಥವಾ ಸಿಮ್ ಕಾರ್ಡ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ SMS ಸಂದೇಶಗಳನ್ನು ಬರೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಸಂದೇಶಗಳನ್ನು ಅಳಿಸಬಹುದು."</string> + <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"ನಿಮ್ಮ ಫೋನ್ ಅಥವಾ ಸಿಮ್ ಕಾರ್ಡ್ನಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾದ SMS ಸಂದೇಶಗಳಲ್ಲಿ ಬರೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ದುರುದ್ದೇಶಪೂರಿತ ಅಪ್ಲಿಕೇಶನ್ಗಳು ನಿಮ್ಮ ಸಂದೇಶಗಳನ್ನು ಅಳಿಸಬಹುದು."</string> <string name="permlab_receiveWapPush" msgid="5991398711936590410">"ಪಠ್ಯ ಸಂದೇಶಗಳನ್ನು ಸ್ವೀಕರಿಸಿ (WAP)"</string> <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP ಸಂದೇಶಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಮತ್ತು ಪ್ರಕ್ರಿಯೆಗೊಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು, ನಿಮಗೆ ಕಳುಹಿಸಲಾಗಿರುವ ಸಂದೇಶಗಳನ್ನು ನಿಮಗೆ ತೋರಿಸದೆಯೇ, ಅವುಗಳನ್ನು ಮಾನಿಟರ್ ಮಾಡುವ ಅಥವಾ ಅಳಿಸುವ ಸಾಮರ್ಥ್ಯವನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ."</string> <string name="permlab_receiveBluetoothMap" msgid="7593811487142360528">"ಬ್ಲೂಟೂತ್ ಸಂದೇಶಗಳನ್ನು ಸ್ವೀಕರಿಸಿ (MAP)"</string> @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"ನಿಮ್ಮದೇ ಸಂಪರ್ಕದ ಕಾರ್ಡ್ ಮಾರ್ಪಡಿಸಿ"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಸಂಗ್ರಹಿಸಲಾಗಿರುವ ನಿಮ್ಮ ಹೆಸರು ಹಾಗೂ ಸಂಪರ್ಕ ಮಾಹಿತಿಯಂತಹ, ವೈಯಕ್ತಿಕ ಪ್ರೊಫೈಲ್ ಮಾಹಿತಿಯನ್ನು ಬದಲಿಸಲು ಅಥವಾ ಸೇರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಅಂದರೆ, ಅಪ್ಲಿಕೇಶನ್ ನಿಮ್ಮನ್ನು ಗುರುತಿಸಬಹುದು ಮತ್ತು ನಿಮ್ಮ ಪ್ರೊಫೈಲ್ ಮಾಹಿತಿಯನ್ನು ಇತರರಿಗೆ ಕಳುಹಿಸಬಹುದು ಎಂದರ್ಥ."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"ದೇಹದ ಸಂವೇದಗಳು (ಹೃದಯದ ರೇಟ್ ಮಾನಿಟರ್ಗಳಂತಹ)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"ಹೃದಯ ಬಡಿತದಂತಹ, ನಿಮ್ಮ ದೇಹದಲ್ಲಿ ಏನು ನಡೆಯುತ್ತಿದೆ ಎಂಬುದನ್ನು ಅಳತೆ ಮಾಡಲು ನೀವು ಬಳಸುವ ಸಂವೇದಕಗಳಿಂದ ಡೇಟಾ ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ನಿಮ್ಮ ಹೃದಯ ಬಡಿತದಂತಹ ನಿಮ್ಮ ದೈಹಿಕ ಸ್ಥಿತಿಯನ್ನು ಮೇಲ್ವಿಚಾರಣೆ ಮಾಡುವ ಸೆನ್ಸಾರ್ಸ್ಗಳಿಂದ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ ಅನ್ನು ಅನುಮತಿಸುತ್ತದೆ."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ನಿಮ್ಮ ಸಾಮಾಜಿಕ ಸ್ಟ್ರೀಮ್ ಓದಿರಿ"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ನೀವು ಮತ್ತು ನಿಮ್ಮ ಸ್ನೇಹಿತರ ಸಾಮಾಜಿಕ ನವೀಕರಣಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ಮತ್ತು ಸಿಂಕ್ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಮಾಹಿತಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳುವಾಗ ಜಾಗರೂಕರಾಗಿರಿ -- ಇದು ಗೌಪ್ಯತೆಯನ್ನು ಲೆಕ್ಕಿಸದೆಯೇ, ಸಾಮಾಜಿಕ ನೆಟ್ವರ್ಕ್ಗಳಲ್ಲಿ ನೀವು ಮತ್ತು ನಿಮ್ಮ ಸ್ನೇಹಿತರ ನಡುವೆ ನಡೆದಿರುವ ಸಂವಹನವನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಗಮನಿಸಿ: ಈ ಅನುಮತಿಯನ್ನು ಎಲ್ಲಾ ಸಾಮಾಜಿಕ ನೆಟ್ವರ್ಕ್ಗಳಲ್ಲಿ ಜಾರಿಗೊಳಿಸದೇ ಇರಬಹುದು."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ನಿಮ್ಮ ಸಾಮಾಜಿಕ ಸ್ಟ್ರೀಮ್ನಲ್ಲಿ ಬರೆಯಿರಿ"</string> @@ -521,10 +521,10 @@ <string name="permdesc_readFrameBuffer" msgid="4937405521809454680">"ಫ್ರೇಮ್ ಬಫರ್ ವಿಷಯವನ್ನು ಓದಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> <string name="permlab_accessInputFlinger" msgid="5348635270689553857">"InputFlinger ಪ್ರವೇಶಿಸಿ"</string> <string name="permdesc_accessInputFlinger" msgid="2104864941201226616">"InputFlinger ಕೆಳಮಟ್ಟದ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> - <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"Wifi ಪ್ರದರ್ಶನಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿ"</string> - <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"Wifi ಪ್ರದರ್ಶನಗಳಿಗೆ ಕಾನ್ಫಿಗರ್ ಮಾಡಲು ಮತ್ತು ಸಂಪರ್ಕಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string> - <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"Wifi ಪ್ರದರ್ಶನಗಳನ್ನು ನಿಯಂತ್ರಿಸಿ"</string> - <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"Wifi ಪ್ರದರ್ಶನಗಳ ಕೆಳ-ಮಟ್ಟದ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ನಿಯಂತ್ರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಕಲ್ಪಿಸುತ್ತದೆ."</string> + <string name="permlab_configureWifiDisplay" msgid="5595661694746742168">"ವೈಫೈ ಪ್ರದರ್ಶನಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿ"</string> + <string name="permdesc_configureWifiDisplay" msgid="7916815158690218065">"ವೈಫೈ ಪ್ರದರ್ಶನಗಳಿಗೆ ಕಾನ್ಫಿಗರ್ ಮಾಡಲು ಮತ್ತು ಸಂಪರ್ಕಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string> + <string name="permlab_controlWifiDisplay" msgid="393641276723695496">"ವೈಫೈ ಪ್ರದರ್ಶನಗಳನ್ನು ನಿಯಂತ್ರಿಸಿ"</string> + <string name="permdesc_controlWifiDisplay" msgid="4543912292681826986">"ವೈಫೈ ಪ್ರದರ್ಶನಗಳ ಕೆಳ-ಮಟ್ಟದ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ನಿಯಂತ್ರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಕಲ್ಪಿಸುತ್ತದೆ."</string> <string name="permlab_captureAudioOutput" msgid="6857134498402346708">"ಆಡಿಯೊ ಔಟ್ಪುಟ್ ಸೆರೆಹಿಡಿಯಿರಿ"</string> <string name="permdesc_captureAudioOutput" msgid="6210597754212208853">"ಆಡಿಯೊ ಔಟ್ಪುಟ್ ಸೆರೆಹಿಡಿಯಲು ಮತ್ತು ಮರುನಿರ್ದೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string> <string name="permlab_captureAudioHotword" msgid="1890553935650349808">"ಹಾಟ್ವರ್ಡ್ ಪತ್ತೆಹಚ್ಚುವಿಕೆ"</string> @@ -542,7 +542,7 @@ <string name="permlab_recordAudio" msgid="3876049771427466323">"ಆಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string> <string name="permdesc_recordAudio" msgid="4906839301087980680">"ಮೈಕ್ರೋಫೋನ್ ಮೂಲಕ ಆಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಖಾತರಿ ಇಲ್ಲದೆಯೇ, ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ಆಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿಕೊಳ್ಳಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> <string name="permlab_sim_communication" msgid="1180265879464893029">"ಸಿಮ್ ಸಂವಹನ"</string> - <string name="permdesc_sim_communication" msgid="5725159654279639498">"SIM ಗೆ ಆದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದು ತುಂಬಾ ಅಪಾಯಕಾರಿ."</string> + <string name="permdesc_sim_communication" msgid="5725159654279639498">"ಸಿಮ್ ಗೆ ಆದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದು ತುಂಬಾ ಅಪಾಯಕಾರಿ."</string> <string name="permlab_camera" msgid="3616391919559751192">"ಚಿತ್ರಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳನ್ನು ಸೆರೆಹಿಡಿಯಿರಿ"</string> <string name="permdesc_camera" msgid="8497216524735535009">"ಕ್ಯಾಮರಾ ಮೂಲಕ ಚಿತ್ರಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳನ್ನು ಸೆರೆಹಿಡಿಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ. ಈ ಅನುಮತಿಯು ನಿಮ್ಮ ಖಾತರಿ ಇಲ್ಲದೆಯೇ ಯಾವುದೇ ಸಮಯದಲ್ಲಿ ಕ್ಯಾಮರಾವನ್ನು ಬಳಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string> <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"ಕ್ಯಾಮರಾ ಬಳಕೆಯಲ್ಲಿರುವಾಗ ಪ್ರಸಾರ ಸೂಚಕ LED ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string> @@ -663,7 +663,7 @@ <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"ಬ್ಲೂಟೂತ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string> <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"ಸ್ಥಳೀಯ ಬ್ಲೂಟೂತ್ ಟ್ಯಾಬ್ಲೆಟ್ ಕಾನ್ಫಿಗರ್ ಮಾಡಲು ಮತ್ತು ಅನ್ವೇಷಿಸಲು ಹಾಗೂ ರಿಮೊಟ್ ಸಾಧನಗಳ ಜೊತೆಗೆ ಜೋಡಿ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ ಅನುಮತಿಸುತ್ತದೆ."</string> <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"ಸ್ಥಳೀಯ ಬ್ಲೂಟೂತ್ ಫೋನ್ ಕಾನ್ಫಿಗರ್ ಮಾಡಲು ಮತ್ತು ಅನ್ವೇಷಿಸಲು ಹಾಗೂ ರಿಮೊಟ್ ಸಾಧನಗಳ ಜೊತೆಗೆ ಜೋಡಿ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string> - <string name="permlab_bluetoothPriv" msgid="4009494246009513828">"ಅಪ್ಲಿಕೇಶನ್ ಮೂಲಕ Bluetooth ಜೋಡಣೆಯನ್ನು ಅನುಮತಿಸಿ"</string> + <string name="permlab_bluetoothPriv" msgid="4009494246009513828">"ಅಪ್ಲಿಕೇಶನ್ ಮೂಲಕ ಬ್ಲೂಟೂತ್ ಜೋಡಣೆಯನ್ನು ಅನುಮತಿಸಿ"</string> <string name="permdesc_bluetoothPriv" product="tablet" msgid="8045735193417468857">"ಬಳಕೆದಾರರ ಸಂವಹನವಿಲ್ಲದೆಯೇ ರಿಮೋಟ್ ಸಾಧನಗಳೊಂದಿಗೆ ಜೋಡಿ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string> <string name="permdesc_bluetoothPriv" product="default" msgid="8045735193417468857">"ಬಳಕೆದಾರರ ಸಂವಹನವಿಲ್ಲದೆಯೇ ರಿಮೋಟ್ ಸಾಧನಗಳೊಂದಿಗೆ ಜೋಡಿ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string> <string name="permlab_bluetoothMap" msgid="6372198338939197349">"ಬ್ಲೂಟೂತ್ MAP ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ"</string> @@ -884,14 +884,14 @@ <string name="sipAddressTypeWork" msgid="6920725730797099047">"ಕಚೇರಿ"</string> <string name="sipAddressTypeOther" msgid="4408436162950119849">"ಇತರೆ"</string> <string name="quick_contacts_not_available" msgid="746098007828579688">"ಈ ಸಂಪರ್ಕವನ್ನು ವೀಕ್ಷಿಸಲು ಯಾವುದೇ ಅಪ್ಲಿಕೇಶನ್ ಕಂಡುಬಂದಿಲ್ಲ."</string> - <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN ಕೋಡ್ ಟೈಪ್ ಮಾಡಿ"</string> - <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK ಮತ್ತು ಹೊಸ PIN ಕೋಡ್ ಟೈಪ್ ಮಾಡಿ"</string> + <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"ಪಿನ್ ಕೋಡ್ ಟೈಪ್ ಮಾಡಿ"</string> + <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK ಮತ್ತು ಹೊಸ ಪಿನ್ ಕೋಡ್ ಟೈಪ್ ಮಾಡಿ"</string> <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK ಕೋಡ್"</string> - <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ಹೊಸ PIN ಕೋಡ್"</string> + <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"ಹೊಸ ಪಿನ್ ಕೋಡ್"</string> <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"ಪಾಸ್ವರ್ಡ್ ಟೈಪ್ ಮಾಡಲು ಸ್ಪರ್ಶಿಸಿ"</font></string> <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಪಾಸ್ವರ್ಡ್ ಟೈಪ್ ಮಾಡಿ"</string> - <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ಅನ್ಲಾಕ್ ಮಾಡಲು PIN ಟೈಪ್ ಮಾಡಿ"</string> - <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ತಪ್ಪಾದ PIN ಕೋಡ್."</string> + <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಪಿನ್ ಟೈಪ್ ಮಾಡಿ"</string> + <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"ತಪ್ಪಾದ ಪಿನ್ ಕೋಡ್."</string> <string name="keyguard_label_text" msgid="861796461028298424">"ಅನ್ಲಾಕ್ ಮಾಡಲು, ಮೆನು ನಂತರ 0 ಒತ್ತಿರಿ."</string> <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"ತುರ್ತು ಸಂಖ್ಯೆ"</string> <string name="lockscreen_carrier_default" msgid="8963839242565653192">"ಸೇವೆ ಇಲ್ಲ."</string> @@ -905,13 +905,13 @@ <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸು"</string> <string name="lockscreen_password_wrong" msgid="5737815393253165301">"ಮತ್ತೆ ಪ್ರಯತ್ನಿಸು"</string> <string name="faceunlock_multiple_failures" msgid="754137583022792429">"ಗರಿಷ್ಠ ಫೇಸ್ ಅನ್ಲಾಕ್ ಪ್ರಯತ್ನಗಳು ಮೀರಿವೆ"</string> - <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"ಯಾವುದೇ SIM ಕಾರ್ಡ್ ಇಲ್ಲ"</string> - <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ SIM ಕಾರ್ಡ್ ಇಲ್ಲ."</string> - <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"ಫೋನ್ನಲ್ಲಿ SIM ಕಾರ್ಡ್ ಇಲ್ಲ."</string> - <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"SIM ಕಾರ್ಡ್ ಸೇರಿಸಿ."</string> - <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM ಕಾರ್ಡ್ ಕಾಣೆಯಾಗಿದೆ ಅಥವಾ ಓದಲು ಸಾಧ್ಯವಿಲ್ಲ. ಒಂದು SIM ಕಾರ್ಡ್ ಸೇರಿಸಿ."</string> - <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"ನಿಷ್ಪ್ರಯೋಜಕ SIM ಕಾರ್ಡ್."</string> - <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"ನಿಮ್ಮ SIM ಕಾರ್ಡ್ ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ.\n ಮತ್ತೊಂದು SIM ಕಾರ್ಡ್ಗಾಗಿ ನಿಮ್ಮ ವಯರ್ಲೆಸ್ ಸೇವೆಯ ಪೂರೈಕೆದಾರರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string> + <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"ಯಾವುದೇ ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ"</string> + <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"ಟ್ಯಾಬ್ಲೆಟ್ನಲ್ಲಿ ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ."</string> + <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"ಫೋನ್ನಲ್ಲಿ ಸಿಮ್ ಕಾರ್ಡ್ ಇಲ್ಲ."</string> + <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"ಸಿಮ್ ಕಾರ್ಡ್ ಸೇರಿಸಿ."</string> + <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"ಸಿಮ್ ಕಾರ್ಡ್ ಕಾಣೆಯಾಗಿದೆ ಅಥವಾ ಓದಲು ಸಾಧ್ಯವಿಲ್ಲ. ಒಂದು ಸಿಮ್ ಕಾರ್ಡ್ ಸೇರಿಸಿ."</string> + <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"ನಿಷ್ಪ್ರಯೋಜಕ ಸಿಮ್ ಕಾರ್ಡ್."</string> + <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"ನಿಮ್ಮ ಸಿಮ್ ಕಾರ್ಡ್ ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ.\n ಮತ್ತೊಂದು ಸಿಮ್ ಕಾರ್ಡ್ಗಾಗಿ ನಿಮ್ಮ ವಯರ್ಲೆಸ್ ಸೇವೆಯ ಪೂರೈಕೆದಾರರನ್ನು ಸಂಪರ್ಕಿಸಿ."</string> <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"ಹಿಂದಿನ ಟ್ರ್ಯಾಕ್"</string> <string name="lockscreen_transport_next_description" msgid="573285210424377338">"ಮುಂದಿನ ಟ್ರ್ಯಾಕ್"</string> <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"ವಿರಾಮಗೊಳಿಸು"</string> @@ -921,13 +921,13 @@ <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"ವೇಗವಾಗಿ ಮುಂದಕ್ಕೆ"</string> <string name="emergency_calls_only" msgid="6733978304386365407">"ತುರ್ತು ಕರೆಗಳು ಮಾತ್ರ"</string> <string name="lockscreen_network_locked_message" msgid="143389224986028501">"ನೆಟ್ವರ್ಕ್ ಲಾಕ್ ಮಾಡಲಾಗಿದೆ"</string> - <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM ಕಾರ್ಡ್ PUK-ಲಾಕ್ ಆಗಿದೆ."</string> + <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"ಸಿಮ್ ಕಾರ್ಡ್ PUK-ಲಾಕ್ ಆಗಿದೆ."</string> <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"ಬಳಕೆದಾರರ ಮಾರ್ಗಸೂಚಿಯನ್ನು ನೋಡಿ ಅಥವಾ ಗ್ರಾಹಕರ ಸಹಾಯ ಕೇಂದ್ರಕ್ಕೆ ಸಂಪರ್ಕಿಸಿ."</string> - <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM ಕಾರ್ಡ್ ಲಾಕ್ ಆಗಿದೆ."</string> - <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM ಕಾರ್ಡ್ ಅನ್ಲಾಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string> + <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"ಸಿಮ್ ಕಾರ್ಡ್ ಲಾಕ್ ಆಗಿದೆ."</string> + <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"ಸಿಮ್ ಕಾರ್ಡ್ ಅನ್ಲಾಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string> <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ನಮೂನೆಯನ್ನುನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> - <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ನಿಮ್ಮ PIN ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> + <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"ನಿಮ್ಮ ಪಿನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ನಮೂನೆಯನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಬಾರಿ ವಿಫಲ ಪ್ರಯತ್ನಗಳನ್ನು ಮಾಡಿರುವಿರಿ, Google ಸೈನ್ ಇನ್ ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ನಮೂನೆಯನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಕ್ಕಿಂತ ಹೆಚ್ಚು ಬಾರಿ ವಿಫಲ ಪ್ರಯತ್ನಗಳನ್ನು ಮಾಡಿರುವಿರಿ, Google ಸೈನ್ ಇನ್ ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ನಂತರ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string> @@ -1243,14 +1243,14 @@ <string name="sendText" msgid="5209874571959469142">"ಪಠ್ಯಕ್ಕೆ ಕ್ರಿಯೆಯನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string> <string name="volume_ringtone" msgid="6885421406845734650">"ರಿಂಗರ್ ವಾಲ್ಯೂಮ್"</string> <string name="volume_music" msgid="5421651157138628171">"ಮೀಡಿಯಾ ವಾಲ್ಯೂಮ್"</string> - <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"Bluetooth ಮೂಲಕ ಪ್ಲೇ ಆಗುತ್ತಿದೆ"</string> + <string name="volume_music_hint_playing_through_bluetooth" msgid="9165984379394601533">"ಬ್ಲೂಟೂತ್ ಮೂಲಕ ಪ್ಲೇ ಆಗುತ್ತಿದೆ"</string> <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"ಶಾಂತ ರಿಂಗ್ಟೋನ್ ಹೊಂದಿಸಲಾಗಿದೆ"</string> <string name="volume_call" msgid="3941680041282788711">"ಒಳ-ಕರೆಯ ವಾಲ್ಯೂಮ್"</string> - <string name="volume_bluetooth_call" msgid="2002891926351151534">"Bluetooth ಒಳ-ಕರೆಯ ವಾಲ್ಯೂಮ್"</string> + <string name="volume_bluetooth_call" msgid="2002891926351151534">"ಬ್ಲೂಟೂತ್ ಒಳ-ಕರೆಯ ವಾಲ್ಯೂಮ್"</string> <string name="volume_alarm" msgid="1985191616042689100">"ಅಲಾರಂ ವಾಲ್ಯೂಮ್"</string> <string name="volume_notification" msgid="2422265656744276715">"ಅಧಿಸೂಚನೆಯ ವಾಲ್ಯೂಮ್"</string> <string name="volume_unknown" msgid="1400219669770445902">"ವಾಲ್ಯೂಮ್"</string> - <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Bluetooth ವಾಲ್ಯೂಮ್"</string> + <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"ಬ್ಲೂಟೂತ್ ವಾಲ್ಯೂಮ್"</string> <string name="volume_icon_description_ringer" msgid="3326003847006162496">"ರಿಂಗ್ಟೋನ್ ವಾಲ್ಯೂಮ್"</string> <string name="volume_icon_description_incall" msgid="8890073218154543397">"ಕರೆಯ ವಾಲ್ಯೂಮ್"</string> <string name="volume_icon_description_media" msgid="4217311719665194215">"ಮೀಡಿಯಾ ವಾಲ್ಯೂಮ್"</string> @@ -1285,8 +1285,8 @@ <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"ಸಂಪರ್ಕಗೊಳ್ಳಲು ಆಹ್ವಾನ"</string> <string name="wifi_p2p_from_message" msgid="570389174731951769">"ಇಂದ:"</string> <string name="wifi_p2p_to_message" msgid="248968974522044099">"ಗೆ:"</string> - <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"ಅಗತ್ಯವಿರುವ PIN ಟೈಪ್ ಮಾಡಿ:"</string> - <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string> + <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"ಅಗತ್ಯವಿರುವ ಪಿನ್ ಟೈಪ್ ಮಾಡಿ:"</string> + <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"ಪಿನ್:"</string> <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ಟ್ಯಾಬ್ಲೆಟ್ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಾಗ ಅದನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ Wi-Fi ನಿಂದ ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗುತ್ತದೆ"</string> <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ಫೋನ್ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಾಗ Wi-Fi ನಿಂದ ಅದು ತಾತ್ಕಾಲಿಕವಾಗಿ ಸಂಪರ್ಕ ಕಡಿತಗೊಳ್ಳುತ್ತದೆ"</string> <string name="select_character" msgid="3365550120617701745">"ಅಕ್ಷರವನ್ನು ಸೇರಿಸಿ"</string> @@ -1303,10 +1303,10 @@ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"ನೀವು ಇದನ್ನು ನಂತರದಲ್ಲಿ ಸೆಟ್ಟಿಂಗ್ಗಳು > ಅಪ್ಲಿಕೇಶನ್ಗಳಲ್ಲಿ ಬದಲಾಯಿಸಬಹುದು"</string> <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"ಯಾವಾಗಲೂ ಅನುಮತಿಸು"</string> <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"ಎಂದಿಗೂ ಅನುಮತಿಸದಿರು"</string> - <string name="sim_removed_title" msgid="6227712319223226185">"SIM ಕಾರ್ಡ್ ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string> - <string name="sim_removed_message" msgid="5450336489923274918">"ನೀವು ಮಾನ್ಯವಾದ SIM ಕಾರ್ಡ್ ಮರುಪ್ರಾರಂಭಿಸುವವರೆಗೆ ಸೆಲ್ಯುಲಾರ್ ನೆಟ್ವರ್ಕ್ ಲಭ್ಯವಿರುವುದಿಲ್ಲ."</string> + <string name="sim_removed_title" msgid="6227712319223226185">"ಸಿಮ್ ಕಾರ್ಡ್ ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string> + <string name="sim_removed_message" msgid="5450336489923274918">"ನೀವು ಮಾನ್ಯವಾದ ಸಿಮ್ ಕಾರ್ಡ್ ಮರುಪ್ರಾರಂಭಿಸುವವರೆಗೆ ಸೆಲ್ಯುಲಾರ್ ನೆಟ್ವರ್ಕ್ ಲಭ್ಯವಿರುವುದಿಲ್ಲ."</string> <string name="sim_done_button" msgid="827949989369963775">"ಮುಗಿದಿದೆ"</string> - <string name="sim_added_title" msgid="3719670512889674693">"SIM ಕಾರ್ಡ್ ಸೇರಿಸಲಾಗಿದೆ"</string> + <string name="sim_added_title" msgid="3719670512889674693">"ಸಿಮ್ ಕಾರ್ಡ್ ಸೇರಿಸಲಾಗಿದೆ"</string> <string name="sim_added_message" msgid="7797975656153714319">"ಸೆಲ್ಯುಲಾರ್ ನೆಟ್ವರ್ಕ್ ಪ್ರವೇಶಿಸಲು ನಿಮ್ಮ ಸಾಧನವನ್ನು ಮರುಪ್ರಾರಂಭಿಸಿ."</string> <string name="sim_restart_button" msgid="4722407842815232347">"ಮರುಪ್ರಾರಂಭಿಸು"</string> <string name="time_picker_dialog_title" msgid="8349362623068819295">"ಸಮಯವನ್ನು ಹೊಂದಿಸಿ"</string> @@ -1596,21 +1596,21 @@ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ಮರೆತಿರುವಿರಿ"</string> <string name="kg_wrong_pattern" msgid="1850806070801358830">"ತಪ್ಪು ಪ್ಯಾಟರ್ನ್"</string> <string name="kg_wrong_password" msgid="2333281762128113157">"ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್"</string> - <string name="kg_wrong_pin" msgid="1131306510833563801">"ತಪ್ಪಾದ PIN"</string> + <string name="kg_wrong_pin" msgid="1131306510833563801">"ತಪ್ಪಾದ ಪಿನ್"</string> <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="kg_pattern_instructions" msgid="398978611683075868">"ನಿಮ್ಮ ನಮೂನೆಯನ್ನು ಚಿತ್ರಿಸಿ"</string> - <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PIN ನಮೂದಿಸಿ"</string> - <string name="kg_pin_instructions" msgid="2377242233495111557">"PIN ನಮೂದಿಸಿ"</string> + <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"ಸಿಮ್ ಪಿನ್ ನಮೂದಿಸಿ"</string> + <string name="kg_pin_instructions" msgid="2377242233495111557">"ಪಿನ್ ನಮೂದಿಸಿ"</string> <string name="kg_password_instructions" msgid="5753646556186936819">"ಪಾಸ್ವರ್ಡ್ ನಮೂದಿಸಿ"</string> - <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ಇದೀಗ SIM ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ. ಮುಂದುವರೆಯಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ."</string> - <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ಅಗತ್ಯವಿರುವ PIN ಕೋಡ್ ನಮೂದಿಸಿ"</string> - <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ಬಯಸಿರುವ PIN ಕೋಡ್ ದೃಢೀಕರಿಸಿ"</string> - <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM ಕಾರ್ಡ್ ಅನ್ಲಾಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string> - <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ತಪ್ಪಾದ PIN ಕೋಡ್."</string> - <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 ರಿಂದ 8 ಸಂಖ್ಯೆಗಳಿರುವ PIN ಟೈಪ್ ಮಾಡಿ."</string> + <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"ಇದೀಗ ಸಿಮ್ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ. ಮುಂದುವರೆಯಲು PUK ಕೋಡ್ ನಮೂದಿಸಿ. ವಿವರಗಳಿಗಾಗಿ ವಾಹಕವನ್ನು ಸಂಪರ್ಕಿಸಿ."</string> + <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"ಅಗತ್ಯವಿರುವ ಪಿನ್ ಕೋಡ್ ನಮೂದಿಸಿ"</string> + <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"ಬಯಸಿರುವ ಪಿನ್ ಕೋಡ್ ದೃಢೀಕರಿಸಿ"</string> + <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"ಸಿಮ್ ಕಾರ್ಡ್ ಅನ್ಲಾಕ್ ಮಾಡಲಾಗುತ್ತಿದೆ…"</string> + <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"ತಪ್ಪಾದ ಪಿನ್ ಕೋಡ್."</string> + <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 ರಿಂದ 8 ಸಂಖ್ಯೆಗಳಿರುವ ಪಿನ್ ಟೈಪ್ ಮಾಡಿ."</string> <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK ಕೋಡ್ 8 ಸಂಖ್ಯೆಗಳನ್ನು ಹೊಂದಿರಬೇಕು."</string> - <string name="kg_invalid_puk" msgid="3638289409676051243">"ಸರಿಯಾದ PUK ಕೋಡ್ ಅನ್ನು ಮರು-ನಮೂದಿಸಿ. ಸತತ ಪ್ರಯತ್ನಗಳು SIM ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string> - <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN ಕೋಡ್ಗಳು ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತಿಲ್ಲ"</string> + <string name="kg_invalid_puk" msgid="3638289409676051243">"ಸರಿಯಾದ PUK ಕೋಡ್ ಅನ್ನು ಮರು-ನಮೂದಿಸಿ. ಸತತ ಪ್ರಯತ್ನಗಳು ಸಿಮ್ ಅನ್ನು ಶಾಶ್ವತವಾಗಿ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string> + <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"ಪಿನ್ ಕೋಡ್ಗಳು ಹೊಂದಾಣಿಕೆಯಾಗುತ್ತಿಲ್ಲ"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"ಹಲವಾರು ಪ್ಯಾಟರ್ನ್ ಪ್ರಯತ್ನಗಳು"</string> <string name="kg_login_instructions" msgid="1100551261265506448">"ಅನ್ಲಾಕ್ ಮಾಡಲು, ನಿಮ್ಮ Google ಖಾತೆ ಬಳಸಿಕೊಂಡು ಸೈನ್ ಇನ್ ಮಾಡಿ."</string> <string name="kg_login_username_hint" msgid="5718534272070920364">"ಬಳಕೆದಾರಹೆಸರು (ಇಮೇಲ್)"</string> @@ -1619,7 +1619,7 @@ <string name="kg_login_invalid_input" msgid="5754664119319872197">"ಅಮಾನ್ಯ ಬಳಕೆದಾರಹೆಸರು ಅಥವಾ ಪಾಸ್ವರ್ಡ್."</string> <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"ನಿಮ್ಮ ಬಳಕೆದಾರಹೆಸರು ಅಥವಾ ಪಾಸ್ವರ್ಡ್ ಮರೆತಿರುವಿರಾ?\n"<b>"google.com/accounts/recovery"</b>" ಗೆ ಭೇಟಿ ನೀಡಿ."</string> <string name="kg_login_checking_password" msgid="1052685197710252395">"ಖಾತೆಯನ್ನು ಪರಿಶೀಲಿಸಲಾಗುತ್ತಿದೆ…"</string> - <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ನಿಮ್ಮ PIN ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> + <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"ನಿಮ್ಮ ಪಿನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"ನಿಮ್ಮ ಪಾಸ್ವರ್ಡ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಟೈಪ್ ಮಾಡಿರುವಿರಿ. \n\n <xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಚಿತ್ರಿಸಿರುವಿರಿ. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER_0">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿರುವಿರಿ. <xliff:g id="NUMBER_1">%d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಫ್ಯಾಕ್ಟರಿ ಡೀಫಾಲ್ಟ್ಗೆ ಮರು ಹೊಂದಿಸಲಾಗುತ್ತದೆ ಮತ್ತು ಎಲ್ಲಾ ಬಳಕೆದಾರರ ಡೇಟಾ ಕಳೆದು ಹೋಗುತ್ತದೆ."</string> @@ -1730,15 +1730,15 @@ <string name="reason_service_unavailable" msgid="7824008732243903268">"ಮುದ್ರಣ ಸೇವೆ ಸಕ್ರಿಯಗೊಂಡಿಲ್ಲ"</string> <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> ಸೇವೆಯನ್ನು ಸ್ಥಾಪಿಸಲಾಗಿದೆ"</string> <string name="print_service_installed_message" msgid="5897362931070459152">"ಸಕ್ರಿಯಗೊಳಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string> - <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"ನಿರ್ವಾಹಕರ PIN ನಮೂದಿಸಿ"</string> - <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PIN ನಮೂದಿಸಿ"</string> + <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"ನಿರ್ವಾಹಕರ ಪಿನ್ ನಮೂದಿಸಿ"</string> + <string name="restr_pin_enter_pin" msgid="3395953421368476103">"ಪಿನ್ ನಮೂದಿಸಿ"</string> <string name="restr_pin_incorrect" msgid="8571512003955077924">"ತಪ್ಪು"</string> - <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"ಸದ್ಯದ PIN"</string> - <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ಹೊಸ PIN"</string> - <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ಹೊಸ PIN ದೃಢೀಕರಿಸಿ"</string> - <string name="restr_pin_create_pin" msgid="8017600000263450337">"ನಿರ್ಬಂಧಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು PIN ರಚಿಸಿ"</string> - <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PIN ಗಳು ಹೊಂದಿಕೆಯಾಗುತ್ತಿಲ್ಲ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> - <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN ತುಂಬಾ ಚಿಕ್ಕದಾಗಿದೆ. ಕನಿಷ್ಟ ಪಕ್ಷ 4 ಅಂಕಿಗಳಾಗಿರಬೇಕು."</string> + <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"ಸದ್ಯದ ಪಿನ್"</string> + <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"ಹೊಸ ಪಿನ್"</string> + <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"ಹೊಸ ಪಿನ್ ದೃಢೀಕರಿಸಿ"</string> + <string name="restr_pin_create_pin" msgid="8017600000263450337">"ನಿರ್ಬಂಧಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಪಿನ್ ರಚಿಸಿ"</string> + <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"ಪಿನ್ ಗಳು ಹೊಂದಿಕೆಯಾಗುತ್ತಿಲ್ಲ. ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string> + <string name="restr_pin_error_too_short" msgid="8173982756265777792">"ಪಿನ್ ತುಂಬಾ ಚಿಕ್ಕದಾಗಿದೆ. ಕನಿಷ್ಟ ಪಕ್ಷ 4 ಅಂಕಿಗಳಾಗಿರಬೇಕು."</string> <plurals name="restr_pin_countdown"> <item quantity="one" msgid="311050995198548675">"1 ಸೆಕೆಂಡಿನಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</item> <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ"</item> @@ -1757,17 +1757,17 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ಆಯ್ಕೆ ಮಾಡಲಾಗಿದೆ"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ಅಳಿಸಲಾಗಿದೆ"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"ಕೆಲಸ <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"ಈ ಪರದೆಯನ್ನು ಅನ್ಪಿನ್ ಮಾಡಲು, ಹಿಂದೆ ಮತ್ತು ಅವಲೋಕನವನ್ನು ಏಕ ಸಮಯದಲ್ಲಿ ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"ಈ ಪರದೆಯನ್ನು ಅನ್ಪಿನ್ ಮಾಡಲು, ಅವಲೋಕನವನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"ಈ ಪರದೆಯನ್ನು ಅನ್ಪಿನ್ ಮಾಡಲು, ‘ಹಿಂದೆ’ ಮತ್ತು ‘ಸಮಗ್ರ ನೋಟ’ವನ್ನು ಏಕಕಾಲದಲ್ಲಿ ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"ಈ ಪರದೆಯನ್ನು ಅನ್ಪಿನ್ ಮಾಡಲು, ‘ಸಮಗ್ರ ನೋಟ’ವನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"ಪರದೆ ಪಿನ್ ಮಾಡಲಾಗಿದೆ. ಅನ್ಪಿನ್ ಮಾಡಲು ನಿಮ್ಮ ಸಂಸ್ಥೆ ಅವಕಾಶ ಮಾಡಿಕೊಟ್ಟಿಲ್ಲ."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"ಸ್ಕ್ರೀನ್ ಪಿನ್ನಿಂಗ್ ಬಳಸುವುದೇ?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"ಪರದೆ ಪಿನ್ ಮಾಡುವಿಕೆಯು ಪ್ರದರ್ಶನವನ್ನು ಏಕ ವೀಕ್ಷಣೆಯಲ್ಲಿ ಲಾಕ್ ಮಾಡುತ್ತದೆ.\n\nಅನ್ಪಿನ್ ಮಾಡಲು, ಹಿಂದೆ ಮತ್ತು ಅವಲೋಕನವನ್ನು ಏಕ ಸಮಯದಲ್ಲಿ ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"ಪರದೆ ಪಿನ್ ಮಾಡುವಿಕೆಯು ಪ್ರದರ್ಶನವನ್ನು ಏಕ ವೀಕ್ಷಣೆಯಲ್ಲಿ ಲಾಕ್ ಮಾಡುತ್ತದೆ.\n\nಅನ್ಪಿನ್ ಮಾಡಲು, ಅವಲೋಕನವನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"ಪರದೆ ಪಿನ್ ಮಾಡುವಿಕೆಯು ಪ್ರದರ್ಶನವನ್ನು ಏಕ ವೀಕ್ಷಣೆಯಲ್ಲಿ ಲಾಕ್ ಮಾಡುತ್ತದೆ.\n\nಅನ್ಪಿನ್ ಮಾಡಲು, ‘ಹಿಂದೆ’ ಮತ್ತು ‘ಸಮಗ್ರ ನೋಟ’ ಎರಡೂ ಬಟನ್ ಅನ್ನು ಏಕಕಾಲದಲ್ಲಿ ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"ಪರದೆ ಪಿನ್ ಮಾಡುವಿಕೆಯು ಪ್ರದರ್ಶನವನ್ನು ಏಕ ವೀಕ್ಷಣೆಯಲ್ಲಿ ಲಾಕ್ ಮಾಡುತ್ತದೆ.\n\nಅನ್ಪಿನ್ ಮಾಡಲು, ‘ಸಮಗ್ರ ನೋಟ’ವನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"ಬೇಡ, ಧನ್ಯವಾದಗಳು"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"ಪ್ರಾರಂಭಿಸು"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"ಸ್ಕ್ರೀನ್ ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"ಸ್ಕ್ರೀನ್ ಅನ್ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string> - <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ಅನ್ಪಿನ್ ಮಾಡುವುದಕ್ಕೂ ಮೊದಲು PIN ಕೇಳಿ"</string> + <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"ಅನ್ಪಿನ್ ಮಾಡುವುದಕ್ಕೂ ಮೊದಲು ಪಿನ್ ಕೇಳಿ"</string> <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"ಅನ್ಪಿನ್ ಮಾಡುವುದಕ್ಕೂ ಮೊದಲು ಅನ್ಲಾಕ್ ನಮೂನೆಯನ್ನು ಕೇಳಿ"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"ಅನ್ಪಿನ್ ಮಾಡುವುದಕ್ಕೂ ಮೊದಲು ಪಾಸ್ವರ್ಡ್ ಕೇಳಿ"</string> <string name="battery_saver_description" msgid="2510530476513605742">"ಬ್ಯಾಟರಿ ಬಾಳಿಕೆಯನ್ನು ಹೆಚ್ಚಿಸುವ ನಿಟ್ಟಿನಲ್ಲಿ ಸಹಾಯ ಮಾಡಲು, ಬ್ಯಾಟರಿ ಉಳಿತಾಯವು ನಿಮ್ಮ ಸಾಧನದ ಕಾರ್ಯಕ್ಷಮತೆಯನ್ನು ಕುಂಠಿತಗೊಳಿಸುತ್ತದೆ ಮತ್ತು ವೈಬ್ರೇಷನ್ ಹಾಗೂ ಹೆಚ್ಚಿನ ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ಸೀಮಿತಗೊಳಿಸುತ್ತದೆ. ಇಮೇಲ್, ಸಂದೇಶ ಕಳುಹಿಸುವಿಕೆ, ಮತ್ತು ಸಿಂಕ್ ಮಾಡುವುದನ್ನು ಅವಲಂಬಿಸಿರುವ ಇತರ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ನೀವು ತೆರೆಯುವವರೆಗೆ ಅವುಗಳನ್ನು ನವೀಕರಿಸಲಾಗುವುದಿಲ್ಲ.\n\nನಿಮ್ಮ ಸಾಧನವು ಚಾರ್ಜ್ ಆಗುತ್ತಿರುವಾಗ ಬ್ಯಾಟರಿ ಉಳಿತಾಯವು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ಆಫ್ ಆಗುತ್ತದೆ."</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index d008dad3d412..0a89714525a1 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"나만의 연락처 카드 수정"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"앱이 기기에 저장된 개인 프로필 정보(예: 사용자 이름, 연락처 정보 등)를 변경 또는 추가할 수 있도록 허용합니다. 이는 앱이 사용자를 확인하고 다른 사용자에게 해당 프로필 정보를 전송할 수 있다는 것을 의미합니다."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"신체 센서(예: 심박수 모니터)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"앱이 신체 변화(예: 심박수) 측정을 위해 사용하는 센서의 데이터에 액세스하도록 허용합니다."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"앱이 심박수와 같은 신체 상태를 모니터링하는 센서의 데이터에 액세스하도록 허용합니다."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"소셜 스트림 읽기"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"앱이 사용자와 친구의 최신 소셜 소식에 액세스하고 동기화할 수 있도록 허용합니다. 이 경우 앱이 비밀유지와 관계 없이 소셜 네트워크에서 사용자와 친구가 주고받는 내용을 읽을 수 있으므로, 정보를 공유할 때 주의해야 합니다. 참고: 이 권한이 적용되지 않는 소셜 네트워크도 있습니다."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"소셜 스트림에 쓰기"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g>이(가) 선택됨"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> 삭제됨"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"업무용 <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"화면을 고정 해제하려면 \'뒤로\'와 \'개요\'를 동시에 길게 터치합니다."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"화면을 고정 해제하려면 \'개요\'를 길게 터치합니다."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"화면을 고정 해제하려면 \'뒤로\'와 \'최근 사용\'을 동시에 길게 터치합니다."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"화면을 고정 해제하려면 \'최근 사용\'을 길게 터치합니다."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"화면이 고정되었습니다. 소속된 조직에서 고정 해제를 허용하지 않습니다."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"화면을 고정하시겠습니까?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"화면을 고정하면 단일 보기에서 디스플레이를 잠급니다.\n\n고정 해제하려면 \'뒤로\'와 \'개요\'를 동시에 길게 터치합니다."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"화면을 고정하면 단일 보기에서 디스플레이를 잠급니다.\n\n고정 해제하려면 \'개요\'를 길게 터치합니다."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"화면을 고정하면 단일 보기에서 디스플레이를 잠급니다.\n\n고정 해제하려면 \'뒤로\'와 \'최근 사용\'을 동시에 길게 터치합니다."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"화면을 고정하면 단일 보기에서 디스플레이를 잠급니다.\n\n고정 해제하려면 \'최근 사용\'을 길게 터치합니다."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"아니요"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"시작"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"화면 고정됨"</string> diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml index ecd4c17bb602..d240c7a0850a 100644 --- a/core/res/res/values-ky-rKG/strings.xml +++ b/core/res/res/values-ky-rKG/strings.xml @@ -653,7 +653,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"сиздин байланыш картаңызды өзгөртүү"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Колдонмого түзмөгүңүздө сакталган, сиздин атыңыз жана байланыш маалыматтарыңыз сыяктуу жеке профайл маалыматтарын өзгөртүү же кошуу уруксатын берет. Бул колдонмо сизди аныктай алат жана сиздин профилдик маалыматтарыңызды башкаларга жөнөтүүгө жөндөм алат дегенди билдирет."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"дене-бой сенсорлору (жүрөктүн кагышын өлчөгүчтөр сыяктуу)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Колдонмого жүрөктүн кагышы сыяктуу дене-боюңуздагы нерселерди өлчөп турган сенсорлордун дайындарын алып туруу мүмкүнчүлүгүн берет."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Колдонмого жүрөгүңүздүн согушу сыяктуу дене-бой абалыңызды көзөмөлдөгөн сенсорлордогу дайындарды көрүп туруу мүмкүнчүлүгүн берет."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"сиздин социалдык агымыңызды окуу"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Колдонмого социалдык түйүндөргө жетүү жана сиздин жана досторуңуздун жаңыртуулары менен синхрондошуу уруксатын берет. Маалымат бөлүшкөндө абайлаңыз -- бул колдонмого сиздин социалдык түйүндөрдөгү досторуңуз менен баарлашууңузду, анын конфиденциалдуулугуна карабастан, окуганга уруксат берет. Эскертүү: бул уруксат айрым социалдык түйүндөрдө иштебеши мүмкүн."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"сиздин социалдык агымыңызга жазуу"</string> diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml index 5eeb1e02c091..34ecf92a4704 100644 --- a/core/res/res/values-lo-rLA/strings.xml +++ b/core/res/res/values-lo-rLA/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"ແກ້ໄຂບັດລາຍຊື່ຜູ່ຕິດຕໍ່ຂອງທ່ານເອງ"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ອະນຸຍາດໃຫ້ແອັບຯ ປ່ຽນແປງ ຫຼືເພີ່ມຂໍ້ມູນໃສ່ໂປຣໄຟລ໌ສ່ວນບຸກຄົນທີ່ເກັບໄວ້ໃນອຸປະກອນຂອງທ່ານ, ເຊັ່ນ: ຊື່ ແລະຂໍ້ມູນຕິດຕໍ່ທ່ານ. ນີ້ໝາຍຄວາມວ່າແອັບຯສາມາດບົ່ງບອກໂຕທ່ານ ແລະອາດສົ່ງຂໍ້ມູນໂປຣໄຟລ໌ຂອງທ່ານໃຫ້ຜູ່ອື່ນໄດ້."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"ເຊັນເຊີຮ່າງກາຍ (ເຊັ່ນ: ຕິດຕາມອັດຕາການເຕັ້ນຂອງຫົວໃຈ)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"ອະນຸຍາດໃຫ້ແອັບຯເຂົ້າເຖິງຂໍ້ມູນຈາກເຊັນເຊີທີ່ທ່ານໃຊ້ເພື່ອວັດແທກສິ່ງທີ່ເກີດຂຶ້ນໃນຮ່າງກາຍຂອງທ່ານ ເຊັ່ນ: ອັດຕາການເຕັ້ນຂອງຫົວໃຈ."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ອະນຸຍາດໃຫ້ແອັບຯເຂົ້າເຖິງຂໍ້ມູນຈາກເຊັນເຊີທີ່ຕິດຕາມສະພາບຮ່າງການຂອງທ່ານ, ເຊັ່ນ: ອັດຕາການເຕັ້ນຂອງຫົວໃຈຂອງທ່ານ."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ອ່ານການອັບເດດສັງຄົມອອນລາຍຂອງທ່ານ"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ອະນຸຍາດໃຫ້ແອັບຯ ເຂົ້າເຖິງ ແລະຊິ້ງຂໍ້ມູນຂ່າວສານສັງຄົມຈາກທ່ານ ແລະໝູ່ຂອງທ່ານ. ຄວນລະມັດລະວັງໃນເວລາທີ່ແລກປ່ຽນຂໍ້ມູນ -- ນີ້ຈະເປັນການອະນຸຍາດໃຫ້ແອັບຯ ອ່ານການສື່ສານລະຫວ່າງທ່ານ ກັບໝູ່ຂອງທ່ານເທິງເຄືອຂ່າຍສັງຄົມ ໂດຍບໍ່ຄຳນຶງເຖິງຄວາມລັບ. ໝາຍເຫດ: ການກຳນົດສິດນີ້ອາດບໍ່ໄດ້ບັງຄັບໃຊ້ໃນທຸກເຄືອຂ່າຍສັງຄົມ."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ຂຽນໃສ່ເຄືອຂ່າຍສັງຄົມຂອງທ່ານ"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index bf6c1b18c4de..35fbe0c2ebf7 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"keisti jūsų kontaktinę kortelę"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Leidžiama programai keisti įrenginyje saugomą asmeninę profilio informaciją, pvz., vardą, pavardę ir kontaktinę informaciją, arba jos pridėti. Tai reiškia, kad programa gali nustatyti tapatybę ir siųsti profilio informaciją kitiems."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"kūno jut. (pvz., pulso d. t.)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Programai leidžiama pasiekti naudojamų jutiklių duomenis, siekiant įvertinti, kas vyksta jūsų kūne, pvz., pulso dažnį."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Programai leidžiama pasiekti duomenis, gautus iš jutiklių, stebinčių fizinę būseną, pvz., širdies ritmą."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"skaityti socialinį srautą"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Leidžiama programai pasiekti ir sinchronizuoti viešas naujienas iš jūsų ir jūsų draugų. Būkite atidūs bendrindami informaciją – programai leidžiama skaityti korespondenciją tarp jūsų ir draugų viešuosiuose tinkluose, neatsižvelgiant į konfidencialumą. Pastaba: šis leidimas negali būti taikomas visuose viešuosiuose tinkluose."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"rašyti į socialinį srautą"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 82d384782144..de2d8a66ac75 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"mainīt manu vizītkarti"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ļauj lietotnei mainīt ierīcē saglabāto personīgā profila informāciju, piemēram, jūsu vārdu un kontaktinformāciju, vai pievienot tai citu informāciju. Tas nozīmē, ka lietotne var jūs identificēt un var nosūtīt jūsu profila informāciju citām personām."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"ķermeņa sensori (piemēram, sirdsdarbības monitori)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Ļauj lietotnei piekļūt to sensoru datiem, kurus izmantojat, lai novērtētu ķermeņa procesus, piemēram, sirdsdarbību."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ļauj lietotnei piekļūt to sensoru datiem, kuri pārrauga jūsu fizisko stāvokli (piemēram, sirdsdarbības ātrumu)."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lasīt jūsu soc. tīklu straumi"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Ļauj lietotnei piekļūt sociālajiem atjauninājumiem no jums un jūsu draugiem un sinhronizēt tos. Esiet piesardzīgs, kad kopīgojat informāciju, — šādi lietotne var lasīt sociālajos tīklos ar draugiem veikto saziņu, neraugoties uz konfidencialitāti. Piezīme: šo atļauju nedrīkst piemērot visiem sociālajiem tīkliem."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"rakstīt sociālo tīklu straumē"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"Atlasīts: <xliff:g id="ITEM">%1$s</xliff:g>"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> tika dzēsts."</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"Darbā: <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Lai atspraustu šo ekrānu, vienlaicīgi pieskarieties pogām “Atpakaļ” un “Kopsavilkums” un turiet tās."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Lai atspraustu šo ekrānu, pieskarieties pogai “Kopsavilkums” un turiet to."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Lai atspraustu šo ekrānu, vienlaicīgi pieskarieties pogām “Atpakaļ” un “Pārskats” un turiet tās."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Lai atspraustu šo ekrānu, pieskarieties pogai “Pārskats” un turiet to."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Ekrāns ir piesprausts. Jūsu organizācija nav atļāvusi atspraušanu."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Vai izmantot ekrāna piespraušanu?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"Izmantojot ekrāna piespraušanu, ekrāns tiek bloķēts, lai tiktu rādīts viens skats.\n\nLai atspraustu ekrānu, vienlaicīgi pieskarieties pogām “Atpakaļ” un “Kopsavilkums” un turiet tās."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Izmantojot ekrāna piespraušanu, ekrāns tiek bloķēts, lai tiktu rādīts viens skats.\n\nLai atspraustu ekrānu, pieskarieties pogai “Kopsavilkums” un turiet to."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"Izmantojot ekrāna piespraušanu, ekrāns tiek bloķēts, lai tiktu rādīts viens skats.\n\nLai atspraustu ekrānu, vienlaicīgi pieskarieties pogām “Atpakaļ” un “Pārskats” un turiet tās."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Izmantojot ekrāna piespraušanu, ekrāns tiek bloķēts, lai tiktu rādīts viens skats.\n\nLai atspraustu ekrānu, pieskarieties pogai “Pārskats” un turiet to."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"NĒ, PALDIES"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"SĀKT"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Ekrāns ir piesprausts"</string> diff --git a/core/res/res/values-mcc310-mnc120/config.xml b/core/res/res/values-mcc310-mnc120/config.xml index 24e55b13135f..774732dba717 100644 --- a/core/res/res/values-mcc310-mnc120/config.xml +++ b/core/res/res/values-mcc310-mnc120/config.xml @@ -27,4 +27,8 @@ <!-- Sprint need a 70 ms delay for 3way call --> <integer name="config_cdma_3waycall_flash_delay">70</integer> + + <!-- If this value is true, The mms content-disposition field is supported correctly. + If false, Content-disposition fragments are ignored --> + <bool name="config_mms_content_disposition_support">false</bool> </resources> diff --git a/core/res/res/values-mcc310-mnc160/config.xml b/core/res/res/values-mcc310-mnc160/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc160/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc200/config.xml b/core/res/res/values-mcc310-mnc200/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc200/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc210/config.xml b/core/res/res/values-mcc310-mnc210/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc210/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc220/config.xml b/core/res/res/values-mcc310-mnc220/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc220/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc230/config.xml b/core/res/res/values-mcc310-mnc230/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc230/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc240/config.xml b/core/res/res/values-mcc310-mnc240/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc240/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc250/config.xml b/core/res/res/values-mcc310-mnc250/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc250/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc260/config.xml b/core/res/res/values-mcc310-mnc260/config.xml index 28cd69533197..6bfc3d19ac64 100644 --- a/core/res/res/values-mcc310-mnc260/config.xml +++ b/core/res/res/values-mcc310-mnc260/config.xml @@ -25,8 +25,8 @@ --> <integer name="config_mobile_mtu">1440</integer> - <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + <!-- Flag specifying whether VoLTE should be available for carrier: independent of carrier provisioning. If false: hard disabled. If true: then depends on carrier provisioning, availability etc --> - <bool name="config_carrier_volte_vt_available">true</bool> + <bool name="config_carrier_volte_available">true</bool> </resources> diff --git a/core/res/res/values-mcc310-mnc270/config.xml b/core/res/res/values-mcc310-mnc270/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc270/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc300/config.xml b/core/res/res/values-mcc310-mnc300/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc300/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc310/config.xml b/core/res/res/values-mcc310-mnc310/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc310/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc490/config.xml b/core/res/res/values-mcc310-mnc490/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc490/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc530/config.xml b/core/res/res/values-mcc310-mnc530/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc530/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc580/config.xml b/core/res/res/values-mcc310-mnc580/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc580/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc590/config.xml b/core/res/res/values-mcc310-mnc590/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc590/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc640/config.xml b/core/res/res/values-mcc310-mnc640/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc640/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc660/config.xml b/core/res/res/values-mcc310-mnc660/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc660/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc310-mnc800/config.xml b/core/res/res/values-mcc310-mnc800/config.xml new file mode 100644 index 000000000000..28cd69533197 --- /dev/null +++ b/core/res/res/values-mcc310-mnc800/config.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2013, 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 my 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 xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + + <!-- Configure mobile network MTU. Carrier specific value is set here. + --> + <integer name="config_mobile_mtu">1440</integer> + + <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_vt_available">true</bool> +</resources> diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml index 820cc2e2fee2..d0a57b37ee10 100644 --- a/core/res/res/values-mcc311-mnc480/config.xml +++ b/core/res/res/values-mcc311-mnc480/config.xml @@ -38,10 +38,10 @@ be disabled) but individual Features can be disabled using ImsConfig.setFeatureValue() --> <bool name="imsServiceAllowTurnOff">false</bool> - <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + <!-- Flag specifying whether VoLTE should be available for carrier: independent of carrier provisioning. If false: hard disabled. If true: then depends on carrier provisioning, availability etc --> - <bool name="config_carrier_volte_vt_available">true</bool> + <bool name="config_carrier_volte_available">true</bool> <bool name="config_auto_attach_data_on_creation">false</bool> <!-- service number convert map in roaming network. --> diff --git a/core/res/res/values-mcc530-mnc05/config.xml b/core/res/res/values-mcc530-mnc05/config.xml new file mode 100644 index 000000000000..893afe586d23 --- /dev/null +++ b/core/res/res/values-mcc530-mnc05/config.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 2014, 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 my 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> + <!-- If this value is true, The mms content-disposition field is supported correctly. + If false, Content-disposition fragments are ignored --> + <bool name="config_mms_content_disposition_support">false</bool> +</resources> diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml index dfa537e56f68..a2049f4607d5 100644 --- a/core/res/res/values-mk-rMK/strings.xml +++ b/core/res/res/values-mk-rMK/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"измени ја сопствената картичка за контакт"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Овозможува апликацијата да менува или да додава информации од личниот профил што се зачувани на вашиот уред, како што се вашето име и информации за контакт. Ова значи дека апликацијата може да ве идентификува и да ги испрати информациите од вашиот профил на други."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"телесни сензори (како монитори за срцев пулс)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Дозволува апликацијата да пристапи до податоци од сензори што ги користите за мерење на настани во вашето тело, како срцевиот ритам."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Дозволува апликацијата да пристапува до податоци од сензори кои ја следат вашата физичка состојба, како на пр. отчукувањата на срцето."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"читај социјални текови"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Овозможува апликацијата да пристапува и да синхронизира социјални ажурирања од вас и вашите пријатели. Бидете внимателни кога споделувате информации - ова овозможува апликацијата да ја чита комуникацијата меѓу вас и вашите пријатели на социјалните мрежи, без оглед на нејзината доверливост. Напомена: оваа дозвола не може да се наметне на сите социјални мрежи."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"пишувај на социјалните текови"</string> diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml index a051d5949671..44399cc0dc6f 100644 --- a/core/res/res/values-ml-rIN/strings.xml +++ b/core/res/res/values-ml-rIN/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"നിങ്ങളുടെ സ്വന്തം കോൺടാക്റ്റ് കാർഡ് പരിഷ്ക്കരിക്കുക"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"നിങ്ങളുടെ ഉപകരണത്തിൽ സംഭരിച്ചിരിക്കുന്ന നിങ്ങളുടെ പേരും ബന്ധപ്പെടാനുള്ള വിവരങ്ങളും പോലുള്ള വ്യക്തിഗത പ്രൊഫൈൽ വിവരം മാറ്റാനോ ചേർക്കാനോ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. നിങ്ങളെ തിരിച്ചറിയാനും നിങ്ങളുടെ പ്രൊഫൈൽ വിവരം മറ്റുള്ളവർക്ക് അയയ്ക്കാനും അപ്ലിക്കേഷന് കഴിഞ്ഞേക്കാമെന്നാണ് ഇതിനർത്ഥം."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"ശാരീര സെൻസറുകൾ (ഹൃദയമിടിപ്പ് നിരക്ക് മോണിറ്ററുകൾ പോലെ)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"ഹൃദയമിടിപ്പിന്റെ നിരക്കുപോലെ നിങ്ങളുടെ ശരീരത്തിനുള്ളിൽ സംഭവിക്കുന്ന കാര്യങ്ങൾ കണക്കാക്കാൻ ഉപയോഗിക്കുന്ന സെൻസറുകളിൽനിന്ന് ഡാറ്റ ആക്സസ്സുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"നിങ്ങളുടെ ഹൃദയമിടിപ്പ് പോലുള്ള ശാരീരികാവസ്ഥ നിരീക്ഷിക്കാൻ സെൻസറുകളിൽ നിന്ന് വിവരം ആക്സസ്സുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"നിങ്ങളുടെ സോഷ്യൽ സ്ട്രീം വായിക്കുക"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"നിങ്ങളിൽ നിന്നും സുഹൃത്തുക്കളിൽ നിന്നും സോഷ്യൽ അപ്ഡേറ്റുകൾ ആക്സസ്സുചെയ്യാനും സമന്വയിപ്പിക്കാനും അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. വിവരം പങ്കിടുമ്പോൾ ജാഗ്രത പാലിക്കുക -- ഇത് സോഷ്യൽ നെറ്റ്വർക്കുകളിൽ നിങ്ങൾക്കും സുഹൃത്തുക്കൾക്കും ഇടയിലുള്ള ആശയവിനിമയങ്ങൾ രഹസ്യാത്മകത പരിഗണിക്കാതെ റീഡുചെയ്യാൻ അപ്ലിക്കേഷനെ അനുവദിക്കുന്നു. ശ്രദ്ധിക്കുക: ഈ അനുമതി എല്ലാ സോഷ്യൽ നെറ്റ്വർക്കുകളിലും നടപ്പിലാക്കാനിടയില്ല."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"നിങ്ങളുടെ സോഷ്യൽ സ്ട്രീമിലേക്ക് എഴുതുക"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> തിരഞ്ഞെടുത്തു"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ഇല്ലാതാക്കി"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"ഔദ്യോഗികം <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"ഈ സ്ക്രീൻ അൺപിൻ ചെയ്യാൻ \'മടങ്ങുക\', \'ചുരുക്കവിവരണം\' എന്നിവ ഒരേ സമയം സ്പർശിച്ച് പിടിക്കുക."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"ഈ സ്ക്രീൻ അൺപിൻ ചെയ്യാൻ, ചുരുക്കവിവരണം സ്പർശിച്ച് പിടിക്കുക."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"ഈ സ്ക്രീൻ അൺപിൻ ചെയ്യാൻ \'മടങ്ങുക\', \'കാഴ്ച\' എന്നിവ ഒരേ സമയം സ്പർശിച്ച് പിടിക്കുക."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"ഈ സ്ക്രീൻ അൺപിൻ ചെയ്യാൻ, കാഴ്ച സ്പർശിച്ച് പിടിക്കുക."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"സ്ക്രീൻ പിൻ ചെയ്തിരിക്കുന്നു. നിങ്ങളുടെ ഓർഗനൈസേഷൻ അൺപിൻ ചെയ്യൽ അനുവദിക്കുന്നില്ല."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"സ്ക്രീൻ പിൻ ചെയ്യൽ ഉപയോഗിക്കണോ?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"സ്ക്രീൻ പിൻ ചെയ്യൽ, ഒരൊറ്റ കാഴ്ചയിൽ ഡിസ്പ്ലേയെ ലോക്കുചെയ്യുന്നു.\n\nഅൺപിൻ ചെയ്യാൻ \'മടങ്ങുക\', \'ചുരുക്കവിവരണം\' എന്നിവ ഒരേ സമയം സ്പർശിച്ച് പിടിക്കുക."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"സ്ക്രീൻ പിൻ ചെയ്യൽ, ഒരൊറ്റ കാഴ്ചയിൽ ഡിസ്പ്ലേയെ ലോക്കുചെയ്യുന്നു.\n\nഅൺപിൻ ചെയ്യാൻ, ചുരുക്കവിവരണം സ്പർശിച്ച് പിടിക്കുക."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"സ്ക്രീൻ പിൻ ചെയ്യൽ, ഒരൊറ്റ കാഴ്ചയിൽ ഡിസ്പ്ലേയെ ലോക്കുചെയ്യുന്നു.\n\nഅൺപിൻ ചെയ്യാൻ \'മടങ്ങുക\', \'കാഴ്ച\' എന്നിവ ഒരേ സമയം സ്പർശിച്ച് പിടിക്കുക."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"സ്ക്രീൻ പിൻ ചെയ്യൽ, ഒരൊറ്റ കാഴ്ചയിൽ ഡിസ്പ്ലേയെ ലോക്കുചെയ്യുന്നു.\n\nഅൺപിൻ ചെയ്യാൻ, കാഴ്ച സ്പർശിച്ച് പിടിക്കുക."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"വേണ്ട, നന്ദി"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"ആരംഭിക്കുക"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"സ്ക്രീൻ പിൻ ചെയ്തു"</string> diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml index a82fb50d488a..0368a980038d 100644 --- a/core/res/res/values-mn-rMN/strings.xml +++ b/core/res/res/values-mn-rMN/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"та өөрийн харилцагчийн картыг өөрчлөх"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Апп нь таны нэр болон холбоо барих мэдээлэл зэрэг таны төхөөрөмж дээр хадгалагдсан хувийн профайл мэдээллийг солих эсвэл нэмэх боломжтой. Ингэснээр апп нь танийг таньж чадах ба таны профайл мэдээллийг бусдад илгээх боломжтой."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"биеийн сенсор (зүрхний цохилт хянагч гэх мэт)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Зүрхний цохилт гэх мэт биеийн үзүүлэлт хэмждэг сенсоруудын дата-д хандалт хийх боломжийг апп-д олгоно."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Апп-т таны зүрхний цохилт гэх мэт биеийн байдлыг хянадаг мэдрэгчдийн датанд хандалт хийх боломж олгоно."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"таны нийтийн урсгалаас унших"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Апп нь та болон таны найзуудын нийтийн шинэчлэлтэд хандах болон синк хийх боломжтой. Мэдээлэл хуваалцахдаа болгоомжтой байна уу - энэ нь апп-д нийтийн сүлжээндэх та болон таны найзууд хоорондын холбоог нууц эсэхээс үл хамааран унших боломжтой. Анхаар: энэ зөвшөөрөл нь бүх нийтийн сүлжээнд ашиглаж боломжгүй."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Таны нийтийн урсгалруу бичих"</string> diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml index 839230577ef1..90f23945d940 100644 --- a/core/res/res/values-mr-rIN/strings.xml +++ b/core/res/res/values-mr-rIN/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"आपल्या स्वतःचे संपर्क कार्ड सुधारित करा"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"आपल्या डिव्हाइसवर संचयित केलेली वैयक्तिक माहिती बदलण्यासाठी किंवा जोडण्यासाठी अॅप ला अनुमती देते. म्हणजेच अॅप आपल्याला ओळखू शकतो आणि इतरांना आपली प्रोफाईल माहिती पाठवू शकतो."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"(हृदय गती मॉनिटरसारखे) शरीर सेन्सर"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"आपल्या शरीरात काय होत आहे जसे की हृदय गती, मोजण्यासाठी आपण वापरता त्या सेन्सरकडील डेटावर प्रवेश करण्यासाठी अॅप ला अनुमती देते."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"हृदय गती सारख्या, आपल्या शारीरिक स्थितीचे नियंत्रण करणार्या सेन्सरवरून डेटामध्ये प्रवेश करण्यासाठी अॅपला अनुमती देते."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"आपला सामाजिक प्रवाह वाचा"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"आपल्याकडील आणि आपल्या मित्रांकडील सामाजिक अद्यतनांवर प्रवेश करण्यास आणि त्यांचे संकालन करण्यास अॅप ला अनुमती देते. माहिती सामायिक करताना सावधगिरी बाळगा -- हे गोपनीयतेकडे दुर्लक्ष करून, आपण आणि सामाजिक नेटवर्कवरील आपल्या मित्रांमधील संप्रेषणे वाचण्यास अॅप ला अनुमती देते. टीप: या परवानगीची अंमलबजावणी सर्व सामाजिक नेटवर्कवर होऊ शकत नाही."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"आपल्या सामाजिक प्रवाहावर लिहा"</string> diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml index 2a6ef3713bab..bebee52e090d 100644 --- a/core/res/res/values-ms-rMY/strings.xml +++ b/core/res/res/values-ms-rMY/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"ubah suai kad kenalan sendiri"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Membenarkan apl menukar atau menambah maklumat profil peribadi yang disimpan pada peranti anda, seperti nama dan maklumat kenalan anda. Ini bermakna apl boleh mengenal pasti anda dan menghantar maklumat profil anda kepada orang lain."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"penderia (spt. denyut jantung)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Membenarkan apl mengakses data dari penderia yang anda gunakan untuk mengukur perkara yang berlaku dalam tubuh anda, seperti kadar denyutan jantung."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Membenarkan apl mengakses data dari penderia yang memantau keadaan fizikal anda, seperti kadar denyutan jantung anda."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"baca aliran sosial anda"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Membenarkan apl mengakses dan menyegerakkan kemas kini sosial daripada anda dan rakan anda. Berhati-hati semasa berkongsi maklumat - ini membenarkan apl untuk membaca komunikasi di antara anda dan rakan anda pada rangkaian sosial tanpa mengira kerahsiaan. Nota: kebenaran ini tidak boleh dikuatkuasakan pada semua rangkaian sosial."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"tulis ke aliran sosial anda"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> dipilih"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> dipadamkan"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"Kerja <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Untuk menyahsemat skrin ini, sentuh dan tahan Kembali serta Gambaran Keseluruhan pada masa yang sama."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Untuk menyahsemat skrin ini, sentuh dan tahan Gambaran Keseluruhan."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Untuk menyahsemat skrin ini, sentuh dan tahan Kembali serta Ikhtisar pada masa yang sama."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Untuk menyahsemat skrin ini, sentuh dan tahan Ikhtisar."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Skrin disemat. Menyahsemat tidak dibenarkan oleh organisasi anda."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Gunakan penyematan skrin?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"Penyematan skrin mengunci paparan dalam pandangan tunggal.\n\nUntuk menyahsemat, sentuh dan tahan Kembali serta Gambaran Keseluruhan pada masa yang sama."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Penyematan skrin mengunci paparan dalam pandangan tunggal.\n\nUntuk menyahsemat, sentuh dan tahan Gambaran Keseluruhan."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"Penyematan skrin mengunci paparan dalam pandangan tunggal.\n\nUntuk menyahsemat, sentuh dan tahan Kembali serta Ikhtisar pada masa yang sama."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Penyematan skrin mengunci paparan dalam pandangan tunggal.\n\nUntuk menyahsemat, sentuh dan tahan Ikhtisar."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"TIDAK, TERIMA KASIH"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"MULA"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Skrin disemat"</string> diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml index a7c799904224..2a8bd765be75 100644 --- a/core/res/res/values-my-rMM/strings.xml +++ b/core/res/res/values-my-rMM/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"သင့်ရဲ့ အဆက်အသွယ်ကဒ် အား ပြင်ရန်"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"အပလီကေးရှင်းအား စက်မှာ သိမ်းထားသော သင့်နာမည် နှင့် အဆက်အသွယ် သတင်းအချက်အလက်များကဲ့သို့သော ကိုယ်ရေးကိုယ်တာ အချက်အလက်များအား ပြင်ဆင်ခွင့် သို့ ထည့်ခွင့် ပြုခြင်း။ အပလီကေးရှင်းမှ သင့်အား သိရှိနိုင်ပြီး သင့်ကိုယ်ရေးအချက်အလက်များအား အခြားသူများကို ပေးပို့နိုင်ပါသည်"</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"ခန္ဓာကိုယ် အာရံခံကိရိယာများ (နှလုံးခုန်နှုန်း စောင့်ကြည့်စက် လို)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"appအား သင့် ခန္ဓာကိုယ် အတွင်းမှာ၊ နှလုံးခုန်နှုန်းလို၊ ဘာတွေ ဖြစ်ပျက်နေကြောင်းကို တိုင်းထွာရန် အသုံးပြုသည့် အာရုံခံကိရိယာများ ထံမှ ဒေတာများကို ရယူသုံးခွင့် ပေးထားသည်။"</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"သင်၏ နှလုံးခုန်နှုန်းလို ရုပ်ပိုင်း အခြေအနေကို စောင့်ကြပ်သည့် အာရုံခံစက်များထံမှ ဒေတာများကို appအား ရယူသုံးခွင့် ပြုပါ။"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"သင့်လူမှုရေးရာအဖွဲ့အစည်းတွင်ရေးသားရန်"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"အပလီကေးရှင်းအား သင်နှင့် သင့်သူငယ်ချင်းတို့၏ ဆိုရှယ်နက်ဝဘ်မှ နောက်ဆုံးပေါ် အချက်အလက်များအား အသုံးပြုခွင့်နင့် ထပ်တူညီအောင် လုပ်ဆောင်ခွင့် ပြုပါ။ သတင်းအချက်အလက် မျှဝေခြင်းတွင် သတိပြုရန် -- ဤသို့ ခွင့်ပြုခြင်းဖြင့် အပလီကေးရှင်းမှ ယုံကြည်စိတ်ချရမှုကို ဂရုမပြုပဲ သင် နှင့် သူငယ်ချင်းများကြား ဆက်သွယ်မှုများအား သိရှိနိုင်ပါသည်။ မှတ်ချက်။ ဤခွင့်ပြုချက်အား ဆိုရှယ်နက်ဝဘ် အားလုံးတွင် ခွင့်ပြုခြင်း မလုပ်သင့်ပါ။"</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"သင့်လူမှုရေးရာအဖွဲ့အစည်းတွင်ရေးသားရန်"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 7ae95c40a1fe..a9d8b118b67d 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"endre ditt eget kontaktkort"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Lar appen endre eller legge til personlig profilinformasjon som er lagret på enheten din, som for eksempel navn og kontaktinformasjon. Dette betyr at appen kan identifisere deg og sende profilinformasjonen din til andre."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"kroppssensorer (som pulsmålere)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Gir appen tillatelse til å bruke data fra sensorer du bruker til å måle det som skjer i kroppen din, som f.eks. pulsen."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Gir appen tilgang til data fra sensorer som overvåker den fysiske tilstanden din, for eksempel hjertefrekvensen din."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"lese din sosiale strøm"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Lar appen lese og synkronisere sosiale oppdateringer fra deg selv og vennene dine. Vær forsiktig når du deler informasjon - med denne tillatelsen kan appen lese kommunikasjon mellom deg og vennene dine på sosiale nettverk, uavhengig av konfidensialitet. Vær oppmerksom på at denne tillatelsen kanskje ikke gjelder for alle sosiale nettverk."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skrive i din sosiale strøm"</string> @@ -1757,10 +1757,10 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> er valgt"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> er slettet"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"Jobb-<xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Hvis du vil avslutte modusen for denne skjermen, trykker og holder du på Tilbake og Oversikt samtidig."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Hvis du vil avslutte modusen for denne skjermen, trykker og holder du på Oversikt."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Hvis du vil avslutte én-appsmodusen for denne skjermen, trykker og holder du på Tilbake og Oversikt samtidig."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Hvis du vil avslutte én-appsmodusen for denne skjermen, trykker og holder du på Oversikt."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Skjermen er festet. Løsning er ikke tillatt av organisasjonen din."</string> - <string name="lock_to_app_title" msgid="1682643873107812874">"Vil du bruke skjermfesting?"</string> + <string name="lock_to_app_title" msgid="1682643873107812874">"Vil du bruke én-appsmodus?"</string> <string name="lock_to_app_description" msgid="4120623404152035221">"Én-appsmodus låser skjermen til én bestemt side.\n\nHvis du vil avslutte modusen, trykker og holder du på Tilbake og Oversikt samtidig."</string> <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Én-appsmodus låser skjermen til én bestemt side.\n\nHvis du vil avslutte modusen, trykker og holder du på Oversikt."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"NEI TAKK"</string> diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml index 43ab64539eb0..fd1173c1af29 100644 --- a/core/res/res/values-ne-rNP/strings.xml +++ b/core/res/res/values-ne-rNP/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"तपाईँको आफ्नै सम्पर्क कार्ड परिमार्जन गर्नुहोस्"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"तपाईँको उपकरणमा भण्डार भएको व्याक्तिगत प्रोफाइल जानकारी, जस्तै तपाईँको नाम वा सम्पर्क जानकारीलाई परिवर्तन गर्न वा थप्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। यसको मतलब अन्य अनुप्रयोगले तपाईँलाई चिन्न सक्छन् र सायद अन्यलाई तपाईँको प्रोफाइल जानकारी पठाउन सक्छन्।"</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"शरीर सेन्सर (हृदयदर मोनिटर जस्तै)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"हृदयदर झैं तपाईँको आफ्नो शरीरभित्र के भइरहेकोछ मापन गर्न प्रयोग सेन्सर द्वारा डेटा पहुँच गर्न अनुप्रयोगलाई अनुमति दिन्छ।"</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"तपाईँको हृदय गति जस्तो सेंसर बाट डेटा पहुँचको लागि अनुप्रयोग अनुमति दिन्छ जसले तपाईँको भौतिक अवस्था अनुगमन गर्छ।"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"तपाईंको सामाजिक स्ट्रिम पढ्नुहोस्"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"तपाईँ र तपाईँका साथीहरूबाट सामाजिक अपडेटलाई पहुँच र सिंक गर्नको लागि अनुप्रयोगलाई अनुमति दिन्छ। जानकारी साझेदारी गर्दा सावधान रहनुहोस् -- समाजिक नेटवर्कहरूमा तपाईँ र तपाईँको साथीको बिचमा भएका संचारलाई पढ्न विश्वासनीयता बेगरै यसले अनुप्रयोगलाई अनुमति दिन्छ। नोट: यो अनुमति बलपूर्वक सबै सामाजिक नेटवर्कहरूमा सायद नगर्न सकिन्छ।"</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"तपाईँको सामाजिक प्रवाहमा लेख्नुहोस्"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 228587a7160c..97744bbd58aa 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"uw eigen contactkaart aanpassen"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Hiermee kan de app persoonlijke profielgegevens wijzigen of toevoegen die op uw apparaat zijn opgeslagen, zoals uw naam en contactgegevens. Dit betekent dat de app u kan identificeren en uw profielgegevens naar anderen kan verzenden."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"lichaamssensoren (zoals hartslagmeters)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Toestaan dat de app toegang krijgt tot gegevens van sensoren die u gebruikt om te meten wat er gebeurt in uw lichaam, zoals de hartslag."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Hiermee kan de app toegang krijgen tot gegevens van sensoren die uw lichamelijke conditie controleren, zoals uw hartslag."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"uw sociale stream lezen"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Hiermee kan de app toegang krijgen tot sociale updates van u en uw vrienden en deze synchroniseren. Wees voorzichtig bij het delen van informatie: hiermee kan de app communicatie lezen tussen u en uw vrienden op sociale netwerken, ongeacht de vertrouwelijkheid. Opmerking: deze toestemming kan niet worden afgedwongen voor alle sociale netwerken."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"schrijven naar sociale streams"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 84c234338e27..f52f4059de67 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"zmiana własnej karty kontaktu"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Pozwala aplikacji na zmianę lub dodanie osobistych informacji przechowywanych w Twoim profilu na urządzeniu (np. imienia i nazwiska lub adresu). Oznacza to, że aplikacja może Cię zidentyfikować i wysłać informacje z Twojego profilu do innych osób."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"czujniki ciała (np. monitorujące tętno)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Zezwala aplikacji na dostęp do danych z czujników mierzących procesy zachodzące w ciele, np. bicie serca (tętno)."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Pozwala aplikacji na dostęp do danych z czujników, które monitorują Twój stan fizyczny (np. tętno)."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"odczyt sieci społecznościowych"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Pozwala aplikacji na odczyt i synchronizację informacji publikowanych przez Ciebie i Twoich znajomych w sieciach społecznościowych. Zachowaj ostrożność, udostępniając informacje. Aplikacja z tym uprawnieniem może odczytać całą komunikację, którą prowadzisz ze swoimi znajomymi w sieciach społecznościowych, niezależnie od jej poufności. Uwaga: to uprawnienie może nie być egzekwowane we wszystkich sieciach społecznościowych."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"zapis sieci społecznościowych"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index fc2bb37112ae..48a8f2fa1c43 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"modificar o próprio cartão de contacto"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permite que a aplicação altere ou adicione dados de perfil pessoais guardados no dispositivo, tais como o seu nome e informações de contacto. Isto significa que outras aplicações podem identificá-lo e enviar os seus dados de perfil a terceiros."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"sensores corporais (como monitores do ritmo cardíaco)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Permite à aplicação aceder a dados de sensores que o utilizador usa para medir o que está a acontecer no seu corpo, por exemplo o ritmo cardíaco."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite que a aplicação aceda a dados de sensores que monitorizam a sua condição física, como o ritmo cardíaco."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ler o seu fluxo social"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permite que a aplicação aceda e sincronize atualizações de redes sociais suas e dos seus amigos. Tenha cuidado ao partilhar informações, pois esta ação permite que a aplicação leia comunicações entre si e os seus amigos nas redes sociais, independentemente do grau de confidencialidade. Nota: esta autorização pode não ser aplicada a todas as redes sociais."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escrever para o seu fluxo social"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 972e60121820..708f5260a1a5 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"mod. próprio cartão contato"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permite que o app altere ou adicione informações pessoais de perfil armazenadas em seu dispositivo, como seu nome e informações de contato. Isso significa que o app pode identificá-lo e enviar as informações de seus perfil para terceiros."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"sensores corporais"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Permite que o app acesse dados de sensores usados para medir o que acontece em seu corpo, como seus batimentos cardíacos."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite que o app acesse dados de sensores que monitoram sua condição física, como a frequência cardíaca."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ler suas transmissões sociais"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permite que o app acesse e sincronize suas atualizações sociais e as de seus amigos. Tenha cuidado ao compartilhar informações: isto permite que o app leia as mensagens trocadas por você e seus amigos em redes sociais, independentemente de sua confidencialidade. Obsservaç: pode não ser aplicável a todas as redes sociais."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"escrever p/ suas transm. soc."</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 113921c5dada..6413218c85b1 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"modifică cartea dvs. de vizită"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Permite aplicaţiei să schimbe sau să adauge conţinut în informaţiile personale din profil stocate pe dispozitivul dvs., cum ar fi numele şi informaţiile dvs. de contact. Aceasta înseamnă că aplicaţia vă poate identifica şi poate trimite informaţiile din profilul dvs. altor persoane."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"senzori (ex.: senzori de ritm cardiac)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Permite aplicației să acceseze datele de la senzorii pe care îi utilizați pentru a măsura funcțiile corpului, cum ar fi ritmul cardiac."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Permite aplicației să acceseze date de la senzorii care vă monitorizează starea fizică, cum ar fi ritmul cardiac."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"citeşte fluxul social"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Permite aplicaţiei să acceseze şi să sincronizeze actualizările sociale de la dvs. şi de la prietenii dvs. Daţi dovadă de precauţie când distribuiţi informaţii - cu această permisiune aplicaţia citeşte comunicările realizate între dvs. şi prietenii dvs. în reţelele sociale, indiferent de gradul de confidenţialitate a acestora. Notă: această permisiune nu poate fi aplicată pentru toate reţelele sociale."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"scrie în fluxul social"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index e9ce7dc6fcf0..344e40832246 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"Изменение ваших контактных данных"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Приложение сможет изменять вашу личную информацию (например, имя и контактные данные), сохраненную на устройстве. Получив эти данные, приложение сможет отправить их другим пользователям."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"датчики (например, пульсометр)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Приложение получит доступ к данным приборов, используемых для измерения ваших физиологических показателей (например, пульса)."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Приложение сможет получить доступ к данным датчиков, размещенных на теле, например измеряющих частоту сердцебиения."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"Просмотр записей в вашей социальной ленте"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Приложение сможет просматривать и синхронизировать записи, публикуемые вами и вашими друзьями в социальных сетях. Будьте осторожны при передаче информации! С этим разрешением приложение сможет просматривать вашу переписку с друзьями в социальных сетях независимо от настроек конфиденциальности. Примечание. Это разрешение может применяться не во всех социальных сетях."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"Добавление записей в вашу социальную ленту"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"Выбран элемент <xliff:g id="ITEM">%1$s</xliff:g>"</string> <string name="deleted_key" msgid="7659477886625566590">"Цифра <xliff:g id="KEY">%1$s</xliff:g> удалена"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"Рабочий <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Чтобы открепить экран, нажмите и удерживайте клавишу \"Назад\" и кнопку \"Обзор\" одновременно."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Чтобы открепить экран, нажмите и удерживайте кнопки \"Назад\" и \"Обзор\" одновременно."</string> <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Чтобы открепить экран, нажмите и удерживайте кнопку \"Обзор\"."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Блокировка включена. Ее отключение запрещено правилами организации."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Использовать блокировку в приложении?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"Функция закрепления позволяет зафиксировать текущий экран.\n\nЧтобы открепить его, нажмите и удерживайте клавишу \"Назад\" и кнопку \"Обзор\" одновременно."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Функция закрепления позволяет зафиксировать текущий экран.\n\nЧтобы открепить его, нажмите и удерживайте кнопку \"Обзор\"."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"Функция блокировки в приложении позволяет зафиксировать текущий экран.\n\nЧтобы снять блокировку, нажмите и удерживайте кнопки \"Назад\" и \"Обзор\" одновременно."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Функция блокировки в приложении позволяет зафиксировать текущий экран.\n\nЧтобы снять блокировку, нажмите и удерживайте кнопку \"Обзор\"."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"НЕТ"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"ДА"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Блокировка включена"</string> diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml index 2506797d5ed2..5b54939115ae 100644 --- a/core/res/res/values-si-rLK/strings.xml +++ b/core/res/res/values-si-rLK/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"ඔබගේ සම්බන්ධතා පත වෙනස් කිරීම"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ඔබගේ නම සහ සම්බන්ධතා තොරතුරු වැනි ඔබගේ උපාංගයේ ආචයනය කරන ලද පුද්ගලික පැතිකඩ තොරතුරු වෙනස් කිරීමට හෝ එකතු කිරීමට යෙදුමට අවසර දෙන්න. මෙමගින් යෙදුමට ඔබව හඳුනා ගත හැකි අතර අනෙක් අයට ඔබගේ පැතිකඩ තොරතුරු යැවිය හැකි බව කියවෙයි."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"සිරුර සංවේදකයන් (හෘද ස්පන්දන වේගය නිරීක්ෂණය කිරීම වැනි)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"හෘද ස්පන්දන වේගය වැනි ඔබගේ සිරුර තුළ සිදුවන්නේ කුමක් දැයි මැනීමට ඔබ භාවිත කරන සංවේදකයන්ගෙන් දත්ත ලබාගැනීමට යෙදුමට ඉඩ ලබාදෙන්න."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"හෘද ස්පන්දන වේගය වැනි ඔබගේ ශාරීරික තත්ත්වය නිරීක්ෂණය කරන සංවේදක වලින් දත්ත ලබාගැනීමට යෙදුමට ඉඩ දෙන්න."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ඔබගේ සමාජ ප්රවාහය කියවන්න"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ඔබගේ සහ ඔබගේ යහළුවන්ගේ සමාජ යාවත්කාලීනයන් වෙත පිවිසීමට හෝ සමමුහුර්ත කිරීමට යෙදුමට අවසර දෙන්න. තොරතුරු බෙදා ගැනීමේ දී සැලකිලිමත් වන්න -- විශ්වාසයකින් තොරව සමාජ ජාලවල ඔබගේ සහ ඔබගේ යහළුවන් අතර සන්නිවේදන කියවීමට මෙමගින් යෙදුමට අවසර දෙයි. සටහන: සියලු සමාජ ජාලවල මෙම අවසරය බල නොකරයි."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ඔබගේ සමාජ ප්රවාහය වෙත ලිවීම"</string> @@ -1759,16 +1759,12 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> තෝරාගෙන ඇත"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> මකා දමන ලදි"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"වැඩ <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <!-- no translation found for lock_to_app_toast (7570091317001980053) --> - <skip /> - <!-- no translation found for lock_to_app_toast_accessible (8239120109365070664) --> - <skip /> + <string name="lock_to_app_toast" msgid="7570091317001980053">"මෙම තීරයේ ඇමුණුම ඉවත් කිරීමට, Back සහ Overview එකම වේලාවේ ස්පර්ශ කර අල්ලා සිටින්න."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"මෙම තීරයේ ඇමුණුම ඉවත් කිරීමට, Overview ස්පර්ශ කර අල්ලා සිටින්න."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"තිරය අගුළු දමා ඇත. ඔබගේ සංවිධානය විසින් අගුළු ඇරීමට ඉඩ නොදෙයි."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"තිරය අගුළු දැමීම භාවිත කරනවාද?"</string> - <!-- no translation found for lock_to_app_description (4120623404152035221) --> - <skip /> - <!-- no translation found for lock_to_app_description_accessible (199664191087836099) --> - <skip /> + <string name="lock_to_app_description" msgid="4120623404152035221">"තනි පෙනුම තුළ දර්ශනය තීර ඇමුණුමෙන් අගුළු දමයි.\n\nඇමුණුම ඉවත් කිරීමට, Back සහ Overview එකම වේලාවේ ස්පර්ශ කර අල්ලා සිටින්න."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"තනි පෙනුම තුළ දර්ශනය තීර ඇමුණුමෙන් අගුළු දමයි.\n\nඇමුණුම ඉවත් කිරීමට, Overview ස්පර්ශ කර අල්ලා සිටින්න."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"නැත, ස්තූතියි"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"ආරම්භය"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"තිරය අගුළු දමා ඇත"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index d67fb2ef04e3..53d6aeaf96fc 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"upraviť vlastnú kartu kontaktu"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Umožňuje aplikácii zmeniť alebo pridať do osobného profilu informácie uložené vo vašom zariadení, ako je vaše meno a kontaktné informácie. Znamená to, že vás aplikácia môže identifikovať a odoslať informácie o vašom profile ostatným aplikáciám."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"telesné senzory (napr. snímače tepu)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Umožňuje aplikácii pristupovať k údajom zo senzorov, pomocou ktorých meriate činnosť svojho tela, napríklad tep."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Umožňuje aplikácii získať prístup k údajom senzorov monitorujúcich vašu fyzickú kondíciu (napríklad pulz)."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"čítať váš sociálny stream"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Umožňuje aplikácii pristupovať k sociálnym aktualizáciám od vás a vašich priateľov a synchronizovať ich. Pri zdieľaní informácií dávajte pozor – toto povolenie umožňuje aplikácii čítať komunikáciu medzi vami a vašimi priateľmi v sociálnych sieťach, a to bez ohľadu na jej dôvernosť. Poznámka: Toto povolenie nie je možné vynucovať v prípade všetkých sociálnych sietí."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"písať do vášho sociálneho streamu"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 6cfa2342df0a..b76757fdbcf3 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"spreminj. vaše osebne vizitke"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Aplikaciji omogoča spreminjanje ali dodajanje osebnih podatkov v profilu, ki so shranjeni v napravi, na primer ime in podatki za stik. To pomeni, da vas lahko aplikacija prepozna in vaše podatke v profilu pošlje drugim."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"tipala telesnih funkcij (npr. merilniki srčnega utripa)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Aplikaciji dovoli dostop do podatkov tipal, ki jih uporabljate za merjenje procesov v telesu, kot je srčni utrip."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Aplikaciji omogoča dostop do podatkov tipal, ki nadzirajo vaše fizično stanje, med drugim vaš srčni utrip."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"branje vašega družabnega toka"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Aplikaciji omogoča dostop do vaših objav in objav vaših prijateljev v družabnih omrežjih ter njihovo sinhronizacijo. Previdno pri objavljanju informacij – aplikacija lahko s tem bere komunikacijo med vami in prijatelji v družabnih omrežjih, ne glede na zasebnost. Opomba: Tega dovoljenja ni mogoče uveljaviti v vseh družabnih omrežjih."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"pisanje v vaš družabni tok"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"Izbrano: <xliff:g id="ITEM">%1$s</xliff:g>"</string> <string name="deleted_key" msgid="7659477886625566590">"Številka <xliff:g id="KEY">%1$s</xliff:g> je izbrisana"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> za delo"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Če želite odpeti ta zaslon, se hkrati dotaknite tipk za nazaj in za pregled ter ju pridržite."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Če želite odpeti ta zaslon, se dotaknite tipke za pregled in jo pridržite."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Če želite odpeti ta zaslon, se hkrati dotaknite tipk Nazaj in Pregled ter ju pridržite."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Če želite odpeti ta zaslon, se dotaknite tipke Pregled in jo pridržite."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Zaslon je pripet. Vaša organizacija ne dovoli odpenjanja."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Želite uporabljati pripenjanje zaslona?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"Pripenjanje zaslonov zaklene zaslon v enojnem pogledu.\n\nČe ga želite odpeti, se hkrati dotaknite tipk za nazaj in za pregled ter ju pridržite."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Pripenjanje zaslonov zaklene zaslon v enojnem pogledu.\n\nČe ga želite odpeti, se dotaknite tipke za pregled in jo pridržite."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"Pripenjanje zaslonov zaklene zaslon v enojnem pogledu.\n\nČe ga želite odpeti, se hkrati dotaknite tipk Nazaj in Pregled ter ju pridržite."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Pripenjanje zaslonov zaklene zaslon v enojnem pogledu.\n\nČe ga želite odpeti, se dotaknite tipke Pregled in jo pridržite."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"NE, HVALA"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"ZAŽENI"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Zaslon je pripet"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index fe195108cafb..de0f5b1dcbb3 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"измена ваше контакт картице"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Дозвољава апликацији да мења или додаје нове личне информације о профилу ускладиштене на уређају, као што су име и контакт информације. То значи да апликација може да вас идентификује и шаље другима информације о профилу."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"телесни сензори (нпр. срчани монитор)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Дозвољава апликацији да приступа подацима сензора које користите за мерење телесних функција, као што је срчани пулс."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Дозвољава апликацији да приступа подацима са сензора који надгледају физичку кондицију, као што је број откуцаја срца."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"читање друштвеног стрима"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Дозвољава апликацији да приступа вашим друштвеним ажурирањима и друштвеним ажурирањима пријатеља и да их синхронизује. Будите опрезни када делите информације – ово омогућава апликацији да чита преписке између вас и пријатеља на друштвеним мрежама, без обзира на поверљивост. Напомена: Ова дозвола се можда не примењује на све друштвене мреже."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"писање у друштвени стрим"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 14a00a42ab71..d39a72275c63 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"ändra ditt eget kontaktkort"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Tillåter att appen ändrar eller lägger till personliga profiluppgifter som sparats på din enhet, till exempel ditt namn och dina kontaktuppgifter. Det innebär att appen kan identifiera dig och skicka profiluppgifter till andra."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"kroppssens. (för hjärtat m.m.)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Tillåter att appen får åtkomst till data från sensorer som används för att mäta vad som sker inuti kroppen, till exempel hjärtfrekvens."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ger appen åtkomst till information från sensorer om ditt fysiska tillstånd, till exempel din puls."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"läs mitt sociala flöde"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Tillåter att appen kommer åt och synkroniserar sociala uppdateringar från dig och dina vänner. Var försiktig när du delar information – med den här behörigheten tillåts appen att läsa kommunikation mellan dig och dina vänner på sociala nätverk oavsett sekretessnivå. Observera att den här behörigheten kanske inte är tillämplig på alla sociala nätverk."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"skriv till mitt sociala flöde"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 727e6b5801fc..00a45b457370 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"rekebisha kadi yako mwenyewe ya mawasiliano"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Inaruhusu programu kubadilisha au kuongeza taarifa ya maelezo mafupi ya kibinafsi yaliyohifadhiwa kwenye kifaa chako, kama vile jina lako na taarifa ya anwani. Hii inamaanisha kuwa programu inaweza kukutambua na inaweza kutuma taarifa ya maelezo yako mafupi kwa wengine."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"vipima hali ya mwili (kama mpigo wa moyo)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Huruhusu programu kufikia data kutoka kwenye vipima mawimbi unavyotumia kupima kinachoendelea mwilini mwako kama vile mpigo wa moyo."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Huruhusu programu kufikia data kutoka vihisi vinavyofuatilia hali yako ya kimwili, kama vile mapigo ya moyo."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"soma mipasho yako wa kijamii"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Huruhusu programu kufikia na kupatanisha masasisho ya kijamii kutoka kwa marafiki zako. Kuwa makini wakati unashiriki taarifa -- hii huruhusu programu kusoma mawasiliano kati yako na marafiki zako kwenye mitandao jamii, bila kujali usiri. Kumbuka: idhini hii haiwezi kutekelezwa kwenye mitandao yote ya jamii."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"kuandikia mipasho yako wa kijamii"</string> diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml index ee9bad8318a2..821de0c79782 100644 --- a/core/res/res/values-ta-rIN/strings.xml +++ b/core/res/res/values-ta-rIN/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"உங்கள் சொந்த தொடர்பு அட்டையை மாற்றுதல்"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"உங்கள் சாதனத்தில் சேமிக்கப்பட்ட உங்கள் பெயர் மற்றும் தொடர்பு தகவல் போன்ற தனிப்பட்ட சுயவிவரத் தகவலை மாற்ற அல்லது சேர்க்க பயன்பாட்டை அனுமதிக்கிறது. அதாவது பயன்பாடு உங்களை அடையாளப்படுத்தலாம், உங்கள் சுயவிவரத் தகவலை மற்றவர்களுக்கு அனுப்பலாம்."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"உடல் உணர்விகள் (இதயத்துடிப்பு கண்காணித்தல் போன்றவை)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"இதயத் துடிப்பு போன்று உங்கள் உடலில் நிகழும் மாற்றங்களை அளவிட, நீங்கள் பயன்படுத்தும் உணர்விகளிடமிருந்து தரவை அணுக, பயன்பாட்டை அனுமதிக்கிறது."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"உங்கள் இதயத்துடிப்பு விகிதம் போன்ற உங்கள் உடல்நிலையைக் கண்காணிக்கும் உணர்விகளில் இருந்து தரவை அணுக பயன்பாடுகளை அனுமதிக்கும்."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"எனது சமூக ஸ்ட்ரீமைப் படித்தல்"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"உங்களிடமிருந்தும், உங்கள் நண்பர்களிடமிருந்தும் வரும் சமூகப் புதுப்பிப்புகளை அணுகி ஒத்திசைக்கப் பயன்பாட்டை அனுமதிக்கிறது. தகவலைப் பகிரும்போது எச்சரிக்கையாக இருக்கவும் -- ரகசியத்தன்மையைப் பொருட்படுத்தாமல், சமூக நெட்வொர்க்குகளில் உங்களுக்கும், உங்கள் நண்பர்களுக்கிடையேயும் உள்ள தொடர்புகளைப் படிக்க பயன்பாட்டை அனுமதிக்கிறது. குறிப்பு: இந்த அனுமதி எல்லா சமூக நெட்வொர்க்குகளிலும் செயல்படுத்தப்படாமல் இருக்கலாம்."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"உங்கள் சமூக ஸ்ட்ரீமில் எழுதுக"</string> diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml index a4dc91413571..ea1260f90a33 100644 --- a/core/res/res/values-te-rIN/strings.xml +++ b/core/res/res/values-te-rIN/strings.xml @@ -54,17 +54,17 @@ <string name="serviceErased" msgid="1288584695297200972">"ఎరేజ్ చేయడం విజయవంతమైంది."</string> <string name="passwordIncorrect" msgid="7612208839450128715">"చెల్లని పాస్వర్డ్."</string> <string name="mmiComplete" msgid="8232527495411698359">"MMI పూర్తయింది."</string> - <string name="badPin" msgid="9015277645546710014">"మీరు టైప్ చేసిన పాత PIN చెల్లదు."</string> + <string name="badPin" msgid="9015277645546710014">"మీరు టైప్ చేసిన పాత పిన్ చెల్లదు."</string> <string name="badPuk" msgid="5487257647081132201">"మీరు టైప్ చేసిన PUK చెల్లదు."</string> <string name="mismatchPin" msgid="609379054496863419">"మీరు టైప్ చేసిన PINలు సరిపోలలేదు."</string> - <string name="invalidPin" msgid="3850018445187475377">"4 నుండి 8 సంఖ్యలు ఉండే PINను టైప్ చేయండి."</string> + <string name="invalidPin" msgid="3850018445187475377">"4 నుండి 8 సంఖ్యలు ఉండే పిన్ను టైప్ చేయండి."</string> <string name="invalidPuk" msgid="8761456210898036513">"8 సంఖ్యలు లేదా అంతకంటే పొడవు ఉండే PUKని టైప్ చేయండి."</string> - <string name="needPuk" msgid="919668385956251611">"మీ SIM కార్డు PUK-లాక్ చేయబడింది. దీన్ని అన్లాక్ చేయడానికి PUK కోడ్ను టైప్ చేయండి."</string> - <string name="needPuk2" msgid="4526033371987193070">"SIM కార్డును అన్బ్లాక్ చేయడానికి PUK2ని టైప్ చేయండి."</string> - <string name="enablePin" msgid="209412020907207950">"వైఫల్యం, SIM/RUIM లాక్ను ప్రారంభించండి."</string> + <string name="needPuk" msgid="919668385956251611">"మీ సిమ్ కార్డు PUK-లాక్ చేయబడింది. దీన్ని అన్లాక్ చేయడానికి PUK కోడ్ను టైప్ చేయండి."</string> + <string name="needPuk2" msgid="4526033371987193070">"సిమ్ కార్డును అన్బ్లాక్ చేయడానికి PUK2ని టైప్ చేయండి."</string> + <string name="enablePin" msgid="209412020907207950">"వైఫల్యం, సిమ్/RUIM లాక్ను ప్రారంభించండి."</string> <plurals name="pinpuk_attempts"> - <item quantity="one" msgid="6596245285809790142">"SIM లాక్ కాకుండా ఉండటానికి మీకు <xliff:g id="NUMBER">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది."</item> - <item quantity="other" msgid="7530597808358774740">"SIM లాక్ కాకుండా ఉండటానికి మీకు <xliff:g id="NUMBER">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి."</item> + <item quantity="one" msgid="6596245285809790142">"సిమ్ లాక్ కాకుండా ఉండటానికి మీకు <xliff:g id="NUMBER">%d</xliff:g> ప్రయత్నం మిగిలి ఉంది."</item> + <item quantity="other" msgid="7530597808358774740">"సిమ్ లాక్ కాకుండా ఉండటానికి మీకు <xliff:g id="NUMBER">%d</xliff:g> ప్రయత్నాలు మిగిలి ఉన్నాయి."</item> </plurals> <string name="imei" msgid="2625429890869005782">"IMEI"</string> <string name="meid" msgid="4841221237681254195">"MEID"</string> @@ -76,7 +76,7 @@ <string name="CwMmi" msgid="9129678056795016867">"కాల్ నిరీక్షణ"</string> <string name="BaMmi" msgid="455193067926770581">"కాల్ బేరింగ్"</string> <string name="PwdMmi" msgid="7043715687905254199">"పాస్వర్డ్ మార్పు"</string> - <string name="PinMmi" msgid="3113117780361190304">"PIN మార్పు"</string> + <string name="PinMmi" msgid="3113117780361190304">"పిన్ మార్పు"</string> <string name="CnipMmi" msgid="3110534680557857162">"కాలింగ్ నంబర్ అందుబాటులో ఉంది"</string> <string name="CnirMmi" msgid="3062102121430548731">"కాలింగ్ నంబర్ పరిమితం చేయబడింది"</string> <string name="ThreeWCMmi" msgid="9051047170321190368">"మూడు మార్గాల కాలింగ్"</string> @@ -289,11 +289,11 @@ <string name="permlab_sendRespondViaMessageRequest" msgid="8713889105305943200">"సందేశం ద్వారా ప్రతిస్పందించే ఈవెంట్లను పంపడం"</string> <string name="permdesc_sendRespondViaMessageRequest" msgid="7107648548468778734">"ఇన్కమింగ్ కాల్ల కోసం సందేశం ద్వారా ప్రతిస్పందించే ఈవెంట్లను నిర్వహించడానికి ఇతర సందేశ విధాన అనువర్తనాలకు అభ్యర్థనలను పంపడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> <string name="permlab_readSms" msgid="8745086572213270480">"మీ వచన సందేశాలు (SMS లేదా MMS) చదవడం"</string> - <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"మీ టాబ్లెట్ లేదా SIM కార్డులో నిల్వ చేయబడిన SMS సందేశాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది కంటెంట్ లేదా గోప్యతతో సంబంధం లేకుండా అన్ని SMS సందేశాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> - <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"మీ ఫోన్ లేదా SIM కార్డులో నిల్వ చేయబడిన SMS సందేశాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది కంటెంట్ లేదా గోప్యతతో సంబంధం లేకుండా అన్ని SMS సందేశాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> + <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"మీ టాబ్లెట్ లేదా సిమ్ కార్డులో నిల్వ చేయబడిన SMS సందేశాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది కంటెంట్ లేదా గోప్యతతో సంబంధం లేకుండా అన్ని SMS సందేశాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> + <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"మీ ఫోన్ లేదా సిమ్ కార్డులో నిల్వ చేయబడిన SMS సందేశాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది కంటెంట్ లేదా గోప్యతతో సంబంధం లేకుండా అన్ని SMS సందేశాలను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> <string name="permlab_writeSms" msgid="3216950472636214774">"మీ వచన సందేశాలను (SMS లేదా MMS) సవరించడం"</string> - <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"మీ టాబ్లెట్లో లేదా SIM కార్డులో నిల్వ చేసిన SMS సందేశాలను వ్రాయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ సందేశాలను తొలగించవచ్చు."</string> - <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"మీ ఫోన్లో లేదా SIM కార్డులో నిల్వ చేసిన SMS సందేశాలను వ్రాయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ సందేశాలను తొలగించవచ్చు."</string> + <string name="permdesc_writeSms" product="tablet" msgid="5160413947794501538">"మీ టాబ్లెట్లో లేదా సిమ్ కార్డులో నిల్వ చేసిన SMS సందేశాలను వ్రాయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ సందేశాలను తొలగించవచ్చు."</string> + <string name="permdesc_writeSms" product="default" msgid="7268668709052328567">"మీ ఫోన్లో లేదా సిమ్ కార్డులో నిల్వ చేసిన SMS సందేశాలను వ్రాయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. హానికరమైన అనువర్తనాలు మీ సందేశాలను తొలగించవచ్చు."</string> <string name="permlab_receiveWapPush" msgid="5991398711936590410">"వచన సందేశాలను (WAP) స్వీకరించడం"</string> <string name="permdesc_receiveWapPush" msgid="748232190220583385">"WAP సందేశాలను స్వీకరించడానికి మరియు ప్రాసెస్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి మీకు పంపబడిన సందేశాలను మీకు చూపకుండానే పర్యవేక్షించగల లేదా తొలగించగల సామర్థ్యాన్ని కలిగి ఉంటుంది."</string> <string name="permlab_receiveBluetoothMap" msgid="7593811487142360528">"బ్లూటూత్ సందేశాల స్వీకరణ (MAP)"</string> @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"మీ స్వంత సంప్రదింపు కార్డును సవరించడం"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"మీ పరికరంలో నిల్వ చేయబడిన వ్యక్తిగత ప్రొఫైల్ సమాచారాన్ని అనగా మీ పేరు మరియు సంప్రదింపు సమాచారం వంటివి మార్చడానికి లేదా జోడించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. అనువర్తనం మిమ్మల్ని గుర్తించగలదని మరియు మీ ప్రొఫైల్ సమాచారాన్ని ఇతరులకు పంపగలదని దీని అర్థం."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"శరీర సెన్సార్లు (హృదయ స్పందన మానిటర్లు వంటివి)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"మీ శరీరం లోపల జరిగే వాటిని అంటే హృదయ స్పందన వంటివి కొలవడానికి మీరు ఉపయోగించే సెన్సార్ల నుండి డేటాను ప్రాప్యత చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"మీ శారీరక పరిస్థితిని అనగా మీ గుండె స్పందన రేటు వంటి వాటిని పర్యవేక్షించే సెన్సార్ల నుండి డేటాను ప్రాప్యత చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"మీ సామాజిక ప్రసారాన్ని చదవడం"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"మీరు మరియు మీ స్నేహితులు సమర్పించిన తాజా సామాజిక విషయాలను ప్రాప్యత చేయడానికి మరియు సమకాలీకరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది. సమాచారాన్ని భాగస్వామ్యం చేస్తున్నప్పుడు జాగ్రత్తగా ఉండండి -- ఇది గోప్యతతో సంబంధం లేకుండా, మీ మధ్య మరియు మీ స్నేహితుల మధ్య జరిగిన కమ్యూనికేషన్లను చదవడానికి అనువర్తనాన్ని అనుమతిస్తుంది. గమనిక: ఈ అనుమతి అన్ని సామాజిక నెట్వర్క్ల్లో అమలు చేయబడకపోవచ్చు."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"మీ సామాజిక ప్రసారానికి వ్రాయడం"</string> @@ -541,8 +541,8 @@ <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"వాల్యూమ్ మరియు అవుట్పుట్ కోసం ఉపయోగించాల్సిన స్పీకర్ వంటి సార్వజనీన ఆడియో సెట్టింగ్లను సవరించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> <string name="permlab_recordAudio" msgid="3876049771427466323">"ఆడియోను రికార్డ్ చేయడం"</string> <string name="permdesc_recordAudio" msgid="4906839301087980680">"మైక్రోఫోన్తో ఆడియోను రికార్డ్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి మీ నిర్ధారణ లేకుండానే ఎప్పుడైనా ఆడియోను రికార్డ్ చేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> - <string name="permlab_sim_communication" msgid="1180265879464893029">"sim కమ్యూనికేషన్"</string> - <string name="permdesc_sim_communication" msgid="5725159654279639498">"SIMకు ఆదేశాలను పంపడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది చాలా ప్రమాదకరం."</string> + <string name="permlab_sim_communication" msgid="1180265879464893029">"సిమ్ కమ్యూనికేషన్"</string> + <string name="permdesc_sim_communication" msgid="5725159654279639498">"సిమ్కు ఆదేశాలను పంపడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఇది చాలా ప్రమాదకరం."</string> <string name="permlab_camera" msgid="3616391919559751192">"చిత్రాలు మరియు వీడియోలు తీయడం"</string> <string name="permdesc_camera" msgid="8497216524735535009">"కెమెరాతో చిత్రాలు మరియు వీడియోలను తీయడానికి అనువర్తనాన్ని అనుమతిస్తుంది. ఈ అనుమతి మీ నిర్ధారణ లేకుండానే ఎప్పుడైనా కెమెరాను ఉపయోగించడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> <string name="permlab_cameraDisableTransmitLed" msgid="2651072630501126222">"కెమెరా ఉపయోగంలో ఉన్నప్పుడు ప్రసరణ సూచీ LEDని నిలిపివేయడం"</string> @@ -884,14 +884,14 @@ <string name="sipAddressTypeWork" msgid="6920725730797099047">"కార్యాలయం"</string> <string name="sipAddressTypeOther" msgid="4408436162950119849">"ఇతరం"</string> <string name="quick_contacts_not_available" msgid="746098007828579688">"ఈ పరిచయాన్ని వీక్షించడానికి అనువర్తనం కనుగొనబడలేదు."</string> - <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"PIN కోడ్ను టైప్ చేయండి"</string> - <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK మరియు కొత్త PIN కోడ్ను టైప్ చేయండి"</string> + <string name="keyguard_password_enter_pin_code" msgid="3037685796058495017">"పిన్ కోడ్ను టైప్ చేయండి"</string> + <string name="keyguard_password_enter_puk_code" msgid="4800725266925845333">"PUK మరియు కొత్త పిన్ కోడ్ను టైప్ చేయండి"</string> <string name="keyguard_password_enter_puk_prompt" msgid="1341112146710087048">"PUK కోడ్"</string> - <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"కొత్త PIN కోడ్"</string> + <string name="keyguard_password_enter_pin_prompt" msgid="8027680321614196258">"కొత్త పిన్ కోడ్"</string> <string name="keyguard_password_entry_touch_hint" msgid="7858547464982981384"><font size="17">"పాస్వర్డ్ను టైప్ చేయడానికి తాకండి"</font></string> <string name="keyguard_password_enter_password_code" msgid="1054721668279049780">"అన్లాక్ చేయడానికి పాస్వర్డ్ను టైప్ చేయండి"</string> - <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"అన్లాక్ చేయడానికి PINను టైప్ చేయండి"</string> - <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"చెల్లని PIN కోడ్."</string> + <string name="keyguard_password_enter_pin_password_code" msgid="6391755146112503443">"అన్లాక్ చేయడానికి పిన్ను టైప్ చేయండి"</string> + <string name="keyguard_password_wrong_pin_code" msgid="2422225591006134936">"చెల్లని పిన్ కోడ్."</string> <string name="keyguard_label_text" msgid="861796461028298424">"అన్లాక్ చేయడానికి, మెను ఆపై 0ని నొక్కండి."</string> <string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"అత్యవసర నంబర్"</string> <string name="lockscreen_carrier_default" msgid="8963839242565653192">"సేవ లేదు."</string> @@ -905,13 +905,13 @@ <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"మళ్లీ ప్రయత్నించండి"</string> <string name="lockscreen_password_wrong" msgid="5737815393253165301">"మళ్లీ ప్రయత్నించండి"</string> <string name="faceunlock_multiple_failures" msgid="754137583022792429">"ముఖంతో అన్లాక్ ప్రయత్నాల గరిష్ట పరిమితి మించిపోయారు"</string> - <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"SIM కార్డు లేదు"</string> - <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"టాబ్లెట్లో SIM కార్డు లేదు."</string> - <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"ఫోన్లో SIM కార్డు లేదు."</string> - <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"SIM కార్డును చొప్పించండి."</string> - <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM కార్డు లేదు లేదా చదవగలిగేలా లేదు. SIM కార్డును చొప్పించండి."</string> - <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"నిరుపయోగ SIM కార్డు."</string> - <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"మీ SIM కార్డు శాశ్వతంగా నిలిపివేయబడింది.\n మరో SIM కార్డు కోసం మీ వైర్లెస్ సేవా ప్రదాతను సంప్రదించండి."</string> + <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"సిమ్ కార్డు లేదు"</string> + <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"టాబ్లెట్లో సిమ్ కార్డు లేదు."</string> + <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"ఫోన్లో సిమ్ కార్డు లేదు."</string> + <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"సిమ్ కార్డును చొప్పించండి."</string> + <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"సిమ్ కార్డు లేదు లేదా చదవగలిగేలా లేదు. సిమ్ కార్డును చొప్పించండి."</string> + <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"నిరుపయోగ సిమ్ కార్డు."</string> + <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"మీ సిమ్ కార్డు శాశ్వతంగా నిలిపివేయబడింది.\n మరో సిమ్ కార్డు కోసం మీ వైర్లెస్ సేవా ప్రదాతను సంప్రదించండి."</string> <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"మునుపటి ట్రాక్"</string> <string name="lockscreen_transport_next_description" msgid="573285210424377338">"తదుపరి ట్రాక్"</string> <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"పాజ్ చేయి"</string> @@ -921,13 +921,13 @@ <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"వేగంగా ఫార్వార్డ్ చేయి"</string> <string name="emergency_calls_only" msgid="6733978304386365407">"అత్యవసర కాల్లు మాత్రమే"</string> <string name="lockscreen_network_locked_message" msgid="143389224986028501">"నెట్వర్క్ లాక్ చేయబడింది"</string> - <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM కార్డు PUK-లాక్ చేయబడింది."</string> + <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"సిమ్ కార్డు PUK-లాక్ చేయబడింది."</string> <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"వినియోగదారు గైడ్ను చూడండి లేదా కస్టమర్ కేర్ను సంప్రదించండి."</string> - <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM కార్డు లాక్ చేయబడింది."</string> - <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"SIM కార్డును అన్లాక్ చేస్తోంది…"</string> + <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"సిమ్ కార్డు లాక్ చేయబడింది."</string> + <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"సిమ్ కార్డును అన్లాక్ చేస్తోంది…"</string> <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"మీరు మీ అన్లాక్ నమూనాను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string> <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"మీరు మీ పాస్వర్డ్ను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string> - <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"మీరు మీ PINను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string> + <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"మీరు మీ పిన్ను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string> <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"మీరు మీ అన్లాక్ నమూనాని <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> విజయవంతం కాని ప్రయత్నాల తర్వాత, మీరు మీ Google సైన్ఇన్ను ఉపయోగించి మీ టాబ్లెట్ను అన్లాక్ చేయడానికి అడగబడతారు.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string> <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"మీరు మీ అన్లాక్ నమూనాని <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> విజయవంతం కాని ప్రయత్నాల తర్వాత, మీరు మీ Google సైన్ఇన్ను ఉపయోగించి మీ ఫోన్ను అన్లాక్ చేయడానికి అడగబడతారు.\n\n <xliff:g id="NUMBER_2">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"మీరు టాబ్లెట్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా ప్రయత్నించారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> వైఫల్య ప్రయత్నాల తర్వాత, టాబ్లెట్ ఫ్యాక్టరీ డిఫాల్ట్కు రీసెట్ చేయబడుతుంది మరియు మొత్తం వినియోగదారు డేటాను కోల్పోవడం సంభవిస్తుంది."</string> @@ -1285,8 +1285,8 @@ <string name="wifi_p2p_invitation_to_connect_title" msgid="4958803948658533637">"కనెక్ట్ చేయడానికి ఆహ్వానం"</string> <string name="wifi_p2p_from_message" msgid="570389174731951769">"వీరి నుండి:"</string> <string name="wifi_p2p_to_message" msgid="248968974522044099">"వీరికి:"</string> - <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"అవసరమైన PINను టైప్ చేయండి:"</string> - <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"PIN:"</string> + <string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"అవసరమైన పిన్ను టైప్ చేయండి:"</string> + <string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"పిన్:"</string> <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"టాబ్లెట్ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>కు కనెక్ట్ చేయబడినప్పుడు Wi-Fi నుండి తాత్కాలికంగా డిస్కనెక్ట్ చేయబడుతుంది"</string> <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ఫోన్ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>కి కనెక్ట్ అయినప్పుడు అది Wi-Fi నుండి తాత్కాలికంగా డిస్కనెక్ట్ చేయబడుతుంది"</string> <string name="select_character" msgid="3365550120617701745">"అక్షరాన్ని చొప్పించండి"</string> @@ -1303,10 +1303,10 @@ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"మీరు దీన్ని తర్వాత సెట్టింగ్లు > అనువర్తనాలులో మార్చవచ్చు"</string> <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"ఎల్లప్పుడూ అనుమతించు"</string> <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"ఎప్పటికీ అనుమతించవద్దు"</string> - <string name="sim_removed_title" msgid="6227712319223226185">"SIM కార్డు తీసివేయబడింది"</string> - <string name="sim_removed_message" msgid="5450336489923274918">"మీరు చెల్లుబాటు అయ్యే SIM కార్డును చొప్పించి, దాన్ని పునఃప్రారంభించే వరకు సెల్యులార్ నెట్వర్క్ అందుబాటులో ఉండదు."</string> + <string name="sim_removed_title" msgid="6227712319223226185">"సిమ్ కార్డు తీసివేయబడింది"</string> + <string name="sim_removed_message" msgid="5450336489923274918">"మీరు చెల్లుబాటు అయ్యే సిమ్ కార్డును చొప్పించి, దాన్ని పునఃప్రారంభించే వరకు సెల్యులార్ నెట్వర్క్ అందుబాటులో ఉండదు."</string> <string name="sim_done_button" msgid="827949989369963775">"పూర్తయింది"</string> - <string name="sim_added_title" msgid="3719670512889674693">"SIM కార్డు జోడించబడింది"</string> + <string name="sim_added_title" msgid="3719670512889674693">"సిమ్ కార్డు జోడించబడింది"</string> <string name="sim_added_message" msgid="7797975656153714319">"సెల్యులార్ నెట్వర్క్ను ప్రాప్యత చేయడానికి మీ పరికరాన్ని పునఃప్రారంభించండి."</string> <string name="sim_restart_button" msgid="4722407842815232347">"పునఃప్రారంభించు"</string> <string name="time_picker_dialog_title" msgid="8349362623068819295">"సమయాన్ని సెట్ చేయండి"</string> @@ -1596,21 +1596,21 @@ <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"నమూనాను మర్చిపోయాను"</string> <string name="kg_wrong_pattern" msgid="1850806070801358830">"నమూనా తప్పు"</string> <string name="kg_wrong_password" msgid="2333281762128113157">"పాస్వర్డ్ తప్పు"</string> - <string name="kg_wrong_pin" msgid="1131306510833563801">"PIN తప్పు"</string> + <string name="kg_wrong_pin" msgid="1131306510833563801">"పిన్ తప్పు"</string> <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string> <string name="kg_pattern_instructions" msgid="398978611683075868">"మీ నమూనాను గీయండి"</string> - <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"SIM PINను నమోదు చేయండి"</string> - <string name="kg_pin_instructions" msgid="2377242233495111557">"PINను నమోదు చేయండి"</string> + <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"సిమ్ పిన్ను నమోదు చేయండి"</string> + <string name="kg_pin_instructions" msgid="2377242233495111557">"పిన్ను నమోదు చేయండి"</string> <string name="kg_password_instructions" msgid="5753646556186936819">"పాస్వర్డ్ని నమోదు చేయండి"</string> - <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM ఇప్పుడు నిలిపివేయబడింది. కొనసాగడానికి PUK కోడ్ను నమోదు చేయండి. వివరాల కోసం క్యారియర్ను సంప్రదించండి."</string> - <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"కోరుకునే PIN కోడ్ను నమోదు చేయండి"</string> - <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"కావల్సిన PIN కోడ్ను నిర్ధారించండి"</string> - <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"SIM కార్డును అన్లాక్ చేస్తోంది…"</string> - <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"చెల్లని PIN కోడ్."</string> - <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 నుండి 8 సంఖ్యలు ఉండే PINను టైప్ చేయండి."</string> + <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"సిమ్ ఇప్పుడు నిలిపివేయబడింది. కొనసాగడానికి PUK కోడ్ను నమోదు చేయండి. వివరాల కోసం క్యారియర్ను సంప్రదించండి."</string> + <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"కోరుకునే పిన్ కోడ్ను నమోదు చేయండి"</string> + <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"కావల్సిన పిన్ కోడ్ను నిర్ధారించండి"</string> + <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"సిమ్ కార్డును అన్లాక్ చేస్తోంది…"</string> + <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"చెల్లని పిన్ కోడ్."</string> + <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"4 నుండి 8 సంఖ్యలు ఉండే పిన్ను టైప్ చేయండి."</string> <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"PUK కోడ్ 8 సంఖ్యలు ఉండాలి."</string> - <string name="kg_invalid_puk" msgid="3638289409676051243">"సరైన PUK కోడ్ను మళ్లీ నమోదు చేయండి. పునరావృత ప్రయత్నాల వలన SIM శాశ్వతంగా నిలిపివేయబడుతుంది."</string> - <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"PIN కోడ్లు సరిపోలలేదు"</string> + <string name="kg_invalid_puk" msgid="3638289409676051243">"సరైన PUK కోడ్ను మళ్లీ నమోదు చేయండి. పునరావృత ప్రయత్నాల వలన సిమ్ శాశ్వతంగా నిలిపివేయబడుతుంది."</string> + <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"పిన్ కోడ్లు సరిపోలలేదు"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"చాలా ఎక్కువ నమూనా ప్రయత్నాలు చేసారు"</string> <string name="kg_login_instructions" msgid="1100551261265506448">"అన్లాక్ చేయడానికి, మీ Google ఖాతాతో సైన్ ఇన్ చేయండి."</string> <string name="kg_login_username_hint" msgid="5718534272070920364">"వినియోగదారు పేరు (ఇమెయిల్)"</string> @@ -1619,7 +1619,7 @@ <string name="kg_login_invalid_input" msgid="5754664119319872197">"చెల్లని వినియోగదారు పేరు లేదా పాస్వర్డ్."</string> <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"మీ వినియోగదారు పేరు లేదా పాస్వర్డ్ను మర్చిపోయారా?\n"<b>"google.com/accounts/recovery"</b>"ని సందర్శించండి."</string> <string name="kg_login_checking_password" msgid="1052685197710252395">"ఖాతాను తనిఖీ చేస్తోంది…"</string> - <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"మీరు మీ PINను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string> + <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"మీరు మీ పిన్ను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string> <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"మీరు మీ పాస్వర్డ్ను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా టైప్ చేసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string> <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"మీరు మీ అన్లాక్ నమూనాను <xliff:g id="NUMBER_0">%d</xliff:g> సార్లు తప్పుగా గీసారు. \n\n<xliff:g id="NUMBER_1">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string> <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"మీరు టాబ్లెట్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER_0">%d</xliff:g> చెల్లని ప్రయత్నాలు చేసారు. మరో <xliff:g id="NUMBER_1">%d</xliff:g> విఫల ప్రయత్నాల తర్వాత, టాబ్లెట్ ఫ్యాక్టరీ డిఫాల్ట్కు రీసెట్ చేయబడుతుంది మరియు మొత్తం వినియోగదారు డేటాను కోల్పోవడం సంభవిస్తుంది."</string> @@ -1730,15 +1730,15 @@ <string name="reason_service_unavailable" msgid="7824008732243903268">"ముద్రణ సేవ ప్రారంభించబడలేదు"</string> <string name="print_service_installed_title" msgid="2246317169444081628">"<xliff:g id="NAME">%s</xliff:g> సేవ ఇన్స్టాల్ చేయబడింది"</string> <string name="print_service_installed_message" msgid="5897362931070459152">"ప్రారంభించడానికి నొక్కండి"</string> - <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"నిర్వాహకుని PINను నమోదు చేయండి"</string> - <string name="restr_pin_enter_pin" msgid="3395953421368476103">"PINను నమోదు చేయండి"</string> + <string name="restr_pin_enter_admin_pin" msgid="783643731895143970">"నిర్వాహకుని పిన్ను నమోదు చేయండి"</string> + <string name="restr_pin_enter_pin" msgid="3395953421368476103">"పిన్ను నమోదు చేయండి"</string> <string name="restr_pin_incorrect" msgid="8571512003955077924">"తప్పు"</string> - <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"ప్రస్తుత PIN"</string> - <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"కొత్త PIN"</string> - <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"కొత్త PINను నిర్ధారించండి"</string> - <string name="restr_pin_create_pin" msgid="8017600000263450337">"నియంత్రణలను సవరించడానికి PINను రూపొందించండి"</string> + <string name="restr_pin_enter_old_pin" msgid="1462206225512910757">"ప్రస్తుత పిన్"</string> + <string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"కొత్త పిన్"</string> + <string name="restr_pin_confirm_pin" msgid="8501523829633146239">"కొత్త పిన్ను నిర్ధారించండి"</string> + <string name="restr_pin_create_pin" msgid="8017600000263450337">"నియంత్రణలను సవరించడానికి పిన్ను రూపొందించండి"</string> <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PINలు సరిపోలలేదు. మళ్లీ ప్రయత్నించండి."</string> - <string name="restr_pin_error_too_short" msgid="8173982756265777792">"PIN చాలా చిన్నదిగా ఉంది. తప్పనిసరిగా కనీసం 4 అంకెలు ఉండాలి."</string> + <string name="restr_pin_error_too_short" msgid="8173982756265777792">"పిన్ చాలా చిన్నదిగా ఉంది. తప్పనిసరిగా కనీసం 4 అంకెలు ఉండాలి."</string> <plurals name="restr_pin_countdown"> <item quantity="one" msgid="311050995198548675">"1 సెకనులో మళ్లీ ప్రయత్నించండి"</item> <item quantity="other" msgid="4730868920742952817">"<xliff:g id="COUNT">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి"</item> @@ -1757,17 +1757,17 @@ <string name="item_is_selected" msgid="949687401682476608">"<xliff:g id="ITEM">%1$s</xliff:g> ఎంచుకోబడింది"</string> <string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> తొలగించబడింది"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"కార్యాలయం <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"ఈ స్క్రీన్ను అన్పిన్ చేయడానికి, వెనుకకు మరియు స్థూలదృష్టి బటన్లను ఒకేసారి నొక్కి, ఉంచండి."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"ఈ స్క్రీన్ని అన్పిన్ చేయడానికి, స్థూలదృష్టిని నొక్కి, ఉంచండి."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"ఈ స్క్రీన్ను అన్పిన్ చేయడానికి, వెనుకకు మరియు అవలోకనం బటన్లను ఒకేసారి నొక్కి, ఉంచండి."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"ఈ స్క్రీన్ని అన్పిన్ చేయడానికి, అవలోకనం నొక్కి, ఉంచండి."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"స్క్రీన్ పిన్ చేయబడింది. మీ సంస్థలో అన్పిన్ చేయడానికి అనుమతి లేదు."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"స్క్రీన్ పిన్నింగ్ను ఉపయోగించాలా?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"స్క్రీన్ పిన్నింగ్ ఒక్క వీక్షణలో డిస్ప్లేను లాక్ చేస్తుంది.\n\nఅన్పిన్ చేయడానికి, వెనుకకు మరియు స్థూలదృష్టి బటన్లను ఒకేసారి నొక్కి, ఉంచండి."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"స్క్రీన్ పిన్నింగ్ ఒక్క వీక్షణలో డిస్ప్లేను లాక్ చేస్తుంది.\n\nఅన్పిన్ చేయడానికి, స్థూలదృష్టిని నొక్కి, ఉంచండి."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"స్క్రీన్ పిన్నింగ్ ఒక్క వీక్షణలో డిస్ప్లేను లాక్ చేస్తుంది.\n\nఅన్పిన్ చేయడానికి, వెనుకకు మరియు అవలోకనం బటన్లను ఒకేసారి నొక్కి, ఉంచండి."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"స్క్రీన్ పిన్నింగ్ ఒక్క వీక్షణలో డిస్ప్లేను లాక్ చేస్తుంది.\n\nఅన్పిన్ చేయడానికి, అవలోకనం నొక్కి, ఉంచండి."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"వద్దు, ధన్యవాదాలు"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"ప్రారంభించు"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"స్క్రీన్ పిన్ చేయబడింది"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"స్క్రీన్ అన్పిన్ చేయబడింది"</string> - <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"అన్పిన్ చేయడానికి ముందు PIN కోసం అడుగు"</string> + <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"అన్పిన్ చేయడానికి ముందు పిన్ కోసం అడుగు"</string> <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"అన్పిన్ చేయడానికి ముందు అన్లాక్ నమూనా కోసం అడుగు"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"అన్పిన్ చేయడానికి ముందు పాస్వర్డ్ కోసం అడుగు"</string> <string name="battery_saver_description" msgid="2510530476513605742">"బ్యాటరీ సామర్థ్యాన్ని మెరుగుపరచడంలో సహాయపడటానికి, బ్యాటరీ సేవర్ మీ పరికరం పనితీరుని తగ్గిస్తుంది మరియు వైబ్రేషన్ను మరియు అత్యధిక నేపథ్య డేటాను పరిమితపరుస్తుంది. అలాగే సమకాలీకరణపై ఆధారపడే ఇమెయిల్, సందేశ సేవ మరియు ఇతర అనువర్తనాలు మీరు వాటిని తెరిస్తే మినహా నవీకరించబడకపోవచ్చు.\n\nమీ పరికరం ఛార్జింగ్లో ఉన్నప్పుడు బ్యాటరీ సేవర్ స్వయంచాలకంగా ఆఫ్ చేయబడుతుంది."</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index ecef924271cc..e5a4e9c1caaa 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"แก้ไขบัตรผู้ติดต่อของคุณเอง"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"อนุญาตให้แอปพลิเคชันเปลี่ยนแปลงหรือเพิ่มข้อมูลโปรไฟล์ส่วนตัวที่จัดเก็บไว้บนอุปกรณ์ของคุณ เช่น ชื่อและข้อมูลติดต่อ ซึ่งหมายความว่าแอปพลิเคชันจะสามารถระบุตัวตนของคุณและส่งข้อมูลโปรไฟล์ของคุณให้แก่ผู้อื่นได้"</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"เซ็นเซอร์ร่างกาย (เช่น วัดอัตราการเต้นของหัวใจ)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"ช่วยให้แอปสามารถเข้าถึงข้อมูลจากเซ็นเซอร์ที่คุณใช้เพื่อวัดความเป็นไปภายในร่างกายของคุณ เช่น อัตราการเต้นของหัวใจ"</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"อนุญาตให้แอปเข้าถึงข้อมูลจากเซ็นเซอร์ที่ตรวจสอบสภาพทางกายภาพ เช่น อัตราการเต้นของหัวใจ"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"อ่านสตรีมเครือข่ายสังคม"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"อนุญาตให้แอปพลิเคชันเข้าถึงและซิงค์การอัปเดตทางสังคมจากคุณและเพื่อน โปรดแชร์ข้อมูลอย่างระมัดระวังเนื่องจากการอนุญาตนี้ทำให้แอปพลิเคชันสามารถอ่านการติดต่อระหว่างคุณและเพื่อนในเครือข่ายสังคมได้ ไม่ว่าจะมีการรักษาข้อมูลที่เป็นความลับแบบใดก็ตาม หมายเหตุ: การอนุญาตนี้อาจไม่สามารถใช้งานได้กับทุกเครือข่ายสังคม"</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"เขียนในสตรีมเครือข่ายสังคม"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 9e1e73194128..8360eb191849 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"baguhin sarili mo contact card"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Pinapayagan ang app na baguhin ang o magdagdag sa personal na impormasyon ng profile na naka-imbak sa iyong device, gaya ng iyong pangalan at impormasyon sa pakikipag-ugnay. Nangangahulugan ito na makikilala ka ng app at maaari nitong ipadala ang impormasyon ng iyong profile sa iba."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"mga sensor sa katawan (gaya ng mga heart rate monitor)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Pinapayagan ang app na i-access ang data mula sa mga sensor na ginagamit mo upang sukatin kung anong nangyayari sa iyong katawan, gaya ng heart rate."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Pinapayagan ang app na i-access ang data mula sa mga sensor na sumusubaybay sa iyong pisikal na kundisyon, tulad ng iyong heart rate."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"basahin ang iyong social stream"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Pinapayagan ang app na mag-access at mag-sync ng mga social na update mula sa iyo at sa iyong mga kaibigan. Maging maingat kapag nagbabahagi ng impormasyon -- pinapayagan nito ang app na magbasa ng mga pakikipag-ugnayan sa pagitan mo at ng iyong mga kaibigan sa mga social network, ano pa man ang katayuan sa pagiging kumpedensyal nito. Tandaan: hindi maaaring ipatupad ang pahintulot na ito sa lahat ng social network."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"magsulat sa iyong social stream"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"Napili ang <xliff:g id="ITEM">%1$s</xliff:g>"</string> <string name="deleted_key" msgid="7659477886625566590">"Tinanggal ang <xliff:g id="KEY">%1$s</xliff:g>"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> sa Trabaho"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Upang i-unpin ang screen na ito, pindutin nang matagal ang Bumalik at Pangkalahatang-ideya nang sabay-sabay."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Upang i-unpin ang screen na ito, pindutin nang matagal ang Pangkalahatang-ideya."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Upang i-unpin ang screen na ito, pindutin nang matagal ang Bumalik at Overview nang sabay-sabay."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Upang i-unpin ang screen na ito, pindutin nang matagal ang Overview."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Naka-pin ang screen. Hindi pinapayagan ng iyong organisasyon ang pag-a-unpin."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Gamitin ang pagpi-pin ng screen?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"Nila-lock ng pagpi-pin ng screen ang display sa iisang view.\n\nUpang i-unpin, pindutin nang matagal ang Bumalik at Pangkalahatang-ideya nang sabay-sabay."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Nila-lock ng pagpi-pin ng screen ang display sa iisang view.\n\nUpang i-unpin, pindutin nang matagal ang Pangkalahatang-ideya."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"Nila-lock ng pagpi-pin ng screen ang display sa iisang view.\n\nUpang i-unpin, pindutin nang matagal ang Bumalik at Overview nang sabay-sabay."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Nila-lock ng pagpi-pin ng screen ang display sa iisang view.\n\nUpang i-unpin, pindutin nang matagal ang Overview."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"HINDI, SALAMAT NA LANG"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"SIMULAN"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Naka-pin ang screen"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index a7861013ebda..e6f78c6970aa 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"kendi kişi kartınızı değiştirme"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Uygulamaya adınız ve iletişim bilgileriniz gibi cihazınızda saklanan kişisel profil bilgilerini değiştirme veya bunlara ekleme yapma izni verir. Bu izin, uygulamanın sizi tanımlayabileceği ve profil bilgilerinizi başkalarına gönderebileceği anlamına gelir."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"vücut sensörleri (kalp atış hızı takip cihazları gibi)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Uygulamanın, kalp atış hızınız gibi vücudunuzla ilgili olayları ölçmek için kullandığınız sensörlerden gelen verilere erişmesine izin verir."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Uygulamanın, nabzınız gibi fiziksel durumunuzu izleyen sensörlerin gönderdiği verilere erişmesine izin verir."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"sosyal akışınızı okuma"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Uygulamaya size veya arkadaşlarınıza ait sosyal güncellemelere erişme ve bunları senkronize etme izni verir. Bilgi paylaşırken dikkatli olun. Bu izin, uygulamanın sosyal ağlarda sizinle arkadaşlarınız arasındaki iletişimi, gizliliğine bakılmaksızın okumasına olanak sağlar. Not: Bu izin tüm sosyal ağlar için geçerli olmayabilir."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"sosyal akışınıza yazma"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 093844bbc67a..925ec80192ef 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"змінювати картки контактів"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Дозволяє програмі змінювати чи додавати особисту інформацію профілю, збережену на пристрої, як-от ваше ім’я та контактну інформацію. Це означає, що програма може ідентифікувати вашу особу та надсилати дані вашого профілю іншим."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"датчики на тілі (як-от пульсометр)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Дозволяє додатку отримувати дані з датчиків, які вимірюють фізіологічні процеси, як-от пульс."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Додаток має доступ до даних із датчиків, які відстежують фізичний стан, зокрема пульс."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"читати ваш соціальний потік"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Дозволяє програмі отримувати доступ до оновлень із соціальних мереж від вас і ваших друзів та синхронізувати їх. Будьте обережні, надаючи доступ до інформації – це дозволяє програмі читати повідомлення, якими ви та ваші друзі обмінювалися в соціальних мережах, незалежно від конфіденційності. Зауважте: цей дозвіл не можна застосовувати в усіх соціальних мережах."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"писати у ваш соціальний потік"</string> diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml index 2826c4e9a3a0..ddfd85d6752c 100644 --- a/core/res/res/values-ur-rPK/strings.xml +++ b/core/res/res/values-ur-rPK/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"اپنے رابطہ کارڈ میں ترمیم کریں"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"ایپ کو آپ کے آلے پر اسٹور کردہ ذاتی پروفائل کی معلومات، جیسے آپ کا نام اور رابطے کی معلومات تبدیل یا اس میں شامل کرنے کی اجازت دیتا ہے۔ اس کا مطلب یہ ہے کہ ایپ آپ کی نشاندہی کرسکتی اور آپ کے پروفائل کی معلومات دوسروں کو بھیج سکتی ہے۔"</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"باڈی سینسرز (جیسے دل کی دھڑکن کے مانیٹرز)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"ایپ کو ان سینسرز سے ڈیٹا تک رسائی کی اجازت دیتا ہے، جنہیں آپ اپنے جسم کے اندر چل رہی چیزوں کی پیمائش کیلئے استعمال کرتے ہیں، جیسے کہ دل کی دھڑکن۔"</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"ان سینسرز سے ڈیٹا تک رسائی حاصل کرنے کی اجازت دیتی ہے جو آپ کی حرکت قلب کی شرح جیسی آپ کی فزیکل صورتحال کو مانیٹر کرتے ہیں۔"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"اپنا سوشل سلسلہ پڑھیں"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"ایپ کو آپ اور آپ کے دوستوں کے سماجی اپ ڈیٹس تک رسائی حاصل کرنے اور انہیں مطابقت پذیر بنانے کی اجازت دیتا ہے۔ معلومات کا اشتراک کرتے وقت محتاط رہیں -- رازداری سے قطع نظر، یہ سماجی نیٹ ورکس پر آپ اور آپ کے دوستوں کے بیچ مواصلتوں کو پڑھنے کی اجازت دیتا ہے۔ نوٹ: یہ اجازت سبھی سماجی نیٹ ورکس پر نافذ نہیں کی جاسکتی ہے۔"</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"اپنے سوشل سلسلہ میں لکھیں"</string> diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml index 2c209c33b939..6d6f36e9d966 100644 --- a/core/res/res/values-uz-rUZ/strings.xml +++ b/core/res/res/values-uz-rUZ/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"shaxsiy kontaktlar kartangizni o‘zgartirish"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ilovaga qurilmangizga zaxiralangan ismingiz va aloqa ma’lumotlaringiz kabi shaxsiy profillingiz ma’lumotlarini o‘zgartirish yoki ularga ma’lumot qo‘shish imkonini beradi. Bu ilova sizni tanib olishi va profil ma’lumotlaringizni boshqalarga jo‘natishi mumkinligini bildiradi."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"sezgichlar (m-n, yurak urishi)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Ilova sizning jismoniy ko‘rsatkichlaringizni (m-n, yurak urishi) o‘lchaydigan sezgich ma’lumotlariga kirish vakolatini oladi."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ilovaga sezgichlardan olingan jismoniy holatingiz haqidagi ma’lumotlarni, masalan, yurak urishini kuzatish uchun ruxsat beradi."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"ijtimoiy uzatishni o‘qish"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Ilovaga siz va do‘stlaringizning ijtimoiy tarmoqlaridagi yangiliklarga kirish va ularni sinxronlashga ruxsat beradi. Ma’lumot ulashayotganda ehtiyot bo‘ling -- u ilovaga ijtimoiy tarmoqlarda maxfiyligidan qat’iy nazar siz va do‘stlaringiz o‘rtasidagi yozishmalarni o‘qish imkonini beradi. Diqqat qiling: ushbu ruxsat na barcha ijtimoiy tarmoqlarda talab qilinishi mumkin."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ijtimoiy uzatishga yozish"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 2e024ae984bc..f56f8e702337 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"sửa đổi thẻ liên hệ của riêng bạn"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Cho phép ứng dụng thay đổi hoặc thêm vào thông tin tiểu sử cá nhân được lưu trữ trên thiết bị, chẳng hạn như tên và thông tin liên hệ của bạn. Điều này có nghĩa là ứng dụng có thể xác định danh tính của bạn và gửi thông tin tiểu sử của bạn cho người khác."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"cảm biến cơ thể (như máy đo nhịp tim)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Cho phép ứng dụng truy cập dữ liệu từ cảm biến mà bạn sử dụng để đo những gì đang diễn ra bên trong cơ thể của bạn, chẳng hạn như nhịp tim."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Cho phép ứng dụng truy cập dữ liệu từ bộ cảm biến giám sát tình trạng thể chất của bạn, ví dụ như nhịp tim."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"đọc luồng xã hội của bạn"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Cho phép ứng dụng truy cập và đồng bộ hóa các cập nhật xã hội của bạn và bạn bè bạn. Hãy cẩn trọng khi chia sẻ thông tin -- việc này có thể cho phép ứng dụng đọc thông tin liên lạc giữa bạn và bạn bè bạn trên các mạng xã hội, bất kể tính bí mật là gì. Lưu ý: quyền này có thể không được thực thi trên tất cả các mạng xã hội."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"ghi luồng xã hội của bạn"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index eef11cea24a7..82c9fe1c2dd8 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"修改您自己的名片"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"允许该应用更改或添加您设备上存储的个人资料信息,例如您的姓名和联系信息。这意味着该应用可以识别您的身份,并可能将您的个人资料信息发送给他人。"</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"人体传感器(如心跳速率检测器)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"允许应用访问您用于测量身体状况(如心跳速率)的传感器中的数据。"</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"允许该应用存取监测您身体状况的传感器所收集的数据,例如您的心率。"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"读取您的社交信息流"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"允许该应用访问并同步您和朋友的社交动态信息。在分享信息时一定要小心,因为此权限可让该应用读取您与社交网络上的朋友之间的交流信息。"</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"写入您的社交信息流"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index cbdeae684365..880380ad2684 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"修改自己的聯絡資料"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"允許應用程式新增或更改裝置上儲存的個人資料,例如您的姓名和聯絡資訊。這表示應用程式可以識別您的身份,並將您的個人資料傳送給他人。"</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"身體感應器 (例如心跳監視器)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"允許應用程式存取用於測量身體狀況感應器的資料,例如心跳。"</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"允許應用程式存取感應器所收集的資料 (這類感應器可監測您的體能狀態,例如您的心跳速率)。"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"讀取您的社交串流"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"允許應用程式存取並同步處理您和好友的最新動態。當您分享資訊時,請務必小心,因為這項權限允許應用程式讀取您和好友在社交網絡上的私人通訊,不論是否機密。注意:這項權限可能不適用於所有社交網絡。"</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"寫入您的社交串流"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index f88b6f0f430c..70cb87e2b859 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"修改自己的聯絡資訊"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"允許應用程式新增或變更裝置上儲存的個人資料,例如您的姓名和聯絡資訊。這項設定可讓應用程式識別您的身分,並可能將您的個人資料傳送給他人。"</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"身體感應器 (例如心律監測器)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"允許應用程式存取感應器從您的身體測得的資料,例如心跳頻率。"</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"允許應用程式存取感測器所收集的資料 (這類感測器可監測您的體能狀態,例如您的心跳速率)。"</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"讀取您的社交串流"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"允許應用程式存取並同步處理您和好友的最新動態。因此,當您分享資訊時請小心,因為這項權限可讓應用程式讀取您和好友在社交網路上的私人通訊,包括機密通訊。注意:並非所有社交網路皆適用於這項權限。"</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"寫入您的社交串流"</string> @@ -1761,8 +1761,8 @@ <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"如要取消固定這個畫面,請輕觸並按住總覽按鈕。"</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"螢幕已固定,且貴機構不允許取消固定。"</string> <string name="lock_to_app_title" msgid="1682643873107812874">"使用螢幕固定功能?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"螢幕鎖定功能可鎖定螢幕,讓單一畫面持續顯示。\n\n如要取消固定單一畫面,請同時輕觸並按住返回按鈕和總覽按鈕。"</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"螢幕鎖定功能可鎖定螢幕,讓單一畫面持續顯示。\n\n如要取消固定單一畫面,請輕觸並按住總覽按鈕。"</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"螢幕固定功能可鎖定螢幕,讓單一畫面持續顯示。\n\n如要取消固定單一畫面,請同時輕觸並按住返回按鈕和總覽按鈕。"</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"螢幕固定功能可鎖定螢幕,讓單一畫面持續顯示。\n\n如要取消固定單一畫面,請輕觸並按住總覽按鈕。"</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"不用了,謝謝"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"啟動"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"已固定螢幕"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index c5e8c49d3ed8..65bd617fa9ab 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -494,7 +494,7 @@ <string name="permlab_writeProfile" msgid="907793628777397643">"guqula ikhadi lakho lokuxhumana"</string> <string name="permdesc_writeProfile" product="default" msgid="5552084294598465899">"Ivumela uhlelo lokusebenza ukushintsha noma ingeze ulwazi lomuntu siqu lwephrofayela olulondolozwe kudivayisi yakho, njengegama lakho kanye nolwazi lokuxhumana. Lokhu kuchaza ukuthi ezinye izinhlelo zokusebenza zingakuhlonza bese zithumelela abanye ulwazi lephrofayela yakho."</string> <string name="permlab_bodySensors" msgid="4871091374767171066">"izinzwa zomzimba (njengeziqaphi zokulinganisela inhliziyo)"</string> - <string name="permdesc_bodySensors" product="default" msgid="2998865085124153531">"Ivumela uhlelo lokusebenza ukuze lufinyelele kudatha esuka kuzinzwa ozisebenzisayo ukuze lulinganise ukuthi kwenzakalani phakathi komzimba wakho, njengokulinganisela kwenhliziyo."</string> + <string name="permdesc_bodySensors" product="default" msgid="4380015021754180431">"Ivumela uhlelo lokusebenza ukuthi lufinyelele kudatha kusukela kuzinzwa eziqapha isimo sakho somzimba, esifana nesilinganiso senhliziyo yakho."</string> <string name="permlab_readSocialStream" product="default" msgid="1268920956152419170">"funda ngezindlela zakho zokuxhumana nabanye abantu"</string> <string name="permdesc_readSocialStream" product="default" msgid="4255706027172050872">"Ivumela uhlelo lokusebenza ukufinyelela nokuvumelanisa izibuyekezo zomphakathi ezivela kuwe nakubangani bakho. Qaphela uma waba ulwazi -- lokhu kuvumela uhlelo lokusebenza ukufunda ukuxhumana phakathi kwakho nabangani bakho kumanethiwekhi omphakathi, ngaphandle kokugcinwa kuyimfihlo. Qaphela: le mvume ingaphoqelelwa kuwo onke amanethiwekhi omphakathi."</string> <string name="permlab_writeSocialStream" product="default" msgid="3504179222493235645">"bhala indlela yakho yokuxhumana nabantu"</string> @@ -1757,12 +1757,12 @@ <string name="item_is_selected" msgid="949687401682476608">"I-<xliff:g id="ITEM">%1$s</xliff:g> ekhethiwe"</string> <string name="deleted_key" msgid="7659477886625566590">"I-<xliff:g id="KEY">%1$s</xliff:g> isusiwe"</string> <string name="managed_profile_label_badge" msgid="2355652472854327647">"Umsebenzi <xliff:g id="LABEL">%1$s</xliff:g>"</string> - <string name="lock_to_app_toast" msgid="7570091317001980053">"Ukuze ususe ukuphina kulesi sikrini, thinta uphinde ubambe i-Emuva ne-Ukubuka konke ngesikhathi esisodwa."</string> - <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Ukuze ususe ukuphina lesi sikrini, thinta uphinde ubambe Ukubuka konke."</string> + <string name="lock_to_app_toast" msgid="7570091317001980053">"Ukuze ususe ukuphina kulesi sikrini, thinta uphinde ubambe i-Emuva ne-Buka konke ngesikhathi esisodwa."</string> + <string name="lock_to_app_toast_accessible" msgid="8239120109365070664">"Ukuze ususe ukuphina lesi sikrini, thinta uphinde ubambe Buka konke."</string> <string name="lock_to_app_toast_locked" msgid="8739004135132606329">"Isikrini siphiniwe. Ukususa ukuphina akuvumelekile inhlangano yakho."</string> <string name="lock_to_app_title" msgid="1682643873107812874">"Sebenzisa ukuphina isikrini?"</string> - <string name="lock_to_app_description" msgid="4120623404152035221">"Ukuphina isikrini kukhiyela isibonisi ekubukeni okukodwa.\n\nUkuze ususe ukuphina, thinta uphinde ubambe i-Ngemuva ne-Ukubuka konke ngesikhathi esisodwa."</string> - <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Ukuphina isikrini kukhiya isikrini ngokubuka okukodwa.\n\nUkuze ususe ukuphina, thinta uphinde ubambe Ukubuka konke."</string> + <string name="lock_to_app_description" msgid="4120623404152035221">"Ukuphina isikrini kukhiyela isibonisi ekubukeni okukodwa.\n\nUkuze ususe ukuphina, thinta uphinde ubambe i-Ngemuva ne-Buka konke ngesikhathi esisodwa."</string> + <string name="lock_to_app_description_accessible" msgid="199664191087836099">"Ukuphina isikrini kukhiya isikrini ngokubuka okukodwa.\n\nUkuze ususe ukuphina, thinta uphinde ubambe Buka konke."</string> <string name="lock_to_app_negative" msgid="2259143719362732728">"CHA, NGIYABONGA"</string> <string name="lock_to_app_positive" msgid="7085139175671313864">"QALA"</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Isikrini siphiniwe"</string> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 747cb1405214..7b4df49390e0 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -4911,7 +4911,7 @@ <!-- Y coordinate of the origin of the gradient within the shape. --> <attr name="centerY" format="float|fraction" /> <!-- Radius of the gradient, used only with radial gradient. --> - <attr name="gradientRadius" format="float|fraction" /> + <attr name="gradientRadius" format="float|fraction|dimension" /> </declare-styleable> <!-- Used to fill the shape of GradientDrawable with a solid color. --> @@ -5702,6 +5702,17 @@ <attr name="reparent" format="boolean"/> </declare-styleable> + <!-- Use <code>changeBounds</code>as the root tag of the XML resource that + describes a {@link android.transition.ChangeBounds} transition. + The attributes of the {@link android.R.styleable#Transition Transition} + resource are available in addition to the specific attributes of ChangeBounds + described here. --> + <declare-styleable name="ChangeBounds"> + <!-- Resize the view by adjusting the clipBounds rather than changing the + dimensions of the view itself. The default value is false. --> + <attr name="resizeClip" format="boolean"/> + </declare-styleable> + <!-- Use <code>transitionManager</code> as the root tag of the XML resource that describes a {@link android.transition.TransitionManager TransitionManager}. --> diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml index 5773b943abf0..46ec83827e8b 100644 --- a/core/res/res/values/colors_material.xml +++ b/core/res/res/values/colors_material.xml @@ -22,7 +22,7 @@ <color name="background_floating_material_light">#ffeeeeee</color> <color name="primary_material_dark">#ff212121</color> - <color name="primary_material_light">#ffbdbdbd</color> + <color name="primary_material_light">#ffe0e0e0</color> <color name="primary_dark_material_dark">#ff000000</color> <color name="primary_dark_material_light">#ff757575</color> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 59b4e9ccbf7d..e50eb0ca7562 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -453,6 +453,26 @@ <!-- If this is true, key chords can be used to take a screenshot on the device. --> <bool name="config_enableScreenshotChord">true</bool> + <!-- If this is true, allow wake from theater mode when plugged in or unplugged. --> + <bool name="config_allowTheaterModeWakeFromUnplug">false</bool> + <!-- If this is true, allow wake from theater mode from gesture. --> + <bool name="config_allowTheaterModeWakeFromGesture">false</bool> + <!-- If this is true, allow wake from theater mode from camera lens cover is switched. --> + <bool name="config_allowTheaterModeWakeFromCameraLens">false</bool> + <!-- If this is true, allow wake from theater mode from power key press. --> + <bool name="config_allowTheaterModeWakeFromPowerKey">true</bool> + <!-- If this is true, allow wake from theater mode from regular key press. Setting this value to + true implies config_allowTheaterModeWakeFromPowerKey is also true--> + <bool name="config_allowTheaterModeWakeFromKey">false</bool> + <!-- If this is true, allow wake from theater mode from motion. --> + <bool name="config_allowTheaterModeWakeFromMotion">false</bool> + <!-- If this is true, allow wake from theater mode from lid switch. --> + <bool name="config_allowTheaterModeWakeFromLidSwitch">false</bool> + <!-- If this is true, allow wake from theater mode when docked. --> + <bool name="config_allowTheaterModeWakeFromDock">false</bool> + <!-- If this is true, allow wake from theater mode from window layout flag. --> + <bool name="config_allowTheaterModeWakeFromWindowLayout">false</bool> + <!-- Auto-rotation behavior --> <!-- If true, enables auto-rotation features using the accelerometer. @@ -1767,13 +1787,21 @@ be disabled) but individual Features can be disabled using ImsConfig.setFeatureValue() --> <bool name="imsServiceAllowTurnOff">true</bool> - <!-- Flag specifying whether VoLTE & VT is availasble on device --> - <bool name="config_device_volte_vt_available">false</bool> + <!-- Flag specifying whether VoLTE is available on device --> + <bool name="config_device_volte_available">false</bool> + + <!-- Flag specifying whether VoLTE should be available for carrier: independent of + carrier provisioning. If false: hard disabled. If true: then depends on carrier + provisioning, availability etc --> + <bool name="config_carrier_volte_available">false</bool> + + <!-- Flag specifying whether VT is available on device --> + <bool name="config_device_vt_available">false</bool> - <!-- Flag specifying whether VoLTE & VT should be available for carrier: independent of + <!-- Flag specifying whether VT should be available for carrier: independent of carrier provisioning. If false: hard disabled. If true: then depends on carrier provisioning, availability etc --> - <bool name="config_carrier_volte_vt_available">false</bool> + <bool name="config_carrier_vt_available">false</bool> <bool name="config_networkSamplingWakesDevice">true</bool> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 7568252d912b..45208ab6b4d5 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2589,5 +2589,6 @@ <!-- @hide --> <public-padding type="attr" name="private_resource_pad" end="0x01010500" /> + <public type="attr" name="resizeClip"/> </resources> diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml index 3d30792b00fe..c6437f35ef64 100644 --- a/core/res/res/values/strings.xml +++ b/core/res/res/values/strings.xml @@ -1449,9 +1449,8 @@ <string name="permlab_bodySensors">body sensors (like heart rate monitors) </string> <!-- Description of the body sensors permission, listed so the user can decide whether to allow the application to access data from body sensors. [CHAR LIMIT=NONE] --> - <string name="permdesc_bodySensors" product="default">Allows the app to - access data from sensors you use to measure what’s happening inside your - body, such as heart rate.</string> + <string name="permdesc_bodySensors" product="default">Allows the app to access data from sensors + that monitor your physical condition, such as your heart rate.</string> <!-- Title of the read social stream permission, listed so the user can decide whether to allow the application to read information from the user's social stream. [CHAR LIMIT=30] --> <string name="permlab_readSocialStream" product="default">read your social stream</string> @@ -2116,6 +2115,16 @@ <string name="permdesc_use_sip">Allows the app to make and receive SIP calls.</string> <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permlab_register_provider">register new telecom connection</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permdesc_register_provider">Allows the app to register new telecom connections.</string> + + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permlab_connection_manager">manage telecom connections</string> + <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> + <string name="permdesc_connection_manager">Allows the app to manage telecom connections.</string> + + <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permlab_bind_incall_service">interact with in-call screen</string> <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. --> <string name="permdesc_bind_incall_service">Allows the app to control when and how the user sees the in-call screen.</string> diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml index f9fca00d3ba4..6e03b3d2696c 100644 --- a/core/res/res/values/styles_material.xml +++ b/core/res/res/values/styles_material.xml @@ -320,50 +320,48 @@ please see styles_device_defaults.xml. <item name="textColor">?attr/textColorPrimaryDisableOnly</item> </style> - <style name="TextAppearance.Material.Widget.ActionMode"/> - <style name="TextAppearance.Material.Widget.ActionMode.Title" - parent="TextAppearance.Material.Title"> - <item name="textSize">@dimen/text_size_title_material_toolbar</item> - </style> - <style name="TextAppearance.Material.Widget.ActionMode.Title.Inverse" - parent="TextAppearance.Material.Title.Inverse"> - <item name="textSize">@dimen/text_size_title_material_toolbar</item> - </style> - <style name="TextAppearance.Material.Widget.ActionMode.Subtitle" - parent="TextAppearance.Material.Subhead"> - <item name="textSize">@dimen/text_size_subtitle_material_toolbar</item> - </style> - <style name="TextAppearance.Material.Widget.ActionMode.Subtitle.Inverse" - parent="TextAppearance.Material.Subhead.Inverse"> - <item name="textSize">@dimen/text_size_subtitle_material_toolbar</item> - </style> <style name="TextAppearance.Material.Widget.ActionBar.Title" parent="TextAppearance.Material.Title"> <item name="textSize">@dimen/text_size_title_material_toolbar</item> + <item name="textColor">?attr/textColorPrimary</item> </style> <style name="TextAppearance.Material.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Material.Title.Inverse"> <item name="textSize">@dimen/text_size_title_material_toolbar</item> + <item name="textColor">?attr/textColorPrimaryInverse</item> </style> <style name="TextAppearance.Material.Widget.ActionBar.Subtitle" parent="TextAppearance.Material.Subhead"> <item name="textSize">@dimen/text_size_subtitle_material_toolbar</item> + <item name="textColor">?attr/textColorSecondary</item> </style> <style name="TextAppearance.Material.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Material.Subhead.Inverse"> <item name="textSize">@dimen/text_size_subtitle_material_toolbar</item> + <item name="textColor">?attr/textColorSecondaryInverse</item> </style> - <style name="TextAppearance.Material.Widget.ActionBar.Menu" parent="TextAppearance.Material.Menu"> + <style name="TextAppearance.Material.Widget.ActionBar.Menu" + parent="TextAppearance.Material.Menu"> <item name="textColor">?attr/actionMenuTextColor</item> <item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item> </style> - - <style name="TextAppearance.Material.Widget.ActionBar.Menu.Inverse" parent="TextAppearance.Material.Menu.Inverse"> + <style name="TextAppearance.Material.Widget.ActionBar.Menu.Inverse" + parent="TextAppearance.Material.Menu.Inverse"> <item name="textColor">?attr/actionMenuTextColor</item> <item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item> </style> + <style name="TextAppearance.Material.Widget.ActionMode"/> + <style name="TextAppearance.Material.Widget.ActionMode.Title" + parent="TextAppearance.Material.Widget.ActionBar.Title" /> + <style name="TextAppearance.Material.Widget.ActionMode.Title.Inverse" + parent="TextAppearance.Material.Widget.ActionBar.Title.Inverse" /> + <style name="TextAppearance.Material.Widget.ActionMode.Subtitle" + parent="TextAppearance.Material.Widget.ActionBar.Subtitle" /> + <style name="TextAppearance.Material.Widget.ActionMode.Subtitle.Inverse" + parent="TextAppearance.Material.Widget.ActionBar.Subtitle.Inverse" /> + <style name="TextAppearance.Material.Widget.Toolbar.Title" parent="TextAppearance.Material.Widget.ActionBar.Title" /> <style name="TextAppearance.Material.Widget.Toolbar.Subtitle" diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 71f06429ab68..a11fdbcbd68e 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -1571,6 +1571,15 @@ <java-symbol type="bool" name="config_enableNetworkLocationOverlay" /> <java-symbol type="bool" name="config_sf_limitedAlpha" /> <java-symbol type="bool" name="config_unplugTurnsOnScreen" /> + <java-symbol type="bool" name="config_allowTheaterModeWakeFromUnplug" /> + <java-symbol type="bool" name="config_allowTheaterModeWakeFromGesture" /> + <java-symbol type="bool" name="config_allowTheaterModeWakeFromCameraLens" /> + <java-symbol type="bool" name="config_allowTheaterModeWakeFromPowerKey" /> + <java-symbol type="bool" name="config_allowTheaterModeWakeFromKey" /> + <java-symbol type="bool" name="config_allowTheaterModeWakeFromMotion" /> + <java-symbol type="bool" name="config_allowTheaterModeWakeFromLidSwitch" /> + <java-symbol type="bool" name="config_allowTheaterModeWakeFromDock" /> + <java-symbol type="bool" name="config_allowTheaterModeWakeFromWindowLayout" /> <java-symbol type="bool" name="config_wifi_background_scan_support" /> <java-symbol type="bool" name="config_wifi_dual_band_support" /> <java-symbol type="bool" name="config_wimaxEnabled" /> @@ -2031,8 +2040,10 @@ <java-symbol type="attr" name="preferenceFragmentStyle" /> <java-symbol type="bool" name="skipHoldBeforeMerge" /> <java-symbol type="bool" name="imsServiceAllowTurnOff" /> - <java-symbol type="bool" name="config_device_volte_vt_available" /> - <java-symbol type="bool" name="config_carrier_volte_vt_available" /> + <java-symbol type="bool" name="config_device_volte_available" /> + <java-symbol type="bool" name="config_carrier_volte_available" /> + <java-symbol type="bool" name="config_device_vt_available" /> + <java-symbol type="bool" name="config_carrier_vt_available" /> <java-symbol type="bool" name="useImsAlwaysForEmergencyCall" /> <java-symbol type="attr" name="touchscreenBlocksFocus" /> <java-symbol type="layout" name="resolver_list_with_default" /> diff --git a/core/res/res/values/themes_micro.xml b/core/res/res/values/themes_micro.xml index 7e0467b3989e..f1bc5dadae8d 100644 --- a/core/res/res/values/themes_micro.xml +++ b/core/res/res/values/themes_micro.xml @@ -24,6 +24,8 @@ <item name="windowBackground">@color/black</item> <item name="windowContentOverlay">@null</item> <item name="windowIsFloating">false</item> + <!-- We need the windows to be translucent for SwipeToDismiss layout + to work properly. --> <item name="windowIsTranslucent">true</item> <item name="windowSwipeToDismiss">true</item> </style> @@ -38,6 +40,8 @@ <item name="windowBackground">@color/white</item> <item name="windowContentOverlay">@null</item> <item name="windowIsFloating">false</item> + <!-- We need the windows to be translucent for SwipeToDismiss layout + to work properly. --> <item name="windowIsTranslucent">true</item> <item name="windowSwipeToDismiss">true</item> </style> diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java index 80d566836dda..64fed7f77176 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestBase.java @@ -49,7 +49,8 @@ import java.util.List; */ public class ConnectivityManagerTestBase extends InstrumentationTestCase { - private static final String PING_IP_ADDR = "8.8.8.8"; + private static final String[] PING_HOST_LIST = { + "www.google.com", "www.yahoo.com", "www.bing.com", "www.facebook.com", "www.ask.com"}; protected static final int WAIT_FOR_SCAN_RESULT = 10 * 1000; //10 seconds protected static final int WIFI_SCAN_TIMEOUT = 50 * 1000; // 50 seconds @@ -281,22 +282,14 @@ public class ConnectivityManagerTestBase extends InstrumentationTestCase { } /** - * @param pingServerList a list of servers that can be used for ping test, can be null * @return true if the ping test is successful, false otherwise. */ - protected boolean pingTest(String[] pingServerList) { - String[] hostList = {"www.google.com", "www.yahoo.com", - "www.bing.com", "www.facebook.com", "www.ask.com"}; - if (pingServerList != null) { - hostList = pingServerList; - } - + protected boolean pingTest() { long startTime = System.currentTimeMillis(); while ((System.currentTimeMillis() - startTime) < PING_TIMER) { try { // assume the chance that all servers are down is very small - for (int i = 0; i < hostList.length; i++ ) { - String host = hostList[i]; + for (String host : PING_HOST_LIST) { logv("Start ping test, ping " + host); Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host); int status = p.waitFor(); @@ -312,6 +305,7 @@ public class ConnectivityManagerTestBase extends InstrumentationTestCase { } catch (InterruptedException e) { logv("Ping test Fail: InterruptedException"); } + SystemClock.sleep(SHORT_TIMEOUT); } // ping test timeout return false; @@ -458,14 +452,7 @@ public class ConnectivityManagerTestBase extends InstrumentationTestCase { // use ping request against Google public DNS to verify connectivity protected boolean checkNetworkConnectivity() { assertTrue("no active network connection", waitForActiveNetworkConnection(LONG_TIMEOUT)); - try { - Process proc = Runtime.getRuntime().exec(new String[]{ - "/system/bin/ping", "-W", "30", "-c", "1", PING_IP_ADDR}); - return proc.waitFor() == 0; - } catch (InterruptedException | IOException e) { - Log.e(mLogTag, "Ping failed", e); - } - return false; + return pingTest(); } @Override diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java index d5051dfafee4..2d291ffc70ed 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/functional/ConnectivityManagerMobileTest.java @@ -72,16 +72,6 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase super.tearDown(); } - // help function to verify 3G connection - public void verifyCellularConnection() { - NetworkInfo extraNetInfo = mCm.getActiveNetworkInfo(); - assertEquals("network type is not MOBILE", ConnectivityManager.TYPE_MOBILE, - extraNetInfo.getType()); - assertTrue("not connected to cellular network", extraNetInfo.isConnected()); - } - - - // Test case 1: Test enabling Wifi without associating with any AP, no broadcast on network // event should be expected. @LargeTest @@ -336,4 +326,12 @@ public class ConnectivityManagerMobileTest extends ConnectivityManagerTestBase assertTrue("wifi state not disabled", waitForWifiState( WifiManager.WIFI_STATE_DISABLED, LONG_TIMEOUT)); } + + // help function to verify 3G connection + private void verifyCellularConnection() { + NetworkInfo extraNetInfo = mCm.getActiveNetworkInfo(); + assertEquals("network type is not MOBILE", ConnectivityManager.TYPE_MOBILE, + extraNetInfo.getType()); + assertTrue("not connected to cellular network", extraNetInfo.isConnected()); + } } diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java index 41f01e6065a7..de934b9c9d82 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiApStress.java @@ -112,7 +112,7 @@ public class WifiApStress extends ConnectivityManagerTestBase { } catch (Exception e) { // ignore } - assertTrue("no uplink data connection after Wi-Fi tethering", pingTest(null)); + assertTrue("no uplink data connection after Wi-Fi tethering", pingTest()); // disable wifi hotspot assertTrue("failed to disable wifi hotspot", mWifiManager.setWifiApEnabled(config, false)); diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java index fbd466977b6e..f3d5c8749617 100644 --- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java +++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/stress/WifiStressTest.java @@ -216,7 +216,7 @@ public class WifiStressTest extends ConnectivityManagerTestBase { assertTrue("wifi not connected", waitForNetworkState(ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT)); // Run ping test to verify the data connection - assertTrue("Wi-Fi is connected, but no data connection.", pingTest(null)); + assertTrue("Wi-Fi is connected, but no data connection.", pingTest()); long i, sum = 0, avgReconnectTime = 0; for (i = 1; i <= mReconnectIterations; i++) { @@ -264,7 +264,7 @@ public class WifiStressTest extends ConnectivityManagerTestBase { } else { assertEquals("mobile not connected", State.CONNECTED, mCm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).getState()); - assertTrue("no connectivity over mobile", pingTest(null)); + assertTrue("no connectivity over mobile", pingTest()); } // Turn screen on again @@ -281,7 +281,7 @@ public class WifiStressTest extends ConnectivityManagerTestBase { avgReconnectTime = sum / i; logv("average reconnection time is: " + avgReconnectTime); - assertTrue("Reconnect to Wi-Fi network, but no data connection.", pingTest(null)); + assertTrue("Reconnect to Wi-Fi network, but no data connection.", pingTest()); } Bundle result = new Bundle(); result.putLong("actual-iterations", i - 1); diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index b5241779a88a..226717ec21d0 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -1252,6 +1252,13 @@ </intent-filter> </activity> + <activity android:name="android.content.res.ResourceCacheActivity"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" /> + </intent-filter> + </activity> + </application> <instrumentation android:name="android.test.InstrumentationTestRunner" diff --git a/core/tests/coretests/res/anim/reset_state_anim.xml b/core/tests/coretests/res/anim/reset_state_anim.xml index 918d0a35b0a1..4bbbe62eba6f 100644 --- a/core/tests/coretests/res/anim/reset_state_anim.xml +++ b/core/tests/coretests/res/anim/reset_state_anim.xml @@ -1,4 +1,18 @@ <?xml version="1.0"?> +<!-- Copyright (C) 2014 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. +--> <set xmlns:android="http://schemas.android.com/apk/res/android"> <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="0" android:valueType="floatType"/> <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="0" android:valueType="floatType"/> diff --git a/core/tests/coretests/res/anim/test_animator.xml b/core/tests/coretests/res/anim/test_animator.xml new file mode 100644 index 000000000000..49afc3f2b58d --- /dev/null +++ b/core/tests/coretests/res/anim/test_animator.xml @@ -0,0 +1,22 @@ +<?xml version="1.0"?> +<!-- Copyright (C) 2014 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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android"> + <!-- if you change this, you should also change AnimatorInflaterTest#testLoadAnimator--> + <objectAnimator android:propertyName="x" android:duration="100" android:valueTo="0" android:valueType="floatType"/> + <objectAnimator android:propertyName="y" android:duration="100" android:valueTo="1" android:valueType="floatType"/> + <objectAnimator android:propertyName="left" android:duration="100" android:valueTo="2" android:valueType="intType"/> +</set>
\ No newline at end of file diff --git a/core/tests/coretests/res/anim/test_state_anim.xml b/core/tests/coretests/res/anim/test_state_anim.xml index 9e08f68a3ebc..b6a4822ae153 100644 --- a/core/tests/coretests/res/anim/test_state_anim.xml +++ b/core/tests/coretests/res/anim/test_state_anim.xml @@ -1,4 +1,18 @@ <?xml version="1.0"?> +<!-- Copyright (C) 2014 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. +--> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true"> <set> diff --git a/core/tests/coretests/res/values-land/dimens.xml b/core/tests/coretests/res/values-land/dimens.xml new file mode 100644 index 000000000000..1ee9f1dbcd5d --- /dev/null +++ b/core/tests/coretests/res/values-land/dimens.xml @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> +<resources> + <dimen name="resource_cache_test_orientation_dependent">3dp</dimen> +</resources>
\ No newline at end of file diff --git a/core/tests/coretests/res/values/dimens.xml b/core/tests/coretests/res/values/dimens.xml new file mode 100644 index 000000000000..00fc414327f1 --- /dev/null +++ b/core/tests/coretests/res/values/dimens.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> +<resources> + <dimen name="resource_cache_test_generic">10dp</dimen> + <dimen name="resource_cache_test_orientation_dependent">20dp</dimen> +</resources>
\ No newline at end of file diff --git a/core/tests/coretests/src/android/animation/AnimatorInflaterTest.java b/core/tests/coretests/src/android/animation/AnimatorInflaterTest.java new file mode 100644 index 000000000000..3c8185328582 --- /dev/null +++ b/core/tests/coretests/src/android/animation/AnimatorInflaterTest.java @@ -0,0 +1,61 @@ +/* +* Copyright (C) 2014 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.animation; + +import android.test.ActivityInstrumentationTestCase2; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import com.android.frameworks.coretests.R; + +public class AnimatorInflaterTest extends ActivityInstrumentationTestCase2<BasicAnimatorActivity> { + Set<Integer> identityHashes = new HashSet<Integer>(); + + public AnimatorInflaterTest() { + super(BasicAnimatorActivity.class); + } + + private void assertUnique(Object object) { + assertUnique(object, ""); + } + + private void assertUnique(Object object, String msg) { + final int code = System.identityHashCode(object); + assertTrue("object should be unique " + msg + ", obj:" + object, identityHashes.add(code)); + + } + + public void testLoadStateListAnimator() { + StateListAnimator sla1 = AnimatorInflater.loadStateListAnimator(getActivity(), + R.anim.test_state_anim); + sla1.setTarget(getActivity().mAnimatingButton); + StateListAnimator sla2 = AnimatorInflater.loadStateListAnimator(getActivity(), + R.anim.test_state_anim); + assertNull(sla2.getTarget()); + for (StateListAnimator sla : new StateListAnimator[]{sla1, sla2}) { + assertUnique(sla); + assertEquals(3, sla.getTuples().size()); + for (StateListAnimator.Tuple tuple : sla.getTuples()) { + assertUnique(tuple); + assertUnique(tuple.getAnimator()); + } + } + } + +} diff --git a/core/tests/coretests/src/android/animation/BasicAnimatorActivity.java b/core/tests/coretests/src/android/animation/BasicAnimatorActivity.java index 93808d9d7e1c..6bcf8fc43d10 100644 --- a/core/tests/coretests/src/android/animation/BasicAnimatorActivity.java +++ b/core/tests/coretests/src/android/animation/BasicAnimatorActivity.java @@ -19,11 +19,14 @@ import com.android.frameworks.coretests.R; import android.app.Activity; import android.os.Bundle; +import android.widget.Button; public class BasicAnimatorActivity extends Activity { + public Button mAnimatingButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.animator_basic); + mAnimatingButton = (Button) findViewById(R.id.animatingButton); } } diff --git a/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java b/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java new file mode 100644 index 000000000000..e9fd5fbb3bab --- /dev/null +++ b/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java @@ -0,0 +1,224 @@ +/* + * Copyright (C) 2014 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.content.res; + +import android.test.ActivityInstrumentationTestCase2; +import android.util.TypedValue; + +import com.android.frameworks.coretests.R; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class ConfigurationBoundResourceCacheTest + extends ActivityInstrumentationTestCase2<ResourceCacheActivity> { + + ConfigurationBoundResourceCache<Float> mCache; + + Method mCalcConfigChanges; + + public ConfigurationBoundResourceCacheTest() { + super(ResourceCacheActivity.class); + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + mCache = new ConfigurationBoundResourceCache<Float>(getActivity().getResources()); + } + + public void testGetEmpty() { + assertNull(mCache.get(-1, null)); + } + + public void testSetGet() { + mCache.put(1, null, new DummyFloatConstantState(5f)); + assertEquals(5f, mCache.get(1, null)); + assertNotSame(5f, mCache.get(1, null)); + assertEquals(null, mCache.get(1, getActivity().getTheme())); + } + + public void testSetGetThemed() { + mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f)); + assertEquals(null, mCache.get(1, null)); + assertEquals(5f, mCache.get(1, getActivity().getTheme())); + assertNotSame(5f, mCache.get(1, getActivity().getTheme())); + } + + public void testMultiThreadPutGet() { + mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f)); + mCache.put(1, null, new DummyFloatConstantState(10f)); + assertEquals(10f, mCache.get(1, null)); + assertNotSame(10f, mCache.get(1, null)); + assertEquals(5f, mCache.get(1, getActivity().getTheme())); + assertNotSame(5f, mCache.get(1, getActivity().getTheme())); + } + + public void testVoidConfigChange() + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + TypedValue staticValue = new TypedValue(); + long key = 3L; + final Resources res = getActivity().getResources(); + res.getValue(R.dimen.resource_cache_test_generic, staticValue, true); + float staticDim = TypedValue.complexToDimension(staticValue.data, res.getDisplayMetrics()); + mCache.put(key, getActivity().getTheme(), + new DummyFloatConstantState(staticDim, staticValue.changingConfigurations)); + final Configuration cfg = res.getConfiguration(); + Configuration newCnf = new Configuration(cfg); + newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ? + Configuration.ORIENTATION_PORTRAIT + : Configuration.ORIENTATION_LANDSCAPE; + int changes = calcConfigChanges(res, newCnf); + assertEquals(staticDim, mCache.get(key, getActivity().getTheme())); + mCache.onConfigurationChange(changes); + assertEquals(staticDim, mCache.get(key, getActivity().getTheme())); + } + + public void testEffectiveConfigChange() + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + TypedValue changingValue = new TypedValue(); + long key = 4L; + final Resources res = getActivity().getResources(); + res.getValue(R.dimen.resource_cache_test_orientation_dependent, changingValue, true); + float changingDim = TypedValue.complexToDimension(changingValue.data, + res.getDisplayMetrics()); + mCache.put(key, getActivity().getTheme(), + new DummyFloatConstantState(changingDim, changingValue.changingConfigurations)); + + final Configuration cfg = res.getConfiguration(); + Configuration newCnf = new Configuration(cfg); + newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ? + Configuration.ORIENTATION_PORTRAIT + : Configuration.ORIENTATION_LANDSCAPE; + int changes = calcConfigChanges(res, newCnf); + assertEquals(changingDim, mCache.get(key, getActivity().getTheme())); + mCache.onConfigurationChange(changes); + assertNull(mCache.get(key, getActivity().getTheme())); + } + + public void testConfigChangeMultipleResources() + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + TypedValue staticValue = new TypedValue(); + TypedValue changingValue = new TypedValue(); + final Resources res = getActivity().getResources(); + res.getValue(R.dimen.resource_cache_test_generic, staticValue, true); + res.getValue(R.dimen.resource_cache_test_orientation_dependent, changingValue, true); + float staticDim = TypedValue.complexToDimension(staticValue.data, res.getDisplayMetrics()); + float changingDim = TypedValue.complexToDimension(changingValue.data, + res.getDisplayMetrics()); + mCache.put(R.dimen.resource_cache_test_generic, getActivity().getTheme(), + new DummyFloatConstantState(staticDim, staticValue.changingConfigurations)); + mCache.put(R.dimen.resource_cache_test_orientation_dependent, getActivity().getTheme(), + new DummyFloatConstantState(changingDim, changingValue.changingConfigurations)); + final Configuration cfg = res.getConfiguration(); + Configuration newCnf = new Configuration(cfg); + newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ? + Configuration.ORIENTATION_PORTRAIT + : Configuration.ORIENTATION_LANDSCAPE; + int changes = calcConfigChanges(res, newCnf); + assertEquals(staticDim, mCache.get(R.dimen.resource_cache_test_generic, + getActivity().getTheme())); + assertEquals(changingDim, mCache.get(R.dimen.resource_cache_test_orientation_dependent, + getActivity().getTheme())); + mCache.onConfigurationChange(changes); + assertEquals(staticDim, mCache.get(R.dimen.resource_cache_test_generic, + getActivity().getTheme())); + assertNull(mCache.get(R.dimen.resource_cache_test_orientation_dependent, + getActivity().getTheme())); + } + + public void testConfigChangeMultipleThemes() + throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { + TypedValue[] staticValues = new TypedValue[]{new TypedValue(), new TypedValue()}; + TypedValue[] changingValues = new TypedValue[]{new TypedValue(), new TypedValue()}; + float staticDim = 0; + float changingDim = 0; + final Resources res = getActivity().getResources(); + for (int i = 0; i < 2; i++) { + res.getValue(R.dimen.resource_cache_test_generic, staticValues[i], true); + staticDim = TypedValue + .complexToDimension(staticValues[i].data, res.getDisplayMetrics()); + + res.getValue(R.dimen.resource_cache_test_orientation_dependent, changingValues[i], + true); + changingDim = TypedValue.complexToDimension(changingValues[i].data, + res.getDisplayMetrics()); + final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null; + mCache.put(R.dimen.resource_cache_test_generic, theme, + new DummyFloatConstantState(staticDim, staticValues[i].changingConfigurations)); + mCache.put(R.dimen.resource_cache_test_orientation_dependent, theme, + new DummyFloatConstantState(changingDim, + changingValues[i].changingConfigurations)); + } + final Configuration cfg = res.getConfiguration(); + Configuration newCnf = new Configuration(cfg); + newCnf.orientation = cfg.orientation == Configuration.ORIENTATION_LANDSCAPE ? + Configuration.ORIENTATION_PORTRAIT + : Configuration.ORIENTATION_LANDSCAPE; + int changes = calcConfigChanges(res, newCnf); + for (int i = 0; i < 2; i++) { + final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null; + assertEquals(staticDim, mCache.get(R.dimen.resource_cache_test_generic, theme)); + assertEquals(changingDim, + mCache.get(R.dimen.resource_cache_test_orientation_dependent, theme)); + } + mCache.onConfigurationChange(changes); + for (int i = 0; i < 2; i++) { + final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null; + assertEquals(staticDim, mCache.get(R.dimen.resource_cache_test_generic, theme)); + assertNull(mCache.get(R.dimen.resource_cache_test_orientation_dependent, theme)); + } + } + + private int calcConfigChanges(Resources resources, Configuration configuration) + throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { + if (mCalcConfigChanges == null) { + mCalcConfigChanges = Resources.class.getDeclaredMethod("calcConfigChanges", + Configuration.class); + mCalcConfigChanges.setAccessible(true); + } + return (Integer) mCalcConfigChanges.invoke(resources, configuration); + + } + + static class DummyFloatConstantState extends + ConstantState<Float> { + + final Float mObj; + + int mChangingConf = 0; + + DummyFloatConstantState(Float obj) { + mObj = obj; + } + + DummyFloatConstantState(Float obj, int changingConf) { + mObj = obj; + mChangingConf = changingConf; + } + + @Override + public int getChangingConfigurations() { + return mChangingConf; + } + + @Override + public Float newInstance() { + return new Float(mObj); + } + } +} diff --git a/core/tests/coretests/src/android/content/res/ResourceCacheActivity.java b/core/tests/coretests/src/android/content/res/ResourceCacheActivity.java new file mode 100644 index 000000000000..f37e549940ec --- /dev/null +++ b/core/tests/coretests/src/android/content/res/ResourceCacheActivity.java @@ -0,0 +1,37 @@ +/* +* Copyright (C) 2014 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.content.res; + +import android.annotation.Nullable; +import android.app.Activity; +import android.os.Bundle; + +import java.lang.ref.WeakReference; + +public class ResourceCacheActivity extends Activity { + static WeakReference<ResourceCacheActivity> lastCreatedInstance; + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + lastCreatedInstance = new WeakReference<ResourceCacheActivity>(this); + } + + public static ResourceCacheActivity getLastCreatedInstance() { + return lastCreatedInstance == null ? null : lastCreatedInstance.get(); + } +} diff --git a/docs/html/about/versions/android-5.0.jd b/docs/html/about/versions/android-5.0.jd index f8d8ab6d71f4..a43842099600 100644 --- a/docs/html/about/versions/android-5.0.jd +++ b/docs/html/about/versions/android-5.0.jd @@ -23,6 +23,7 @@ sdk.platform.apiLevel=21 <li><a href="#BehaviorGetRecentTasks">If your app uses getRecentTasks()...</a></li> <li><a href="#64BitSupport">If you are using the Android Native Development Kit (NDK)...</a></li> <li><a href="#BindService">If your app binds to a Service...</a></li> +<li><a href="#BehaviorWebView">If your app uses a WebView...</a></li> </ol> </li> <li><a href="#UI">User Interface</a> @@ -234,8 +235,8 @@ the system can present notifications correctly in vibration.</p> <p>Setting the device to -{@link android.media.AudioManager#RINGER_MODE_SILENT RINGER_MODE_SILENT} now -causes the device to enter the new priority mode. The device leaves priority +{@link android.media.AudioManager#RINGER_MODE_SILENT RINGER_MODE_SILENT} causes +the device to enter the new priority mode. The device leaves priority mode if you set it to {@link android.media.AudioManager#RINGER_MODE_NORMAL RINGER_MODE_NORMAL} or {@link android.media.AudioManager#RINGER_MODE_NORMAL RINGER_MODE_VIBRATE}.</p> @@ -366,6 +367,31 @@ and throws an exception if given an implicit intent. To ensure your app is secure, use an explicit intent when starting or binding your {@link android.app.Service}, and do not declare intent filters for the service.</p> +<h3 id="BehaviorWebView">If your app uses WebView...</h3> + +<p>Android 5.0 changes the default behavior for your app.</p> +<ul> +<li><strong>If your app targets API level 21 or higher:</strong> + <ul> + <li>The system + blocks <a href="https://developer.mozilla.org/en-US/docs/Security/MixedContent" + class="external-link">mixed content</a> and third party cookies by default. To allow mixed + content and third party cookies, use the + {@link android.webkit.WebSettings#setMixedContentMode(int) setMixedContentMode()} +and {@link android.webkit.CookieManager#setAcceptThirdPartyCookies(android.webkit.WebView, boolean) setAcceptThirdPartyCookies()} +methods respectively.</li> + <li>The system now intelligently chooses portions of the HTML + document to draw. This new default behavior helps to reduce memory + footprint and increase performance. If you want to + render the whole document at once, disable this optimization by calling + {@link android.webkit.WebView#enableSlowWholeDocumentDraw()}.</li> + </ul> +</li> +<li><strong>If your app targets API levels lower than 21:</strong> The system + allows mixed content and third party cookies, and always renders the whole + document at once.</li> +</ul> + <h2 id="UI">User Interface</h2> <h3 id="MaterialDesign">Material design support</h3> @@ -470,7 +496,7 @@ request the user’s permission by launching a screen capture dialog using an method.</p> <p>For an example of how to use the new APIs, see the {@code MediaProjectionDemo} -class in the {@code ApiDemos} sample project.</p> +class in the sample project.</p> <h2 id="Notifications">Notifications</h2> diff --git a/docs/html/about/versions/lollipop.jd b/docs/html/about/versions/lollipop.jd index 085dc247fd1c..3ee0a8643169 100644 --- a/docs/html/about/versions/lollipop.jd +++ b/docs/html/about/versions/lollipop.jd @@ -206,15 +206,16 @@ video apps and games to display smooth synchronized content.</p> <p>Android 5.0 also adds support for <strong>multimedia tunneling</strong> to provide the best experience for ultra-high definition (4K) content and the ability to play compressed audio and video data together. </p> -<!-- + <div class="figure" style="width:320px; margin:1em 0 0 20px;padding-left:2em;"> <img style="float:right; margin:0 1em 1em 2em" src="{@docRoot}images/android-5.0/managed_apps_launcher@2x.png" srcset="{@docRoot}images/android-5.0/managed_apps_launcher@2x.png 2x" alt="" width="300" /> -<p class="img-caption">Android Work users have a unified view of their personal and work apps, which are badged for easy identification.</p> +<p class="img-caption">Users have a unified view of their personal and work apps, which are +badged for easy identification.</p> </div> ---> + <h2 id="Work">Android in the workplace</h2> diff --git a/docs/html/auto/overview.jd b/docs/html/auto/overview.jd index cf63b9892217..ae1efecc064b 100644 --- a/docs/html/auto/overview.jd +++ b/docs/html/auto/overview.jd @@ -207,7 +207,7 @@ playback state through callbacks.</li> <p>The Android Auto app uses a car-specific UI model to display content and user interaction opportunities. Android Auto provides you with a standard UI designed to minimize driver -distraction. You do not have to test a custom UI for for driver distraction, which is a +distraction. You do not have to test a custom UI for driver distraction, which is a lengthy and expensive process involving multiple legislations across the globe and different standards for each vehicle OEM.</p> @@ -217,7 +217,7 @@ media apps. You can customize the UI colors, action icons, background images, an <h3 id="launchapp">Launcher</h3> <p>The launcher shows all the compatible media apps installed on the user’s -Android device and lets users select one of them from an scrollable list:</p> +Android device and lets users select one of them from a scrollable list:</p> <div class="auto-img-container-single"> <div class="auto-img-container"> diff --git a/docs/html/distribute/essentials/essentials_toc.cs b/docs/html/distribute/essentials/essentials_toc.cs index 4e53468b5194..a1c9575ec9ad 100644 --- a/docs/html/distribute/essentials/essentials_toc.cs +++ b/docs/html/distribute/essentials/essentials_toc.cs @@ -17,6 +17,12 @@ </div> </li> <li class="nav-section"> + <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/quality/wear.html"> + <span class="en">Wear App Quality</span> + </a> + </div> + </li> + <li class="nav-section"> <div class="nav-section empty" style="font-weight:normal"><a href="<?cs var:toroot?>distribute/essentials/optimizing-your-app.html"> <span class="en">Optimize Your App</span> </a> diff --git a/docs/html/distribute/essentials/quality/tv.jd b/docs/html/distribute/essentials/quality/tv.jd index 8e1715763b18..b13307e8c04f 100644 --- a/docs/html/distribute/essentials/quality/tv.jd +++ b/docs/html/distribute/essentials/quality/tv.jd @@ -234,7 +234,7 @@ page.image=/distribute/images/gp-tv-quality.png </td> <td> <p style="margin-bottom:.5em;"> - App does not depend on a remote controller having a menu button to access user interface + App does not depend on a remote controller having a Menu button to access user interface controls. (<a href="{@docRoot}training/tv/start/navigation.html#d-pad-navigation">Learn how</a>) </p> @@ -291,8 +291,8 @@ data-sortorder="-timestamp" data-cardsizes="9x3" data-maxresults="6"> </td> <td> <p style="margin-bottom:.5em;"> - App manifest sets an intent type of {@code ACTION_MAIN} with category - {@code CATEGORY_LEANBACK_LAUNCHER}. + App manifest sets an intent type of {@link android.content.Intent#ACTION_MAIN} with category + {@link android.content.Intent#CATEGORY_LEANBACK_LAUNCHER}. (<a href="{@docRoot}training/tv/start/start.html#tv-activity">Learn how</a>) </p> </td> @@ -321,8 +321,9 @@ data-sortorder="-timestamp" data-cardsizes="9x3" data-maxresults="6"> </td> <td> <p style="margin-bottom:.5em;"> - If the app requires a game controller, the app manifest sets the {@code uses-feature} setting - {@code android.hardware.gamepad} to {@code required="true"}. + If the app uses a game controller as it's primary input method, it declares the appropriate + requirement with the <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html" + >{@code <uses-feature>}</a> manifest tag. (<a href="{@docRoot}training/tv/games/index.html#gamepad">Learn how</a>) </p> </td> @@ -334,9 +335,9 @@ data-sortorder="-timestamp" data-cardsizes="9x3" data-maxresults="6"> </td> <td> <p style="margin-bottom:.5em;"> - If the app provides user instructions for use of game controllers, the instructions - do not include a controller with any branding. - (<a href="{@docRoot}training/tv/games/index.html#generic-controllers">Learn how</a>) + If the app provides visual instructions for using game controllers, the instructions should + be free of branding and show a compatible button layout. + (<a href="{@docRoot}training/tv/games/index.html#ControllerHelp">Learn how</a>) </p> </td> </tr> @@ -351,7 +352,7 @@ data-sortorder="-timestamp" data-cardsizes="9x3" data-maxresults="6"> </td> <td> <p style="margin-bottom:.5em;"> - App enables interaction with any advertising using D-pad controls. + App allows interaction with advertising using D-pad controls. (<a href="{@docRoot}training/tv/start/navigation.html#d-pad-navigation">Learn how</a>) </p> </td> @@ -363,7 +364,7 @@ data-sortorder="-timestamp" data-cardsizes="9x3" data-maxresults="6"> </td> <td> <p style="margin-bottom:.5em;"> - For advertising that uses full-screen, non-video ads, the app allows the user to + For advertising that uses fullscreen, non-video ads, the app allows the user to immediately dismiss the ad with D-pad controls. </p> </td> @@ -375,7 +376,7 @@ data-sortorder="-timestamp" data-cardsizes="9x3" data-maxresults="6"> </td> <td> <p style="margin-bottom:.5em;"> - For advertising that uses clickable, non-full screen, non-video ads, the app does not allow + For advertising that uses clickable, non-fullscreen, non-video ads, the app does not allow ads to link to a web URL. </p> </td> @@ -387,7 +388,7 @@ data-sortorder="-timestamp" data-cardsizes="9x3" data-maxresults="6"> </td> <td> <p style="margin-bottom:.5em;"> - For advertising that uses clickable, non-full screen, non-video ads, the app does not allow + For advertising that uses clickable, non-fullscreen, non-video ads, the app does not allow ads to link to another app that is not available on TV devices. </p> </td> diff --git a/docs/html/distribute/essentials/quality/wear.jd b/docs/html/distribute/essentials/quality/wear.jd new file mode 100644 index 000000000000..4125027e6a34 --- /dev/null +++ b/docs/html/distribute/essentials/quality/wear.jd @@ -0,0 +1,416 @@ +page.title=Wear App Quality +page.tags="wear","wearables","quality","guidelines" +page.metaDescription=Wearables are smaller devices that are built for glanceability and require unique apps to provide just the right information at the the right time. +page.image=/distribute/images/gp-wear-quality.png +@jd:body + +<div id="qv-wrapper"><div id="qv"> +<h2>Quality Criteria</h2> + <ol> + <li><a href="#ux">Design and Interaction</a></li> + <li><a href="#fn">Functionality</a></li> + <li><a href="#faq">Frequently Asked Questions</a></li> + </ol> + + <h2>You Should Also Read</h2> + <ol> + <li><a href="{@docRoot}distribute/essentials/quality/core.html"> + Core App Quality</a></li> + <li><a href="{@docRoot}distribute/essentials/optimizing-your-app.html"> + Optimize Your App</a></li> + <li><a href="{@docRoot}design/patterns/notifications.html"> + Notifications</a></li> + </ol> +</div> +</div> + +<img src="{@docRoot}distribute/images/gp-wear-quality.png" style="width:480px;"> + +<p> + Android Wear aims to provide users with just the right information at just the right time. Great + Android Wear experiences are launched automatically, glanceable, and require zero or low user + interaction. Designing apps for wearables is substantially different than designing for phones or + tablets. There are different strengths and weaknesses, different use cases, and different + ergonomics to take into consideration. +</p> + +<p> + The first step toward creating a great experience for users on Wear is to read the + <a href="{@docRoot}design/wear/index.html">Android Wear design guidelines</a>, which provides + instructions on how to build the best user experience for Wear apps. You should also review the + <a href="{@docRoot}training/building-wearables.html">Building Apps for Wearables</a> training, to + understand the basic implementation requirements for a Wear app. +</p> + +<p class="caution"> + <strong>Important:</strong> To ensure a great user experience, apps for wearables must meet + specific requirements for usability. Only apps that meet the following quality criteria will + qualify as an Android Wear app on Google Play. Qualifying as a Wear app will make it easier for + Android Wear users to discover your app on Google Play. +</p> + +<p class="note"> + <strong>Note:</strong> You will be able to submit your apps for Android Wear review when the + public release of Android 5.0 launches on November 3. Stay tuned for more information about how to + submit your apps for Android Wear review through the <a href="https://play.google.com/apps/publish/signup/">Google Play Developer Console</a>. +</p> + +<div class="headerLine"> + <h2 id="fn"> + Functionality + </h2> + + +</div> + +<p> + These criteria ensure that your app is configured correctly and provides the expected + functional behavior. +</p> + + +<table> +<tr> + <th style="width:2px;"> + Type + </th> + <th style="width:54px;"> + ID + </th> + <th> + Description + </th> +</tr> + +<tr> + <td rowspan="1" id="general"> + General + </td> + + <td id="WR-GL"> + WR-GL + </td> + <td> + <p style="margin-bottom:.5em;"> + Handheld app includes either notifications with wearable-specific functionality or a wearable + app that runs directly on the Wear device. + (<a href="{@docRoot}training/building-wearables.html">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td rowspan="1" id="packaging"> + Packaging + </td> + + <td id="WR-PK"> + WR-PK + </td> + <td> + <p style="margin-bottom:.5em;"> + Wearable apps that run directly on the device are packaged inside the primary handheld app. + (<a href="{@docRoot}training/wearables/apps/packaging.html">Learn how</a>) + </p> + </td> +</tr> + + +<tr> + <td rowspan="3" id="functional-notifications"> + Notifications + </td> + + <td id="WR-FW"> + WR-FW + </td> + <td> + <p style="margin-bottom:.5em;"> + Notifications with wearable-specific functionality use a {@code RemoteInput} or + {@code WearableExtender}. + (<a href="{@docRoot}training/wearables/notifications/index.html">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td id="WR-FR"> + WR-FR + </td> + <td> + <p style="margin-bottom:.5em;"> + Notifications for messaging apps allow users to reply via voice input or quick responses. + (<a href="{@docRoot}training/wearables/notifications/voice-input.html">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td id="WR-FG"> + WR-FG + </td> + <td> + <p style="margin-bottom:.5em;"> + Similar notifications are grouped together in a stack. + (<a href="{@docRoot}training/wearables/notifications/stacks.html">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td rowspan="2" id="gestures"> + Gestures + </td> + + <td id="WR-GP"> + WR-GP + </td> + <td> + <p style="margin-bottom:.5em;"> + Full-screen activities use long press for the sole purpose of prompting to quit. + <br/> + (<a href="{@docRoot}training/wearables/ui/exit.html">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td id="WR-GD"> + WR-GD + </td> + <td> + <p style="margin-bottom:.5em;"> + If the app disables the swipe-to-dismiss gesture in a full-screen activity, it responds to the + long-press-to-dismiss gesture in that activity. + (<a href="{@docRoot}training/wearables/ui/exit.html">Learn how</a>) + </p> + </td> +</tr> + +</table> + + +<h3 class="rel-resources clearfloat">Related resources</h3> + +<div class="resource-widget resource-flow-layout col-13" data-query= +"collection:distribute/essentials/wearqualityguidelines/functionality" +data-sortorder="-timestamp" data-cardsizes="6x2" data-maxresults="6"> +</div> + +<div class="headerLine"> + <h2 id="ux"> + Visual Design and User Interaction + </h2> + + +</div> + +<p> + These criteria ensure that your app follows critical design and interaction patterns to provide a + consistent, intuitive, and enjoyable user experience on wearables. +</p> + +<table> + +<tr> + <th style="width:2px;"> + Type + </th> + <th style="width:54px;"> + ID + </th> + <th> + Description + </th> +</tr> + +<tr> + <td rowspan="3" id="layout"> + Layout + </td> + + <td id="WR-LS"> + WR-LS + </td> + <td> + <p style="margin-bottom:.5em;"> + App user interface is formatted appropriately for square displays. App content fits within + the physical display area and no text or controls are cut off by the screen edges. + <br/> + (<a href="{@docRoot}training/wearables/ui/layouts.html">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td id="WR-LR"> + WR-LR + </td> + <td> + <p style="margin-bottom:.5em;"> + App user interface is formatted appropriately for round displays. App content fits within + the physical display area and no text or controls are cut off by the screen edges. + <br/> + (<a href="{@docRoot}training/wearables/ui/layouts.html">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td id="WR-TC"> + WR-TC + </td> + <td> + <p style="margin-bottom:.5em;"> + App text is large and glanceable with a suggested minimum size of 16sp. + (<a href="{@docRoot}design/wear/style.html#Typography">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td rowspan="1" id="launcher"> + Launcher + </td> + + <td id="WR-LN"> + WR-LN + </td> + <td> + <p style="margin-bottom:.5em;"> + App launcher string is the app name, not a command phrase. + (<a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td rowspan="5" id="notifications"> + Notifications + </td> + + <td id="WR-NC"> + WR-NC + </td> + <td> + <p style="margin-bottom:.5em;"> + App displays confirmation animations when appropriate. + (<a href="{@docRoot}design/wear/patterns.html#Countdown">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td id="WR-NR"> + WR-NR + </td> + <td> + <p style="margin-bottom:.5em;"> + Notification cards have the app icon visible at the top right edge. The one exception is if the + notification card has single-action controls, for example a media playback card. + <br/> + (<a href="{@docRoot}design/wear/style.html#Assets">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td id="WR-WI"> + WR-WI + </td> + <td> + <p style="margin-bottom:.5em;"> + Notification actions have a white icon, action title, and transparent background. + <br/> + (<a href="{@docRoot}training/wearables/notifications/creating.html#ActionButtons">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td id="WR-PB"> + WR-PB + </td> + <td> + <p style="margin-bottom:.5em;"> + Notification photo backgrounds are used only to convey information, not to brand a card. + (<a href="{@docRoot}design/wear/style.html#Branding">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td id="WR-PR"> + WR-PR + </td> + <td> + <p style="margin-bottom:.5em;"> + Notification photo backgrounds have a resolution of at least 400x400. + (<a href="{@docRoot}training/wearables/notifications/creating.html#AddWearableFeatures">Learn how</a>) + </p> + </td> +</tr> + +<tr> + <td rowspan="1" id="googleplay"> + Google Play + </td> + + <td id="WR-GS"> + WR-GS + </td> + <td> + <p style="margin-bottom:.5em;"> + App includes at least one Wear screenshot in its Play Store Listing. + (<a href="https://support.google.com/googleplay/android-developer/answer/1078870?hl=en">Learn how</a>) + </p> + </td> +</tr> + +</table> + + +<h3 class="rel-resources clearfloat">Related resources</h3> + +<div class="resource-widget resource-flow-layout col-13" data-query= +"collection:distribute/essentials/wearqualityguidelines/visualdesign" +data-sortorder="-timestamp" data-cardsizes="6x2" data-maxresults="6"> +</div> + +<div class="headerLine"> + <h2 id="faq"> + Frequently Asked Questions + </h2> +</div> + +<p style="margin-top:30px;"> + <strong>After I submit my app for Android Wear review, how will I find out if my app does not meet + all the requirements for Wear?</strong> +</p> +<p> + If your app does not meet the usability requirements described on this page, the Play Store team + will contact you through the email address specified in the <a href= + "https://play.google.com/apps/publish/">Google Play Developer Console</a> account associated with + the app. +</p> +<p class="caution"> + <strong>Caution:</strong> Make sure your app meets the <a href="#fn">functionality + requirements</a>, otherwise your app will not be considered a Wear app and will not be reviewed + for Wear <a href="#ux">design and interaction</a>. +</p> +<p class="note"> + <strong>Note:</strong> You will be able to submit your apps for additional Android Wear review when + the public release of Android 5.0 launches on November 3. +</p> + + +<p style="margin-top:30px;"> + <strong>If my app does not meet the Wear requirements, will my new or updated app still appear on + Google Play for phones and tablets and still be installable on wearables?</strong> +</p> +<p> + Yes. The requirements described above only determine whether your app will be identified as an + Android Wear app on Google Play and easier for Android Wear users to discover. If your app is not + accepted as a Wear app, it will still be available to other device types, such as phones and + tablets, and it will still be installable on wearables. +</p> diff --git a/docs/html/distribute/images/gp-wear-quality.png b/docs/html/distribute/images/gp-wear-quality.png Binary files differnew file mode 100644 index 000000000000..a51a32c1ad09 --- /dev/null +++ b/docs/html/distribute/images/gp-wear-quality.png diff --git a/docs/html/google/play/billing/billing_testing.jd b/docs/html/google/play/billing/billing_testing.jd index 10f5326411dc..36456ccc1900 100644 --- a/docs/html/google/play/billing/billing_testing.jd +++ b/docs/html/google/play/billing/billing_testing.jd @@ -10,7 +10,7 @@ page.tags="inapp, billing, iap" <ol> <li><a href="#testing-purchases">Testing In-app Purchases</a></li> <li><a href="#billing-testing-static">Testing with Static Responses</a></li> - <li><a href="#billing-testing-real">Setting Up for Test Purchases</a></li> + <li><a href="#billing-testing-test">Setting Up for Test Purchases</a></li> <li><a href="#draft_apps">Draft Apps are No Longer Supported</a></li> </ol> <h2>See also</h2> diff --git a/docs/html/guide/topics/ui/actionbar.jd b/docs/html/guide/topics/ui/actionbar.jd index a61696a987a2..d972c47f59ad 100644 --- a/docs/html/guide/topics/ui/actionbar.jd +++ b/docs/html/guide/topics/ui/actionbar.jd @@ -1427,7 +1427,7 @@ href="#ActionView">action views</a>.</dd> <p>Here's an example that defines a custom theme for an activity, {@code CustomActivityTheme}, that includes several styles to customize the action bar.</p> -<p>Notice that there are two version for each action bar style property. The first one +<p>Notice that there are two versions for each action bar style property. The first one includes the {@code android:} prefix on the property name to support API levels 11 and higher that include these properties in the framework. The second version does <em>not</em> include the {@code android:} prefix and is for older versions of the platform, on which diff --git a/docs/html/images/android-5.0/managed_apps_launcher.png b/docs/html/images/android-5.0/managed_apps_launcher.png Binary files differindex 818455634dbb..46e4c74d3fac 100644 --- a/docs/html/images/android-5.0/managed_apps_launcher.png +++ b/docs/html/images/android-5.0/managed_apps_launcher.png diff --git a/docs/html/images/android-5.0/managed_apps_launcher@2x.png b/docs/html/images/android-5.0/managed_apps_launcher@2x.png Binary files differindex 66b7be91c2f9..d7fdbce3eff0 100644 --- a/docs/html/images/android-5.0/managed_apps_launcher@2x.png +++ b/docs/html/images/android-5.0/managed_apps_launcher@2x.png diff --git a/docs/html/images/games/game-controller-buttons.png b/docs/html/images/games/game-controller-buttons.png Binary files differnew file mode 100644 index 000000000000..b3e458ab08b5 --- /dev/null +++ b/docs/html/images/games/game-controller-buttons.png diff --git a/docs/html/images/games/game-controller-buttons_2x.png b/docs/html/images/games/game-controller-buttons_2x.png Binary files differnew file mode 100644 index 000000000000..7a0ad0b506d8 --- /dev/null +++ b/docs/html/images/games/game-controller-buttons_2x.png diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js index c49f8cc93123..08c00902ac24 100644 --- a/docs/html/jd_collections.js +++ b/docs/html/jd_collections.js @@ -67,9 +67,9 @@ var RESOURCE_COLLECTIONS = { "distribute/essentials/quality/core.html", "distribute/essentials/quality/tablets.html", "distribute/essentials/quality/tv.html", + "distribute/essentials/quality/wear.html", "https://developers.google.com/edu/guidelines", - "distribute/essentials/optimizing-your-app.html", - "distribute/essentials/best-practices/games.html" + "distribute/essentials/optimizing-your-app.html" ] }, "distribute/users": { @@ -332,6 +332,22 @@ var RESOURCE_COLLECTIONS = { "training/tv/games/index.html" ] }, + "distribute/essentials/wearqualityguidelines/visualdesign": { + "title": "", + "resources": [ + "design/wear/index.html", + "training/building-wearables.html", + "training/wearables/ui/index.html" + ] + }, + "distribute/essentials/wearqualityguidelines/functionality": { + "title": "", + "resources": [ + "training/wearables/notifications/index.html", + "training/wearables/apps/index.html", + "training/wearables/notifications/voice-input.html" + ] + }, "distribute/essentials/core/performance": { "title": "", "resources": [ diff --git a/docs/html/samples/new/index.jd b/docs/html/samples/new/index.jd index 523b922c376e..330caa309af0 100644 --- a/docs/html/samples/new/index.jd +++ b/docs/html/samples/new/index.jd @@ -348,3 +348,18 @@ AppRestrictionEnforcer sample to toggle the restriction. </p> <p><a href="http://github.com/googlesamples/android-AppRestrictionSchema">Get it on GitHub</a></p> + +<h3 id="SpeedTracker">Speed Tracker (Wear)</h3> + +<p> +This sample uses the FusedLocation APIs of Google Play Services on Android Wear +devices that have a hardware GPS built in. In those cases, this sample provides +a simple screen that shows the current speed of the wearable device. User can +set a speed limit and if the speed approaches that limit, it changes the color +to yellow and if it exceeds the limit, it turns red. User can also enable +recording of coordinates and when it pairs back with the phone, this data +is synced with the phone component of the app and user can see a track +made of those coordinates on a map on the phone. +</p> + +<p><a href="http://github.com/googlesamples/android-SpeedTracker">Get it on GitHub</a></p> diff --git a/docs/html/samples/wearable.jd b/docs/html/samples/wearable.jd new file mode 100644 index 000000000000..311437425a1c --- /dev/null +++ b/docs/html/samples/wearable.jd @@ -0,0 +1,11 @@ +page.title=Wearable +@jd:body + + +<div id="samples" class="wearable"> +</div> + + +<script> + $(document).ready(showSamples); +</script> diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd index 3d9ef21bfc5b..a64679532d7c 100644 --- a/docs/html/sdk/index.jd +++ b/docs/html/sdk/index.jd @@ -243,7 +243,7 @@ This is the Android Software Development Kit License Agreement <h1 style="margin-top:0">Get the Android SDK</h1> -<p>The Android SDK provides you the API libraries and developer tools necessary to build, test, +<p>The Android SDK provides the API libraries and developer tools necessary to build, test, and debug apps for Android.</p> <p>Download the ADT Bundle to quickly start developing apps. It includes the essential Android diff --git a/docs/html/sdk/installing/adding-packages.jd b/docs/html/sdk/installing/adding-packages.jd index e6c0118cca5c..22d055c14aef 100644 --- a/docs/html/sdk/installing/adding-packages.jd +++ b/docs/html/sdk/installing/adding-packages.jd @@ -1,5 +1,8 @@ page.title=Adding SDK Packages +page.tags=studio, sdk tools, eclipse adt, sdk manager, google play services, support library +helpoutsWidget=true + @jd:body <style> diff --git a/docs/html/sdk/installing/index.jd b/docs/html/sdk/installing/index.jd index ec0e2f8fa46e..6a99952319df 100644 --- a/docs/html/sdk/installing/index.jd +++ b/docs/html/sdk/installing/index.jd @@ -1,5 +1,8 @@ page.title=Installing the Android SDK +page.tags=studio, sdk tools, eclipse adt +helpoutsWidget=true + @jd:body <style> diff --git a/docs/html/support.jd b/docs/html/support.jd index 4271eee2d1a7..bbed7df7b3cc 100644 --- a/docs/html/support.jd +++ b/docs/html/support.jd @@ -3,6 +3,7 @@ page.type=about fullpage=1 page.metaDescription=Resources available to help you report and resolve issues while you are developing apps for Android. page.image=/images/android-support-card.png + @jd:body <div class="wrap" style="width:940px;"> @@ -28,13 +29,20 @@ page.image=/images/android-support-card.png <a href="http://webchat.freenode.net/?channels=android">#android</a>, <a href="http://webchat.freenode.net/?channels=android-dev">#android-dev</a> <span style="color:#888">(IRC via irc.freenode.net)</span><br /> </p> +<p><b> +<a target="_blank" +href="https://helpouts.google.com/partner/ask?vertical=programming&tags=android&origin=http:%2F%2Fdeveloper.android.com%2Fsupport.html">Ask a question in Google Helpouts</a> +</b></p> + <h5>Send Feedback</h5> <p> <a href="http://code.google.com/p/android/issues/entry?template=Developer%20Documentation">Report documentation bug</a><br /> <a href="https://code.google.com/p/android/issues/entry?template=User%20bug%20report">Report device bug</a><br /> <a href="https://code.google.com/p/android/issues/entry?template=Developer%20bug%20report">Report platform bug</a><br /> - +</p> + + </div> diff --git a/docs/html/tools/debugging/debugging-memory.jd b/docs/html/tools/debugging/debugging-memory.jd index fccb67ec7a60..ae67b3c16df7 100644 --- a/docs/html/tools/debugging/debugging-memory.jd +++ b/docs/html/tools/debugging/debugging-memory.jd @@ -243,7 +243,7 @@ here, as some details of the output differ across platform versions.</p> Other mmap 107 0 8 8 324 68 Unknown 6994(4) 0 252 6992(4) 0 0 TOTAL 24358(1) 4188 9724 17972(2)16388 4260(2)16968 16595 336 - + Objects Views: 426 ViewRootImpl: 3(8) AppContexts: 6(7) Activities: 2(7) @@ -251,7 +251,7 @@ here, as some details of the output differ across platform versions.</p> Local Binders: 64 Proxy Binders: 34 Death Recipients: 0 OpenSSL Sockets: 1 - + SQL MEMORY_USED: 1739 PAGECACHE_OVERFLOW: 1164 MALLOC_SIZE: 62 @@ -374,7 +374,7 @@ all app processes, they don’t matter very much to your own heap analysis.</p> <p>To analyze your heap dump, you can use a standard tool like jhat or the <a href= "http://www.eclipse.org/mat/downloads.php">Eclipse Memory Analyzer Tool</a> (MAT). However, first you'll need to convert the HPROF file from Android's format to the J2SE HPROF format. You can do -this using the <code>hprof-conv</code> tool provided in the <code><sdk>/tools/</code> +this using the <code>hprof-conv</code> tool provided in the <code><sdk>/platform-tools/</code> directory. Simply run the <code>hprof-conv</code> command with two arguments: the original HPROF file and the location to write the converted HPROF file. For example:</p> diff --git a/docs/html/tools/devices/managing-avds.jd b/docs/html/tools/devices/managing-avds.jd index 10633d264fca..d3bbfdcd2052 100644 --- a/docs/html/tools/devices/managing-avds.jd +++ b/docs/html/tools/devices/managing-avds.jd @@ -31,6 +31,12 @@ parent.link=index.html <p>From the main screen, you can create, delete, repair and start AVDs as well as see the details of each AVD. </p> + + <p class="note"><strong>Note:</strong> The emulator system images include experimental +64-bit system images along with standard 32-bit system images. The 64-bit system images +require the Intel x86 Emulator Accelerator (HAXM) Rev.5 which can be downloaded from the +<a href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a> <em>Extras</em> folder. + </p> <h2 id="createavd">Creating an AVD</h2> diff --git a/docs/html/tools/revisions/build-tools.jd b/docs/html/tools/revisions/build-tools.jd index fe78ce946421..6f0775561ffe 100644 --- a/docs/html/tools/revisions/build-tools.jd +++ b/docs/html/tools/revisions/build-tools.jd @@ -77,6 +77,28 @@ listing in the Android SDK Manager.</p> <div class="toggle-content opened"> <p><a href="#" onclick="return toggleContent(this)"> <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-content-img" + alt=""/>Build Tools, Revision 21.0.2</a> <em>(October 2014)</em> + </p> + <div class="toggle-content-toggleme"> + <p>Complete updates for Eclipse ADT to solve instability issues on Windows platforms.</p> + </div> +</div> + + +<div class="toggle-content closed"> + <p><a href="#" onclick="return toggleContent(this)"> + <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" + alt=""/>Build Tools, Revision 21.0.1</a> <em>(October 2014)</em> + </p> + <div class="toggle-content-toggleme"> + <p>Initial updates for Eclipse ADT on Windows. Please use Revision 21.0.2.</p> + </div> +</div> + + +<div class="toggle-content closed"> + <p><a href="#" onclick="return toggleContent(this)"> + <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" alt=""/>Build Tools, Revision 21.0.0</a> <em>(October 2014)</em> </p> <div class="toggle-content-toggleme"> @@ -96,6 +118,7 @@ listing in the Android SDK Manager.</p> </div> </div> + <div class="toggle-content closed"> <p><a href="#" onclick="return toggleContent(this)"> <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-content-img" diff --git a/docs/html/tools/revisions/platforms.jd b/docs/html/tools/revisions/platforms.jd index 3fa1b9bd325a..85b9c5ede3a6 100644 --- a/docs/html/tools/revisions/platforms.jd +++ b/docs/html/tools/revisions/platforms.jd @@ -80,6 +80,23 @@ class="toggle-content-img" alt="" />Revision 1</a> <em>(October 2014)</em> <h2 id="4.4">Android 4.4W</h2> +<div class="toggle-content open"> + <p><a href="#" onclick="return toggleContent(this)"> + <img src="{@docRoot}assets/images/triangle-open.png" +class="toggle-content-img" alt="" />Revision 2</a> <em>(October 2014)</em> + </p> + + <div class="toggle-content-toggleme"> + + <p>Added location APIs support for Wear.</p> + + <p>Dependencies:</p> + <ul> + <li>Android SDK Platform-tools r20 or higher is required.</li> + <li>Android SDK Tools 23.0 or higher is required.</li> + </ul> + </div> + <div class="toggle-content closed"> <p><a href="#" onclick="return toggleContent(this)"> <img src="{@docRoot}assets/images/triangle-closed.png" diff --git a/docs/html/tools/sdk/tools-notes.jd b/docs/html/tools/sdk/tools-notes.jd index 20388be11fa7..3e3cb4b374da 100644 --- a/docs/html/tools/sdk/tools-notes.jd +++ b/docs/html/tools/sdk/tools-notes.jd @@ -13,7 +13,7 @@ latest revision of the SDK Tools in the <code><sdk>/tools</code> directory of the SDK Tools, use the <em>Android SDK Manager</em> to get the update, rather than downloading a new SDK starter package. For more information about how to update, see <a -href="{@docRoot}sdk/exploring.html#UpdatingComponents">Exploring the SDK</a>.</p> +href="{@docRoot}tools/help/sdk-manager.html">SDK Manager</a>.</p> <h2 id="notes">Revisions</h2> diff --git a/docs/html/tools/support-library/features.jd b/docs/html/tools/support-library/features.jd index 8311097c155e..44c504547db8 100644 --- a/docs/html/tools/support-library/features.jd +++ b/docs/html/tools/support-library/features.jd @@ -139,10 +139,10 @@ page.title=Support Library Features <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:support-v4:18.0.+ +com.android.support:support-v4:21.0.+ </pre> -<p>This dependency notation specifies the release version 18.0.0 or higher.</p> +<p>This dependency notation specifies the release version 21.0.0 or higher.</p> <h2 id="v7">v7 Support Libraries</h2> @@ -237,10 +237,10 @@ com.android.support:cardview-v7:21.0.+ <p>The Gradle build script dependency identifier for this library is as follows:</p> <pre> -com.android.support:gridlayout-v7:18.0.+ +com.android.support:gridlayout-v7:21.0.+ </pre> -<p>This dependency notation specifies the release version 18.0.0 or higher.</p> +<p>This dependency notation specifies the release version 21.0.0 or higher.</p> <h3 id="v7-mediarouter">v7 mediarouter library</h3> @@ -271,10 +271,10 @@ both the <code>android-support-v7-mediarouter.jar</code> and <p>If you are using Android Studio, all you need to do is specify the Gradle build script dependency identifier <code>com.android.support:support-v7-mediarouter:<revision></code>, -where "18.0.0" is the minimum revision at which the library is available. For example:</p> +where "<revision>" is the minimum revision at which the library is available. For example:</p> <pre> -com.android.support:mediarouter-v7:18.0.+ +com.android.support:mediarouter-v7:21.0.+ </pre> <p class="caution">The v7 mediarouter library APIs introduced in Support Library diff --git a/docs/html/training/articles/wear-location-detection.jd b/docs/html/training/articles/wear-location-detection.jd new file mode 100644 index 000000000000..b0d975548a24 --- /dev/null +++ b/docs/html/training/articles/wear-location-detection.jd @@ -0,0 +1,375 @@ +page.title=Detecting Location on Android Wear +page.tags="gps" + +page.article=true +@jd:body + +<div id="tb-wrapper"> +<div id="tb"> +<h2>In this document</h2> +<ol class="nolist"> + <li><a href="#Connect">Connect to Google Play Services</a></li> + <li><a href="#Request">Request Location Updates</a></li> + <li><a href="#DetectGPS">Detect On-Board GPS</a></li> + <li><a href="#Disconnection">Handle Disconnection Events</a></li> + <li><a href="#Notify">Handle Location Not Found</a></li> + <li><a href="#Synchronize">Synchronize Data</a></li> +</ol> +<!-- Required platform, tools, add-ons, devices, knowledge, etc. --> +<h2>Dependencies and prerequisites</h2> +<ul> + <li>Android 4.3 (API Level 18) or higher on the handset device</li> + <li><a href="{@docRoot}google/play-services/index.html">Google Play services</a> 6.1 or higher</li> + <li>An Android Wear device</li> +</ul> +<h2>See also</h2> +<ul> + <li><a href="{@docRoot}training/location/index.html">Making Your App Location-Aware + </a></li> +</ul> +</div></div> + +<p>Location awareness on wearable devices enables you to create apps that give users a better +understanding of their geographic position, movement and what's around them. With the small form +factor and glanceable nature of a wearable device, you can build low-friction apps that record and +respond to location data.</p> + +<p>Some wearable devices include a GPS sensor that can retrieve location data without another +tethered device. However, when you request location data in a wearable app, you don't have to worry +about where the location data originates; the system retrieves the location updates using the most +power-efficient method. Your app should be able to handle loss of location data, in case the wear +device loses connection with its paired device and does not have a built-in GPS sensor.</p> + +<p>This document shows you how to check for on-device location sensors, receive location data, and +monitor tethered data connections.</p> + +<p class="note"><b>Note:</b> The article assumes that you know how to use the Google Play services +API to retrieve location data. For more information, see <a href="{@docRoot}training/ +location/index.html">Making Your App Location-Aware</a>.</p> + +<h2 id="Connect">Connect to Google Play Services</h2> + +<p>Location data on wearable devices is obtained though the Google Play services location APIs. You +use the <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html"> +<code>FusedLocationProviderApi</code></a> and its accompanying classes to obtain this data. +To access location services, create an instance of +<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html"> +<code>GoogleApiClient</code></a>, which is +the main entry point for any of the Google Play services APIs. +</p> + +<p class="caution"><b>Caution:</b> Do not use the existing <a href="{@docRoot}reference/android/location/package-summary.html">Location</a> +APIs in the Android framework. The best practice for retrieving location updates is through the +Google Play services API as outlined in this article.</p> + +<p>To connect to Google Play services, configure your app to create an instance of +<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html"> +<code>GoogleApiClient</code></a>:</p> + +<ol> + <li>Create an activity that specifies an implementation for the interfaces <a +href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html" +>{@code ConnectionCallbacks}</a>, <a href="{@docRoot}reference/com/google/android/gms/common/api/ +GoogleApiClient.OnConnectionFailedListener.html">{@code OnConnectionFailedListener}</a>, and <a +href="{@docRoot}reference/com/google/android/gms/location/LocationListener.html">{@code +LocationListener}</a>.</li> + <li>In your activity's {@link android.app.Activity#onCreate onCreate()} method, create an instance +of <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html"><code> +GoogleApiClient</code></a> and add the Location service. + </li> + <li>To gracefully manage the lifecycle of the connection, call <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html#connect()"> + {@code connect()}</a> in the {@link android.app.Activity#onResume onResume()} method and + <a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.html#disconnect()"> + {@code disconnect()}</a> in the {@link android.app.Activity#onPause onPause()} method. + </li> +</ol> + +<p>The following code example shows an implementation of an activity that implements the +<a href="{@docRoot}reference/com/google/android/gms/location/LocationListener.html"> +{@code LocationListener}</a> interface:</p> + +<pre> +public class WearableMainActivity extends Activity implements + GoogleApiClient.ConnectionCallbacks, + GoogleApiClient.OnConnectionFailedListener, + LocationListener { + + private GoogleApiClient mGoogleApiClient; + ... + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ... + mGoogleApiClient = new GoogleApiClient.Builder(this) + .addApi(LocationServices.API) + .addApi(Wearable.API) // used for data layer API + .addConnectionCallbacks(this) + .addOnConnectionFailedListener(this) + .build(); + } + + @Override + protected void onResume() { + super.onResume(); + mGoogleApiClient.connect(); + ... + } + + @Override + protected void onPause() { + super.onPause(); + ... + mGoogleApiClient.disconnect(); + } +} +</pre> + +<p>For more information on connecting to Google Play services, see <a href="{@docRoot}google/auth +/api-client.html">Accessing Google APIs</a>.</p> + +<h2 id="Request">Request Location Updates</h2> + +<p>After your app has connected to the Google Play services API, it is ready to start receiving +location updates. When the system invokes the +<a href="{@docRoot}reference/com/google/android/gms/common/api/GoogleApiClient.ConnectionCallbacks.html#onConnected(android.os.Bundle)"> +<code>onConnected()</code></a> callback for your client, you build the location data request as +follows:</p> + +<ol> + <li>Create a <a +href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html" +>{@code LocationRequest}</a> object and set any options using methods like <a +href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setPriority(int)" +>{@code setPriority()}</a>. + </li> + <li>Request location updates using <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#requestLocationUpdates(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.location.LocationRequest, com.google.android.gms.location.LocationListener)"> + <code>requestLocationUpdates()</code></a>. + </li> + <li>Remove location updates using <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#removeLocationUpdates(com.google.android.gms.common.api.GoogleApiClient, com.google.android.gms.location.LocationListener)"> + <code>removeLocationUpdates()</code></a> in the {@link android.app.Activity#onPause + onPause()} method. + </li> +</ol> + +<p>The following example shows how to retrieve and remove location updates:</p> + +<pre> +@Override +public void onConnected(Bundle bundle) { + LocationRequest locationRequest = LocationRequest.create() + .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) + .setInterval(UPDATE_INTERVAL_MS) + .setFastestInterval(FASTEST_INTERVAL_MS); + + LocationServices.FusedLocationApi + .requestLocationUpdates(mGoogleApiClient, locationRequest, this) + .setResultCallback(new ResultCallback<Status>() { + + @Override + public void onResult(Status status) { + if (status.getStatus().isSuccess()) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "Successfully requested location updates"); + } + } else { + Log.e(TAG, + "Failed in requesting location updates, " + + "status code: " + + status.getStatusCode() + + ", message: " + + status.getStatusMessage()); + } + } + }); +} + +@Override +protected void onPause() { + super.onPause(); + if (mGoogleApiClient.isConnected()) { + LocationServices.FusedLocationApi + .removeLocationUpdates(mGoogleApiClient, this); + } + mGoogleApiClient.disconnect(); +} + +@Override +public void onConnectionSuspended(int i) { + if (Log.isLoggable(TAG, Log.DEBUG)) { + Log.d(TAG, "connection to location client suspended"); + } +} + +</pre> + +<p>Now that you have enabled location updates, the system calls the {@link android.location.LocationListener#onLocationChanged +onLocationChanged()} method with the updated location at the interval specified in <a +href="{@docRoot}reference/com/google/android/gms/location/LocationRequest.html#setInterval(long)"> +{@code setInterval()}</a> +</p> + +<h2 id="DetectGPS">Detect On-Board GPS</h2> + +<p>Not all wearables have a GPS sensor. If your user goes out for a run and leaves their phone at +home, your wearable app cannot receive location data through a tethered connection. If the +wearable device does not have a sensor, you should detect this situation and warn the user that +location functionality is not available. + +<p>To determine whether your Android Wear device has a built-in GPS sensor, use the +{@link android.content.pm.PackageManager#hasSystemFeature hasSystemFeature()} +method. The following code detects whether the device has built-in GPS when you start an activity: +</p> + +<pre> + +protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.main_activity); + if (!hasGps()) { + Log.d(TAG, "This hardware doesn't have GPS."); + // Fall back to functionality that does not use location or + // warn the user that location function is not available. + } + + ... +} + +private boolean hasGps() { + return getPackageManager().hasSystemFeature(PackageManager.FEATURE_LOCATION_GPS); +} +</pre> + +<h2 id="Disconnection">Handle Disconnection Events</h2> + +<p>Wearable devices relying on a tethered connection for location data may lose their connections +abruptly. If your wearable app expects a constant stream of data, you must handle the +disconnection based upon where that data is interrupted or unavailable. On a wearable device with no +onboard GPS sensor, loss of location data occurs when the device loses its tethered data connection. +</p> + +<p>In cases where your app depends on a tethered data connection for location data and the wear +device does not have a GPS sensor, you should detect the loss of that connection, warn the user, and +gracefully degrade the functionality of your app.</p> + +<p>To detect the loss of a tethered data connection:</p> + +<ol> + <li>Extend a <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"> + <code>WearableListenerService</code></a> that lets you listen for important data layer events. + </li> + <li>Declare an intent filter in your Android manifest to notify the system about your + <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html"><code> + WearableListenerService</code></a>. + This filter allows the system to bind your service as needed. +<pre> +<service android:name=".NodeListenerService"> + <intent-filter> + <action android:name="com.google.android.gms.wearable.BIND_LISTENER" /> + </intent-filter> +</service> +</pre> + </li> + <li>Implement the <a href="{@docRoot}reference/com/google/android/gms/wearable/WearableListenerService.html#onPeerDisconnected(com.google.android.gms.wearable.Node)"> + <code>onPeerDisconnected()</code></a> method and handle cases of whether or not the device has + built-in + GPS. +<pre> +public class NodeListenerService extends WearableListenerService { + + private static final String TAG = "NodeListenerService"; + + @Override + public void onPeerDisconnected(Node peer) { + Log.d(TAG, "You have been disconnected."); + if(!hasGPS()) { + // Notify user to bring tethered handset + // Fall back to functionality that does not use location + } + } + ... +} +</pre> + </li> +</ol> + +For more information, read the <a href="{@docRoot}training/wearables/data-layer/events.html#Listen"> +Listen for Data Layer Events</a> guide. + +<h2 id="Notify">Handle Location Not Found</h2> + +<p>When the GPS signal is lost, you can still retrieve the last known location using +<a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#getLastLocation(com.google.android.gms.common.api.GoogleApiClient)"> +<code>getLastLocation()</code></a>. This method can be helpful in situations where you are unable to +get a GPS fix, or when your wearable doesn't have built-in GPS and loses its connection with the +phone.</p> + +<p>The following code uses <a href="{@docRoot}reference/com/google/android/gms/location/FusedLocationProviderApi.html#getLastLocation(com.google.android.gms.common.api.GoogleApiClient)"> +<code>getLastLocation()</code></a> to retrieve the last known location if available: +</p> + +<pre> +Location location = LocationServices.FusedLocationApi + .getLastLocation(mGoogleApiClient); +</pre> + +<h2 id="Synchronize">Synchronize Data</h2> + +<p>If your wearable app records data using the built-in GPS, you may want to synchronize +the location data with the handset. With the {@link android.location.LocationListener}, you +implement the {@link android.location.LocationListener#onLocationChanged onLocationChanged()} +method to detect and record the location as it changes. + +<p>The following code for wearable apps detects when the location changes and uses the data layer +API to store the data for later retrieval by your phone app:</p> + +<pre> +@Override +public void onLocationChanged(Location location) { + ... + addLocationEntry(location.getLatitude(), location.getLongitude()); + +} + +private void addLocationEntry(double latitude, double longitude) { + if (!mSaveGpsLocation || !mGoogleApiClient.isConnected()) { + return; + } + + mCalendar.setTimeInMillis(System.currentTimeMillis()); + + // Set the path of the data map + String path = Constants.PATH + "/" + mCalendar.getTimeInMillis(); + PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(path); + + // Set the location values in the data map + putDataMapRequest.getDataMap() + .putDouble(Constants.KEY_LATITUDE, latitude); + putDataMapRequest.getDataMap() + .putDouble(Constants.KEY_LONGITUDE, longitude); + putDataMapRequest.getDataMap() + .putLong(Constants.KEY_TIME, mCalendar.getTimeInMillis()); + + // Prepare the data map for the request + PutDataRequest request = putDataMapRequest.asPutDataRequest(); + + // Request the system to create the data item + Wearable.DataApi.putDataItem(mGoogleApiClient, request) + .setResultCallback(new ResultCallback<DataApi.DataItemResult>() { + @Override + public void onResult(DataApi.DataItemResult dataItemResult) { + if (!dataItemResult.getStatus().isSuccess()) { + Log.e(TAG, "Failed to set the data, " + + "status: " + dataItemResult.getStatus() + .getStatusCode()); + } + } + }); +} +</pre> + +<p>For more information on how to use the Data Layer API, see the <a href="{@docRoot}training/ +wearables/data-layer/index.html">Sending and Syncing Data</a> +guide.</p> diff --git a/docs/html/training/basics/firstapp/building-ui.jd b/docs/html/training/basics/firstapp/building-ui.jd index 179b3ac445a2..c0826427fd40 100644 --- a/docs/html/training/basics/firstapp/building-ui.jd +++ b/docs/html/training/basics/firstapp/building-ui.jd @@ -1,12 +1,8 @@ page.title=Building a Simple User Interface -parent.title=Building Your First App -parent.link=index.html - trainingnavtop=true -previous.title=Running Your App -previous.link=running-app.html -next.title=Starting Another Activity -next.link=starting-activity.html + +page.tags=ui, views, layouts, widgets, string resources +helpoutsWidget=true @jd:body diff --git a/docs/html/training/basics/firstapp/creating-project.jd b/docs/html/training/basics/firstapp/creating-project.jd index c4cb362e6d1f..418eb687bb48 100644 --- a/docs/html/training/basics/firstapp/creating-project.jd +++ b/docs/html/training/basics/firstapp/creating-project.jd @@ -1,6 +1,7 @@ page.title=Creating an Android Project -parent.title=Building Your First App -parent.link=index.html + +page.tags=eclipse adt, sdk tools, project setup +helpoutsWidget=true trainingnavtop=true next.title=Running Your App diff --git a/docs/html/training/basics/firstapp/index.jd b/docs/html/training/basics/firstapp/index.jd index 1b4909618f4d..ac8e64a72658 100644 --- a/docs/html/training/basics/firstapp/index.jd +++ b/docs/html/training/basics/firstapp/index.jd @@ -3,8 +3,9 @@ page.metaDescription=If you're new to Android app development, this where you sh trainingnavtop=true startpage=true -next.title=Creating an Android Project -next.link=creating-project.html + +page.tags=sdk tools +helpoutsWidget=true @jd:body @@ -47,6 +48,3 @@ not apply to earlier versions.</p> <p>This class uses a tutorial format that incrementally builds a small Android app that teaches you some fundamental concepts about Android development, so it's important that you follow each step.</p> - -<p><strong><a href="creating-project.html">Start the first lesson ›</a></strong></p> - diff --git a/docs/html/training/basics/firstapp/running-app.jd b/docs/html/training/basics/firstapp/running-app.jd index 23cedba1e8b9..96b71726823b 100644 --- a/docs/html/training/basics/firstapp/running-app.jd +++ b/docs/html/training/basics/firstapp/running-app.jd @@ -3,10 +3,9 @@ parent.title=Building Your First App parent.link=index.html trainingnavtop=true -previous.title=Creating a Project -previous.link=creating-project.html -next.title=Building a Simple User Interface -next.link=building-ui.html + +page.tags=emulator +helpoutsWidget=true @jd:body diff --git a/docs/html/training/basics/firstapp/starting-activity.jd b/docs/html/training/basics/firstapp/starting-activity.jd index 27d2c104ee74..f9dcba4e59b7 100644 --- a/docs/html/training/basics/firstapp/starting-activity.jd +++ b/docs/html/training/basics/firstapp/starting-activity.jd @@ -3,8 +3,9 @@ parent.title=Building Your First App parent.link=index.html trainingnavtop=true -previous.title=Building a Simpler User Interface -previous.link=building-ui.html + +page.tags=input events, intents, activity lifecycle +helpoutsWidget=true @jd:body diff --git a/docs/html/training/material/compatibility.jd b/docs/html/training/material/compatibility.jd index 5e03450a1910..49ef7f716256 100644 --- a/docs/html/training/material/compatibility.jd +++ b/docs/html/training/material/compatibility.jd @@ -131,9 +131,9 @@ href="{@docRoot}/sdk/installing/studio-build.html#dependencies">Gradle dependenc <pre> dependencies { - compile 'com.android.support:appcompat-v7:+' - compile 'com.android.support:cardview-v7:+' - compile 'com.android.support:recyclerview-v7:+' + compile 'com.android.support:appcompat-v7:21.0.+' + compile 'com.android.support:cardview-v7:21.0.+' + compile 'com.android.support:recyclerview-v7:21.0.+' } </pre> diff --git a/docs/html/training/material/drawables.jd b/docs/html/training/material/drawables.jd index 8d7f4535e4ca..fd21e3df53f1 100644 --- a/docs/html/training/material/drawables.jd +++ b/docs/html/training/material/drawables.jd @@ -73,7 +73,7 @@ app's module:</p> <pre> dependencies { ... - compile 'com.android.support:palette-v7:+' + compile 'com.android.support:palette-v7:21.0.+' } </pre> diff --git a/docs/html/training/material/index.jd b/docs/html/training/material/index.jd index 542a9410b3b2..4eb7911238e2 100644 --- a/docs/html/training/material/index.jd +++ b/docs/html/training/material/index.jd @@ -1,6 +1,6 @@ page.title=Creating Apps with Material Design page.type=design -page.image=design/material/images/MaterialLight.png +page.image=images/material.png page.metaDescription=Learn how to apply material design to your apps. diff --git a/docs/html/training/material/lists-cards.jd b/docs/html/training/material/lists-cards.jd index eb45f0d6ec56..e7bdfe0ab09a 100644 --- a/docs/html/training/material/lists-cards.jd +++ b/docs/html/training/material/lists-cards.jd @@ -260,7 +260,7 @@ app's module:</p> <pre> dependencies { ... - compile 'com.android.support:cardview-v7:+' - compile 'com.android.support:recyclerview-v7:+' + compile 'com.android.support:cardview-v7:21.0.+' + compile 'com.android.support:recyclerview-v7:21.0.+' } </pre> diff --git a/docs/html/training/search/index.jd b/docs/html/training/search/index.jd index 612e8e88aced..66874bb2732b 100644 --- a/docs/html/training/search/index.jd +++ b/docs/html/training/search/index.jd @@ -49,5 +49,5 @@ startpage=true <dt><b><a href="backward-compat.html">Remaining Backward Compatible</a></b></dt> - <dd>Learn how to keep search features backward compatible with older devices by using.</dd> + <dd>Learn how to keep search features backward compatible with older devices.</dd> </dl> diff --git a/docs/html/training/training_toc.cs b/docs/html/training/training_toc.cs index 0fee77156f5f..9f0666665c07 100644 --- a/docs/html/training/training_toc.cs +++ b/docs/html/training/training_toc.cs @@ -834,6 +834,12 @@ include the action bar on devices running Android 2.1 or higher." </li> </ul> </li> + <li> + <a href="<?cs var:toroot ?>training/articles/wear-location-detection.html" + description= + "How to detect location data on Android Wear devices." + >Detecting Location</a> + </li> </ul> </li> <!-- End Building for wearables --> diff --git a/docs/html/training/tv/games/index.jd b/docs/html/training/tv/games/index.jd index 29b055beec31..2f510a948cf6 100644 --- a/docs/html/training/tv/games/index.jd +++ b/docs/html/training/tv/games/index.jd @@ -31,7 +31,7 @@ page.article=true </p> -<h3 id="shared-display">Shared display</h3> +<h3 id="shared-display">Consider the shared display</h3> <p> A living-room TV poses design challenges for multiplayer games, in that all players can see @@ -57,7 +57,7 @@ page.article=true </ul> -<h3 id="landscape-display">Landscape display</h3> +<h3 id="landscape-display">Support landscape display</h3> <p> A TV is always sideways: You can’t turn it, and there is no portrait orientation. Always design @@ -69,19 +69,19 @@ page.article=true <p> TVs don't have touch interfaces, so it's even more important to get your controls right and make - sure that players find them intuitive and fun to use. The separation of controller from device - also introduces some other issues to pay attention to, like keeping track of multiple players' + sure players find them intuitive and fun to use. Handling controllers + also introduces some other issues to pay attention to, like keeping track of multiple controllers, and handling disconnects gracefully. </p> -<h3 id="d-pad">D-pad</h3> +<h3 id="d-pad">Support D-pad controls</h3> <p> Plan your control scheme around a directional pad (D-pad) control, since this control set is the default for Android TV devices. The player needs to be able to use a D-Pad in all aspects of the - game–not just controlling core gameplay, but also navigating menus and ads. For this reason, you - should also ensure that your Android TV game does not refer to a touch interface: For example, an - Android TV game should not tell a player to <strong>Tap here to skip</strong>. + game—not just controlling core gameplay, but also navigating menus and ads. For this reason, you + should also ensure that your Android TV game does not refer to a touch interface. For example, an + Android TV game should not tell a player to "<em>Tap</em> here to continue." </p> <p> @@ -91,35 +91,35 @@ page.article=true <ul> <li> - <strong>Communicate Controller Requirements up Front</strong> - Use your Play Store description + <strong>Communicate Controller Requirements up Front</strong>. Use your Google Play description to communicate to the player any expectations about controllers. If a game is better suited to a gamepad with a joystick than one with only a D-pad, make this fact clear. A player who uses - an ill-suited controller for a game is likely to have a subpar experience–and penalize your + an ill-suited controller for a game is likely to have a subpar experience and penalize your game in the ratings. </li> <li> - <strong>Use Consistent Button Mapping</strong> - Intuitive and flexible button mapping is key - to a good user experience. For example, you can adhere to accepted custom by using the A button - to <code>Accept</code>, and the B button to <code>Cancel</code>. You can also offer flexibility - in the form of remappability. For more information on button mapping, see <a href= + <strong>Use Consistent Button Mapping</strong>. Intuitive and flexible button mapping is key + to a good user experience. For example, you should adhere to accepted customs by using the A button + to <em>Accept</em>, and the B button to <em>Cancel</em>. You can also offer flexibility + in the form of remappability. For more information about button mapping, see <a href= "http://developer.android.com/training/game-controllers/controller-input.html">Handling Controller Actions</a>. </li> <li> - <strong>Detect Controller Capabilities and Adjust Accordingly</strong> - Query the controller + <strong>Detect Controller Capabilities and Adjust Accordingly</strong>. Query the controller about its capabilities in order to optimize the match between controller and game. For example, you may intend for a player to steer an object by waving the controller in the air. If a player's controller lacks accelerometer and gyroscope hardware, however, waving will not work. - When, however, your game queries the controller and discovers that motion detection is not - supported, it can switch over to an alternative, available control scheme. For more information - on querying controller capabilities, see <a href= + So, your game should query the controller and if motion detection is not + supported, switch over to an alternative, available control scheme. For more information + about querying controller capabilities, see <a href= "http://developer.android.com/training/game-controllers/compatibility.html">Supporting Controllers Across Android Versions</a>. </li> </ul> -<h3 id="back-button">Back-button behavior</h3> +<h3 id="back-button">Provide appropriate Back-button behavior</h3> <p> The Back button should never act as a toggle. For example, do not use it to both open and close a @@ -139,18 +139,18 @@ page.article=true </p> -<h3 id="multiple-controllers">Handling multiple controllers</h3> +<h3 id="multiple-controllers">Handle multiple controllers</h3> <p> When multiple players are playing a game, each with his or her own controller, it is important to - map each player-controller pair. For information on how to implement controller-number + map each player-controller pair. For information about how to implement controller-number identification, see <a href= "http://developer.android.com/reference/android/view/InputDevice.html#getControllerNumber">Input Devices</a>. </p> -<h3 id="handle-disconnect">Handling disconnects</h3> +<h3 id="handle-disconnect">Handle controller disconnects</h3> <p> When a controller is disconnected in the middle of gameplay, the game should pause, and a dialog @@ -159,7 +159,7 @@ page.article=true <p> The dialog should also offer troubleshooting tips (for example, a pop-up dialog telling the - player to "Check your Bluetooth connection"). For more information on implementing input-device + player to "Check your Bluetooth connection"). For more information about implementing input-device support, see <a href= "http://developer.android.com/training/game-controllers/controller-input.html">Handling Controller Actions</a>. Specific information about Bluetooth connections is at <a href= @@ -167,25 +167,53 @@ page.article=true </p> +<h3 id="ControllerHelp">Show controller instructions</h3> + +<p>If your game provides visual game control instructions, the +controller image should be free of branding and include only <a +href="{@docRoot}training/game-controllers/controller-input.html#button" +>buttons compatible with Android</a>.</p> + +<p>For sample images of an Android-compatible controller, download the +<a href="http://storage.googleapis.com/androiddevelopers/design/android_tv_gamepad_template-2014-10.zip" +>Android TV Gamepad Template (ZIP)</a>. +It includes a white controller on black background and a black controller on white background +(shown in figure 1), as a PNG file and an Adobe® Illustrator® file.</p> + +<img src="{@docRoot}images/games/game-controller-buttons_2x.png" width="700" + srcset="{@docRoot}images/games/game-controller-buttons_2x.png 2x, + {@docRoot}images/games/game-controller-buttons.png 1x" /> +<p class="img-caption"><b>Figure 1.</b> Example controller instructions using the +<a href="http://storage.googleapis.com/androiddevelopers/design/android_tv_gamepad_template-2014-10.zip" +>Android TV Gamepad Template (ZIP)</a>. + + + + <h2 id="manifest">Manifest</h2> +<p>There are a some special things games should include in the Android manifest.</p> + +<h3 id="Launcher">Show your game in the launcher</h3> <p> - The Android TV launcher home screen displays games in a separate row from regular apps. The TV - framework uses the <code>android:isGame</code> manifest attribute to differentiate games from - non-game apps. Set this value to <code>true</code> in your game's app manifest, as shown in the - following code example: + The Android TV launcher home screen displays games in a separate row from regular apps. + To make your game appear in the list of games, add the + <a href="{@docRoot}guide/topics/manifest/meta-data-element.html" + ><code><meta-data></code></a> tag in your app manifest with <code>android:name</code> + set to <code>"isGame"</code> and <code>android:value</code> + set to <code>"true"</code>. For example: </p> <pre class="fragment"> <application> ... - < meta-data android:name="isGame" android:value="true" > + <meta-data android:name="isGame" android:value="true" > ... </application> </pre> -<h3 id="gamepad">Game Controllers</h3> +<h3 id="gamepad">Declare support for game controllers</h3> <p> Games controllers may not be available or active for users of a TV device. In order to properly @@ -215,7 +243,9 @@ page.article=true <h2 id="gpgs">Google Play Game Services</h2> <p> - If your game integrates Google Play Game Services, you should keep in mind a number of + If your game integrates <a + href="https://developers.google.com/games/services/">Google Play Game services</a>, + you should keep in mind a number of considerations pertaining to achievements, sign-in, saving games, and multiplayer play. </p> @@ -224,7 +254,7 @@ page.article=true <p> Your game should include at least five (earnable) achievements. Only a user controlling gameplay - from a supported input device should be able to earn achievements. For more information on + from a supported input device should be able to earn achievements. For more information about achievements and how to implement them, see <a href= "https://developers.google.com/games/services/android/achievements">Achievements in Android</a>. </p> @@ -262,7 +292,7 @@ page.article=true <p> A game offering a multiplayer experience must allow at least two players to enter a room. For - further information on multiplayer games in Android, see the <a href= + further information about multiplayer games in Android, see the <a href= "https://developers.google.com/games/services/android/realtimeMultiplayer">Real-time Multiplayer</a> and <a href="">Turn-based Multiplayer</a> documentation on the Android developer site. diff --git a/docs/html/training/wearables/apps/index.jd b/docs/html/training/wearables/apps/index.jd index 7d961b783ad1..256205bc7a05 100644 --- a/docs/html/training/wearables/apps/index.jd +++ b/docs/html/training/wearables/apps/index.jd @@ -1,5 +1,6 @@ page.title=Creating Wearable Apps -page.image=wear/images/notifications.png +page.tags="wear","wearable","app" +page.image=wear/images/01_create.png @jd:body diff --git a/docs/html/training/wearables/notifications/index.jd b/docs/html/training/wearables/notifications/index.jd index 17f3cb3c57d4..a7b67333ff52 100644 --- a/docs/html/training/wearables/notifications/index.jd +++ b/docs/html/training/wearables/notifications/index.jd @@ -1,4 +1,6 @@ page.title=Adding Wearable Features to Notifications +page.tags="wear","notifications","wearables" +page.image=wear/images/01_notifications.png @jd:body <div id="tb-wrapper"> diff --git a/docs/html/training/wearables/notifications/stacks.jd b/docs/html/training/wearables/notifications/stacks.jd index e71e74c098e3..9a528a45962e 100644 --- a/docs/html/training/wearables/notifications/stacks.jd +++ b/docs/html/training/wearables/notifications/stacks.jd @@ -45,7 +45,7 @@ final static String GROUP_KEY_EMAILS = "group_key_emails"; Notification notif = new NotificationCompat.Builder(mContext) .setContentTitle("New mail from " + sender1) .setContentText(subject1) - .setSmallIcon(R.drawable.new_mail); + .setSmallIcon(R.drawable.new_mail) .setGroup(GROUP_KEY_EMAILS) .build(); @@ -65,7 +65,7 @@ instead of as a new card:</p> Notification notif2 = new NotificationCompat.Builder(mContext) .setContentTitle("New mail from " + sender2) .setContentText(subject2) - .setSmallIcon(R.drawable.new_mail); + .setSmallIcon(R.drawable.new_mail) .setGroup(GROUP_KEY_EMAILS) .build(); diff --git a/docs/html/training/wearables/ui/index.jd b/docs/html/training/wearables/ui/index.jd index 8ef6fe7baa17..5d9749091411 100644 --- a/docs/html/training/wearables/ui/index.jd +++ b/docs/html/training/wearables/ui/index.jd @@ -1,4 +1,5 @@ page.title=Creating Custom UIs for Wear Devices +page.image=wear/images/10_uilib.png @jd:body diff --git a/docs/html/wear/images/01_create.png b/docs/html/wear/images/01_create.png Binary files differnew file mode 100644 index 000000000000..5a39dde4d1bd --- /dev/null +++ b/docs/html/wear/images/01_create.png diff --git a/docs/html/wear/images/02_create.png b/docs/html/wear/images/02_create.png Binary files differnew file mode 100644 index 000000000000..e722df1170ce --- /dev/null +++ b/docs/html/wear/images/02_create.png diff --git a/docs/html/wear/images/10_uilib.png b/docs/html/wear/images/10_uilib.png Binary files differnew file mode 100644 index 000000000000..de7be57e6971 --- /dev/null +++ b/docs/html/wear/images/10_uilib.png diff --git a/docs/image_sources/distribute/gp-wear-quality.svg b/docs/image_sources/distribute/gp-wear-quality.svg new file mode 100644 index 000000000000..2acf81abcea9 --- /dev/null +++ b/docs/image_sources/distribute/gp-wear-quality.svg @@ -0,0 +1,2268 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + version="1.1" + width="2824.887" + height="1419.8136" + id="svg3004" + xml:space="preserve" + inkscape:version="0.48.1 " + sodipodi:docname="wear_app_quality.svg"><sodipodi:namedview + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1" + objecttolerance="10" + gridtolerance="10" + guidetolerance="10" + inkscape:pageopacity="0" + inkscape:pageshadow="2" + inkscape:window-width="1280" + inkscape:window-height="1002" + id="namedview125" + showgrid="false" + inkscape:zoom="0.23675905" + inkscape:cx="1735.4152" + inkscape:cy="-51.97425" + inkscape:window-x="1272" + inkscape:window-y="-8" + inkscape:window-maximized="1" + inkscape:current-layer="layer8" + showguides="true" + inkscape:guide-bbox="true" + fit-margin-top="50" + fit-margin-left="200" + fit-margin-right="200" + fit-margin-bottom="200"><sodipodi:guide + orientation="0,1" + position="1543.7834,1150.3523" + id="guide3963" /><sodipodi:guide + orientation="0,1" + position="1978.6428,757.82274" + id="guide9681" /></sodipodi:namedview><metadata + id="metadata3010"><rdf:RDF><cc:Work + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs + id="defs3008"><clipPath + id="clipPath3020"><path + d="m 0,1080 1920,0 L 1920,0 0,0 0,1080 z" + id="path3022" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3044"><path + d="m 391.754,758.654 452.495,0 0,-452.496 -452.495,0 0,452.496 z" + id="path3046" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3060"><path + d="m 362.683,787.727 510.637,0 0,-510.638 -510.637,0 0,510.638 z" + id="path3062" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3086"><path + d="m 1058,722 374,0 0,-374 -374,0 0,374 z" + id="path3088" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3100"><path + d="m 1029,344 432,0 0,-32 -432,0 0,32 z" + id="path3102" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3116"><path + d="m 1029,756 432,0 0,-32 -432,0 0,32 z" + id="path3118" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3060-8"><path + d="m 362.683,787.727 510.637,0 0,-510.638 -510.637,0 0,510.638 z" + id="path3062-8" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3044-8"><path + d="m 391.754,758.654 452.495,0 0,-452.496 -452.495,0 0,452.496 z" + id="path3046-8" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3116-3"><path + d="m 1029,756 432,0 0,-32 -432,0 0,32 z" + id="path3118-0" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3100-0"><path + d="m 1029,344 432,0 0,-32 -432,0 0,32 z" + id="path3102-0" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3086-0"><path + d="m 1058,722 374,0 0,-374 -374,0 0,374 z" + id="path3088-4" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3086-0-0"><path + d="m 1058,722 374,0 0,-374 -374,0 0,374 z" + id="path3088-4-2" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3100-0-7"><path + d="m 1029,344 432,0 0,-32 -432,0 0,32 z" + id="path3102-0-2" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3116-3-2"><path + d="m 1029,756 432,0 0,-32 -432,0 0,32 z" + id="path3118-0-6" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3060-8-2"><path + d="m 362.683,787.727 510.637,0 0,-510.638 -510.637,0 0,510.638 z" + id="path3062-8-4" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3044-8-3"><path + d="m 391.754,758.654 452.495,0 0,-452.496 -452.495,0 0,452.496 z" + id="path3046-8-8" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3086-4"><path + inkscape:connector-curvature="0" + d="m 1058,722 374,0 0,-374 -374,0 0,374 z" + id="path3088-8" /></clipPath><clipPath + id="clipPath3100-8"><path + inkscape:connector-curvature="0" + d="m 1029,344 432,0 0,-32 -432,0 0,32 z" + id="path3102-2" /></clipPath><clipPath + id="clipPath3116-4"><path + inkscape:connector-curvature="0" + d="m 1029,756 432,0 0,-32 -432,0 0,32 z" + id="path3118-5" /></clipPath><clipPath + id="clipPath3044-8-1"><path + inkscape:connector-curvature="0" + d="m 391.754,758.654 452.495,0 0,-452.496 -452.495,0 0,452.496 z" + id="path3046-8-5" /></clipPath><clipPath + id="clipPath3060-8-27"><path + inkscape:connector-curvature="0" + d="m 362.683,787.727 510.637,0 0,-510.638 -510.637,0 0,510.638 z" + id="path3062-8-6" /></clipPath><clipPath + id="clipPath3086-0-0-4"><path + inkscape:connector-curvature="0" + d="m 1058,722 374,0 0,-374 -374,0 0,374 z" + id="path3088-4-2-1" /></clipPath><clipPath + id="clipPath3100-0-7-1"><path + inkscape:connector-curvature="0" + d="m 1029,344 432,0 0,-32 -432,0 0,32 z" + id="path3102-0-2-5" /></clipPath><clipPath + id="clipPath3116-3-2-9"><path + inkscape:connector-curvature="0" + d="m 1029,756 432,0 0,-32 -432,0 0,32 z" + id="path3118-0-6-5" /></clipPath><clipPath + id="clipPath3044-8-3-2"><path + inkscape:connector-curvature="0" + d="m 391.754,758.654 452.495,0 0,-452.496 -452.495,0 0,452.496 z" + id="path3046-8-8-2" /></clipPath><clipPath + id="clipPath3060-8-2-1"><path + inkscape:connector-curvature="0" + d="m 362.683,787.727 510.637,0 0,-510.638 -510.637,0 0,510.638 z" + id="path3062-8-4-5" /></clipPath><clipPath + id="clipPath3942" + clipPathUnits="userSpaceOnUse"><path + id="path3944" + d="m 1337.7,554.569 67.31,0 0,-64.569 -67.31,0 0,64.569 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3912" + clipPathUnits="userSpaceOnUse"><path + id="path3914" + d="m 1404.777,549.002 12,0 0,11.998 -12,0 0,-11.998 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3908" + clipPathUnits="userSpaceOnUse"><path + id="path3910" + d="m 1404.78,561 12,0 0,-12 -12,0 0,12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3886" + clipPathUnits="userSpaceOnUse"><path + id="path3888" + d="m 1363,547.865 32,0 0,12 -32,0 0,-12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3882" + clipPathUnits="userSpaceOnUse"><path + id="path3884" + d="m 1363,559.865 32,0 0,-12.002 -32,0 0,12.002 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3852" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3854" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHEAAABECAAAAACTooUSAAAAAXNCSVQI5gpbmQAAAXhJREFUWIXt2T9v3DAMBfBHWj4Fzh2CXjsEaZd+/+8VZGiN+v4Y1cni6+ADmqUjnQ7kqEE/ULQXPgEAQLBB8S8lAnE3SZCrKFBVVd8+CTMzA5EAaOr7PrmShC211sWABNGUh8fHnNRTtKVcrzMWY4JoPxw/Hw+585sl2cp5/AkzMgm033/59nIcevUCAavz+Cq3Upvce3z5/nzY+T0r7XZ+w/zrpMJ1jvvj89enB0/x94Rpn5PK/VvNw+HpU+78xFZwGnJSAAkQ0a7f5fzgKSLv+k5FgAQAoqJd1zmK6DqVdWppPZK1vES8u93xj/hHhRhiiCGGGGKIIYYYYoghhhhiiCGGGOL/Jt73ciRJuinvr08AQKO11vzCALbWjMa7SFqrt1LgutEtt9qMXHu0pcznCc5b6/NcFgOQQFvKZXzDyXszP17KYkQCrc7jKyb/9GGcqxGJYvXyg9ctEpZLNXDtEWXaJEWqRgggWyZl/IA08EMST2DTVPcPY4fdi0eNNAgAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><mask + id="mask3840" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3842"><g + id="g3844" + clip-path="url(#clipPath3836)"><g + id="g3846"><g + id="g3848" + transform="matrix(113,0,0,68,1351,505)"><image + id="image3850" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHEAAABECAYAAAC2ydrOAAAABHNCSVQICAgIfAhkiAAAA1NJREFUeJztnc1uozAURj8HjCMCikq7iNJu+v7vVXXRovJn1RDiWUztMQnttIuQmat7pKugAFn4yDZk8V0BwGIGIcTc18wVsXZWFQROJAohvMDwmLke1lovMDx2xO7AyVqtVmcVnmeWw8k6Ho9nFZ6Pw5tWqxXiOIaU0lccxyzyCoQCD4cDhmHwdTgcvEjgQ6IQwgtUSiFNU2w2G2w2GyilvEiWuBzWWi/QGIOu69B1HbTWAOBFWmunEqWUSNMURVHg9vYWRVEgz3MopRBFEe+RC+H2vXEcYYxB0zQoyxKvr68A/iyv7ro43AullMiyDHd3d3h4eMB+v0dRFEjTFFJKv6wyl+d4PGIYBmitUZYlnp6eIIRA3/cwxmAYBozjCCHE5zNxv9/j8fERu90OeZ4jSRJeUhfCLaV936NpGjw/PwMAtNZ4e3tDXdfexdly6vbELMtQFAV2ux3u7++x3W6xXq9Z4kI4ie/v76iqCgBQVRWyLJt9Rpl9OnUPN3meY7vd4ubmZrIvMpcl3A8BoK5rpGk6ERgyeU90MzKKIkgpkSQJlFJQSmG9XrPEhXASAUAphSRJIKVEFEV+BoYe4tMfcCJDoWGxxMvj3hHdmIc+5sb/TKLD2Z4r5vL8ZNz5nYEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEAn2a7uWji02Iuz0/H/kyiC0x1n+M4+gI4kX8JXFSmq9DHnMw4vDEUNwyDz5t24akclbkMYWitMQZ93/vM7zDA3TGZiWGEv9YaTdP4+GKOj16O0/jopmmgtYYx5qwnBvAh8bQHQ9u2KMvSB4jXdc1B7gsyF+ReliXatp2InHSocTedRvgDvwPEuaXC8sz5KMsSWmsMwzCVaK2FEMLf1LYtXl5eYK1F13Xc3OQKfNXcpG1bL9FdOzsTAcAYg6qquM3QlfiqzdDpTPSt98LeGNzw6/p8p+HXrESAW+/9S3y39R43wfwP+FsTzDOJ/gTL++f47K+3XyWNnXDxB1SBAAAAAElFTkSuQmCC" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3836" + clipPathUnits="userSpaceOnUse"><path + id="path3838" + d="m 1351,573 113,0 0,-68 -113,0 0,68 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3832" + clipPathUnits="userSpaceOnUse"><path + id="path3834" + d="m 1351,573 113,0 0,-68 -113,0 0,68 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3824" + clipPathUnits="userSpaceOnUse"><path + id="path3826" + d="m 0,1080 1920,0 L 1920,0 0,0 0,1080 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3798" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3800" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHEAAABECAAAAACTooUSAAAAAXNCSVQI5gpbmQAAAZ9JREFUWIXt2U9v1DAQBfA348lmyXa1FdBSgRDf/4tVe4CI7J+oXtvzOKQIOCOnF8/Ft/lpZCeHeQIAgGCF4h9KBFLdJEEuokBVVevOSbi7OwiDiIZN14WqJOE5pZQdMEBtO+yGPmhN0XO8Xmdkp4mEfv/+w/2u13p3SZZ4Hn/AnTRo2B6evjwd3lnFGT3N47PcYipiIrY9PH77+nHotBpIv52PmH+eVGiQsBnuHz5/2m1qii8TprveVJa3av2wP9xt6j0dlojT0JsCMJAk1LptVRH9pgsqAhjoJedC0YqfBxGCytLfCJZcsgM1/3Qi8ru7gnQv7mQ17t9SgEutBEIBYEXvVVy1mtjEJjaxiU1sYhOb2MQmNrGJTWxiE5v4P2XLUXlt9Xd7AwA6vZRSLwxgKcXpfBVJL+kWI0LNjW68peLkMqPnOJ8nbCvuV/1lOs8xO5aNbo6X8YhTzR2y387H8RKzEwZ6msdnTDWzgCV9GOfkhFE8Xb7zuu9D9YTlkhxcZkScelshRUpOCCBqXdfZOkkZ3yANfJPEE1g11f0FocoCRBRb0tkAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><mask + id="mask3786" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3788"><g + id="g3790" + clip-path="url(#clipPath3782)"><g + id="g3792"><g + id="g3794" + transform="matrix(113,0,0,68,1351,444)"><image + id="image3796" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHEAAABECAYAAAC2ydrOAAAABHNCSVQICAgIfAhkiAAAA59JREFUeJztnclurDoURTdgmkAhSmlLiaL8/49FGSQodFZM5zd4sstUkdsMQnKPzpKsQgVMWDo2ZrCPB0BjBc/z1v5mvhGtV1XBw4lEz/OsQPeY+T601lage2wQ5sDI8n3/bLjnme0wsuZ5PhvueQEcK873fQRBgCiKEIYhwjBEEAQs8htwBY7jiGEY7BjH0YoEnEr0fR9CCCRJgjRNkWUZ0jRFHMdWJEvcDq21FaiUQtd16LoOUkoAsCK11hCmCoMgQBzHyPMcl5eXuLq6wn6/R5ZliOPYSmSRX49Z96ZpglIKTdOgLEu8vb0BOE6v5joBwE6jSZKgKAocDgc8PDzgcDigKApcXFxACMECN2SeZwzDACklyrLE8/MzPM9D3/dQSmEYBkzTBM/zjpVoptKiKHB7e4unpyc8Pj7i+voaaZoiDEO7NjJfi5lK+75H0zR4eXkBAEgp8f7+jrqu7cxoK9FMp1EUIU1T7Pd73Nzc4P7+Hnd3d8iyDFEUscSNMBI/Pj5QVRUAoKoq7HY7xHEMIcTiHeXs7VQIgTiOkaYp8jxHURTY7XZWIk+pX4+7HgJAXdf2JdMIdBHmJncAx7fVMAyRJAlL3BAjEQDiOLZbPneX4HqwEud5xjRNGMcR4zhimiZorRf7R5a4DaaQgiBYPPfPnr9wP+cYiebX3VAC/BluS8yzdsdn+MBxOjX7j2mazvYizM/FrpCn6+LpGsn8XM72DCzv34M3fgRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQQQn53gdKnv42+f/ZlEk/HmJi+aAXAi/xaYsEQzXB9rMoV7oytuGAabN23CU4MgYIkb4IbWKqXQ973N/F4LTVxUohvhL6VE0zQ2vjhJEs473YjT+OimaSClhFJqNcJ0EVprBLZti7IsbYB4XdecPLwha0HuZVmibduFyEWHGnPTaYQ/8H+AOKfxb8+aj7IsIaXEMAxLiSYi2tzUti1eX1+htUbXdcjz3Hap4eThbfhVc5O2ba1Ec+1qJQKAUgpVVa1G+DNfz6/aDJ1Wom2957ZUMM2+wjBcRPizxO34k4ZfqxIBbr33k/jT1nvcBPMf4HdNMM8k2hMs78fx2ae3/wBR6gt9OOvm0AAAAABJRU5ErkJggg==" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3782" + clipPathUnits="userSpaceOnUse"><path + id="path3784" + d="m 1351,512 113,0 0,-68 -113,0 0,68 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3778" + clipPathUnits="userSpaceOnUse"><path + id="path3780" + d="m 1351,512 113,0 0,-68 -113,0 0,68 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3770" + clipPathUnits="userSpaceOnUse"><path + id="path3772" + d="m 1341,490 129,0 0,89 -129,0 0,-89 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3748" + clipPathUnits="userSpaceOnUse"><path + id="path3750" + d="m 1214,628 270,0 0,-182 -270,0 0,182 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3726" + clipPathUnits="userSpaceOnUse"><path + id="path3728" + d="m 652.002,520.002 12,0 0,11.998 -12,0 0,-11.998 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3722" + clipPathUnits="userSpaceOnUse"><path + id="path3724" + d="m 652,532 12.002,0 0,-12 -12.002,0 0,12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3700" + clipPathUnits="userSpaceOnUse"><path + id="path3702" + d="m 592,518.865 32,0 0,12 -32,0 0,-12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3696" + clipPathUnits="userSpaceOnUse"><path + id="path3698" + d="m 592,530.865 32,0 0,-12.002 -32,0 0,12.002 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3688" + clipPathUnits="userSpaceOnUse"><path + id="path3690" + d="m 0,1080 1920,0 L 1920,0 0,0 0,1080 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3662" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3664" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAABPCAAAAAAc13L4AAAAAXNCSVQI5gpbmQAAAdJJREFUaIHt2rFu2zAUheFDirICJUZQt0OQdun7v1fgwRHqylJMkbyng1S0He5aarj/C/gDLWnhcQAAONSNfxTOwdXkkCBXjIP33vtqp0OIiAiIAMCHtm1DLQ0hJaWlCBjgfOj6x8cu+EoYKXGe5nsuCHC+7U+fT8euqfLckBKnH+8DKQgOvn368u311Le+ggVg/rie27KkUraTef3+cjzU+Z8kzZcu3caP5NZn5un08vX5oRJmmQ73S39o3PY2df3x+VPXVHlmZAlz3wXvHALgnG/aQ9c9VML4GDxIrt8ZOO980zR1MM47lpyLbBjArVXAAIDkkgvBOq/zP5EiRYTEDjDgGnaBAUgCe8FsGUbLMFqG0TKMlmG0DKNlGC3DaBlGyzBahtEyjJZhtAyjZRgtw2gZRsswWobRMoyWYbQMo2UYLcNoGUZru0r+fWX5//v7lwMAUCillCprHpZShMINQ0pJS4yoc+NfYlxSEXI9GclxHq+osxKh3K/jHLMACKDkeBvO+FlnP0NZxvNwi1mIAEqahzdcay2LJM3D2zAnIQKdpNuFU73NVYnj8H5LAq4ng3ituEbLcZrmJIQDXPWdXk4p5Q2zmwXj3radwF5Wr78ATrQFVxEFtwQAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><mask + id="mask3650" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3652"><g + id="g3654" + clip-path="url(#clipPath3646)"><g + id="g3656"><g + id="g3658" + transform="matrix(139.35082,0,0,78.633677,558.31445,465.31115)"><image + id="image3660" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAABPCAYAAAA5vC0kAAAABHNCSVQICAgIfAhkiAAABCJJREFUeJzt3UFvskwYheEDAmNQYkq7MLab/v//1bhQUgqMwjDMt3gzBJTmy7Ol50omNSLdcAcfcEEAwGFBEARLb9Mf4dxiFgjwEEwQBGMs09f0Nzjnxlimr73Iv/BhhGH4tKbbaZ18GMMwPK3p9mi6UxiGiKIIcRyPK4oiRrNy01istTDGwBiDrutgrZ1FEwH/QvCxKKWQpil2ux12ux2UUmM0DGadnHNjLG3bQmuNpmmgtcb9fkff97DWAsA8mDiOkaYp8jzH6+sr8jxHlmVQSmGz2XCmWSE/pwzDgLZt0TQNvr+/cb1eURTFbDsARNPZJY5j7Pd7vL294ePjA6fTCXmeI01TxHE8fjXRujjn0Pc9brcbyrLE+XxGHMew1qLrOhhjYK2Ftfb3M8zpdMLn5yeOxyOyLEOSJPxaWqlhGGCMgdYal8sFSikYY1DXNaqqwu12gzEGQRAszzD7/R55nuN4POL9/R2HwwHb7ZbBrNQwDOi6Dk3TIEkS3O93XC4XpGmKJEnGcQT45SrJD75ZluFwOODl5WU2x9B6+Pmk6zpEUQStNdI0fbrYeQrGvxmGITabDeI4RpIkUEpBKYXtdstgVsgHE4Yh2rad3UbxA+/0Bl70+A98NNN4povBrItzbnbMnXOw1qLv+/FyehiG34Px/BlnadF6DcMwhuL/Tn8q4HUyAZjfj/E38fzr6VcSg6HR48zyOL8ADIYWLIXiMRgSYTAkwmBIhMGQCIMhEQZDIgyGRBgMiTAYEmEwJMJgSITBkAiDIREGQyIMhkQYDIkwGBJhMCTCYEiEwZAIgyERBkMiDIZEGAyJMBgSYTAkwmBIhMGQCIMhEQZDIgyGRBgMiTAYEmEwJMJgSITBkAiDIREGQyIMhkQYDIkwGBJhMCTCYEiEwZAIgyERBkMiDIZEGAyJMBgSYTAkwmBI5NfHEP/fwyJpHaTH+SkY/yha/9daOy4AfG71yvgHm/s1PfZL4UTTHaeRGGPQdR3atkXbtgCAzWbDYFbGB+OPc9d1MMbM4pmGMzvD+Keit20LrTWqqkJZlgCA7XaLMAwZzMr4k8T9fkdZlqiqClprtG2Lvu8xDMPs89F0Jx9LXdcoigLn8xkA8PPzgyRJGMwK+WPfdR2qqsL5fEZRFKjrehaNP8vMgjHGQGuNoijw9fUFACjLEmmaIo5jhCEvqtZo6dgXRQGtNYwx82CccwiCYNyprmtcLhc459A0DbIsg1JqnF94hlkXP6P4OaaqKhRFgev1irqux2D8ZxfPMADQti3KsoRSClEU8etoxR5HkqZp0DTN4hkmAOCAf5fLYRgiiiLEcTwuH4v/DK2Pj8FHY4wZ1+MMMwsGAMIwfFrT7bRO02ge13T7GIw3nVM4s/w90/suS3d9n4IZNzCUP+23nwf+AzNnFIrywW/wAAAAAElFTkSuQmCC" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3646" + clipPathUnits="userSpaceOnUse"><path + id="path3648" + d="m 558.314,543.945 139.351,0 0,-78.634 -139.351,0 0,78.634 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3642" + clipPathUnits="userSpaceOnUse"><path + id="path3644" + d="m 558.314,543.945 139.351,0 0,-78.633 -139.351,0 0,78.633 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3634" + clipPathUnits="userSpaceOnUse"><path + id="path3636" + d="m 570.26,532 c 0,-30.785 24.955,-55.742 55.74,-55.742 l 0,0 c 30.784,0 55.74,24.957 55.74,55.742 l 0,0 c 0,30.784 -24.956,55.74 -55.74,55.74 l 0,0 c -30.785,0 -55.74,-24.956 -55.74,-55.74" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3610" + clipPathUnits="userSpaceOnUse"><path + id="path3612" + d="m 652.333,574.333 101,0 0,-79.333 -101,0 0,79.333 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3592" + clipPathUnits="userSpaceOnUse"><path + id="path3594" + d="m 730.778,549 12,0 0,-12 -12,0 0,12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3570" + clipPathUnits="userSpaceOnUse"><path + id="path3572" + d="m 679,535.865 32,0 0,12 -32,0 0,-12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3566" + clipPathUnits="userSpaceOnUse"><path + id="path3568" + d="m 679,547.865 32,0 0,-12.002 -32,0 0,12.002 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3540" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3542" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAAAAADGw2ZMAAAAAXNCSVQI5gpbmQAAAZJJREFUWIXt2DFv2zAQhuHvTlTkyDaMuBmCtEv//+9q0KKuAtWWZJnkfR0UAwY69jyVXAhoeEQcyOUVAAAEvos3rAjE0ydBfugCVVV1Oz9hZmYgEABoqOs6ePGE5Rgv2UAEiIamXa+boE665Xkch3PKQIBo3e4/7bdN5TJ70i7De6ckjUGg9eb5y+u+rdUBB5jO/Y/G4s3ZX7++bB98RmNp6lpOwzkal7lv9i+fdysvfVzb8XCoVWS5M0273T01lYvOtMJxt2kqBQIgolX90DQrLx1T+9jUlQgCAIiKVlXlpKOqQwgqsrwmALIsDx2iqioqAHxu4V8/+DjoffTrKnrRi170ohe96EUvetGLXvSiF/3/0bkkvWsnIHn98u+ymRmNV51Gyzn7RD2mHFNKxqUYkpbjZZ7h1WfGaZzmmEkEAJbm8djDr1z96vrTnA0IoKX51H3Hb8fq9u1nP0UjA2hx7N7QuxbDt26IRgSKxdOBg3PtfJ8Sl8nEEXPvXWrnbIQAcqfKTN65kN+97t9sfv6y/QG64fFP78GtbgAAAABJRU5ErkJggg==" + height="1" + width="1" /></mask><mask + id="mask3528" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3530"><g + id="g3532" + clip-path="url(#clipPath3524)"><g + id="g3534"><g + id="g3536" + transform="matrix(93,0,0,68,667,493)"><image + id="image3538" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAYAAADjqDmQAAAABHNCSVQICAgIfAhkiAAAA51JREFUeJztnEtv4koQRo/BpokBoThZIJJN/v/vCkoUYuSAbYwfPYu57duOzWPm3lEvpo5UwqLbXhyXihaLzwM0A3ieN/S1cCNaD2oFwOObdM/zWuH2tXAbWutWuH1t45sLI3c0GvXKXheGMXKbpumVvQ6WdPgp3Pd9giBoy/d9EX8FW3hd15RlSVmWnE4n6rruiffhp0wjXClFGIbMZjNmsxlKqVa8SB9Ga90KL4qCLMvIsow0TTkej1RVRV3X7f6O9CAICMOQKIp4eHggiiIWiwVKKcbjscz4AczcbpqG0+lEmqbsdjviOGY0GrXrZo/WGt+e5UEQMJ/PeXx85Pn5mfV6TRRFhGFIEATtmBG6aK2pqorj8UiSJLy/v6OUomkayrK8vdPX6zUvLy+sVisWiwWTyURGzBmapqGqKvI8J45jwjBEa02e5+2IKcvy306H/kyfz+dEUcRqteLp6Ynlcsl0OhXpZzDSsyxjNpvRNA37/Z7tdst2u22nhBnPg6cX82O6WCxYLpfc39935rrQxYyX6XQKwH6/Z7lcMp/PW2/2aO6c003Hj8djgiBgMpmglEIpxXQ6FelnMNIB8jwnDEPu7u5QShEEQe8Q4n9/gBFvvwC7RHofc/42zer7flv2WDH0pBvMxqES+pgmtctuYBs5A/4BrjWoSHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASP8D2GlGQ5zNBrBvvPaQvx07LsouO0LKpifd3mjCwEyBJNYNYaJHTFJdVVVtGZeDEYH22zI3n04niqKgKAoAiR45g5GeZRl5nrefRVFQliV1XXfEdzrdxCKZmLv9fk+SJAASJ3UBO07q8/OTOI5JkoTD4UBRFJ1sRvhHuulwI/xwOBDHMW9vbwB8fX1JcNoFvgenvb6+8vHxQZIk5HneCU1rg9OM9LIsybKMOI7ZbDYAJEkiEYFXGIoI3Gw2xHFMmqYd6QC+1hrP81rph8OB7XaL1po0TSUM8wqXwjB3ux15nlNVVf+H9HunAxRFQZIkEvt6A5diX+2ZbsS3Ud52NqMEHP8atwQc26eXjnSQKO/f5VeivCW0/n/mltD6nvR2QWT/Jy79ZfIDbR7YvKqk0OoAAAAASUVORK5CYII=" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3524" + clipPathUnits="userSpaceOnUse"><path + id="path3526" + d="m 667,561 93,0 0,-68 -93,0 0,68 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3520" + clipPathUnits="userSpaceOnUse"><path + id="path3522" + d="m 667,561 93,0 0,-68 -93,0 0,68 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3498" + clipPathUnits="userSpaceOnUse"><path + id="path3500" + d="m 560,628 270,0 0,-182 -270,0 0,182 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3490" + clipPathUnits="userSpaceOnUse"><path + id="path3492" + d="m 0,1080 1920,0 L 1920,0 0,0 0,1080 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3476" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3478" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABHcAAAK/CAAAAADGr34kAAAAAXNCSVQI5gpbmQAACLFJREFUeJzt1DEBACAMwDDAv+fhohwkCnp1zwJIndcBwHd8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4DaBSkuBn0AocgUAAAAAElFTkSuQmCC" + height="1" + width="1" /></mask><clipPath + id="clipPath3470" + clipPathUnits="userSpaceOnUse"><path + id="path3472" + d="m 538,215 954,0 0,118 -954,0 0,-118 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3460" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3462" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABHcAAAK/CAAAAADGr34kAAAAAXNCSVQI5gpbmQAACLFJREFUeJzt1DEBACAMwDDAv+fhohwkCnp1zwJIndcBwHd8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4DaBSkuBn0AocgUAAAAAElFTkSuQmCC" + height="1" + width="1" /></mask><clipPath + id="clipPath3454" + clipPathUnits="userSpaceOnUse"><path + id="path3456" + d="m 554,720 958,0 0,204 -958,0 0,-204 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3432" + clipPathUnits="userSpaceOnUse"><path + id="path3434" + d="m 904,587 32,0 0,12 -32,0 0,-12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3428" + clipPathUnits="userSpaceOnUse"><path + id="path3430" + d="m 904,599 32,0 0,-12.002 -32,0 0,12.002 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3420" + clipPathUnits="userSpaceOnUse"><path + id="path3422" + d="m 0,1080 1920,0 L 1920,0 0,0 0,1080 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3396" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3398" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFwAAACdCAAAAAAcMECVAAAAAXNCSVQI5gpbmQAAAZdJREFUaIHt27tu20AQheEzy6Vo0BKMKCkMJ03e/70MFzYR3YisljsnBQXETZpg1J0pt/gwGGz7GwAAhtjhX9UMFsmTIFfckFJKKWx7wt3dQWQAKfd9n6N0wpda6+JAhqU8jI+PQ05BuC/lcpmxODMs9eP+6343dCF3J1s5TR9wJ7Mh9dtvP172Y58CbMDrPL3atdRmt81ffj7vNiF3oV9Pb5h/HZNxvfl2//z96SEI/33AYTvkZLffMoy7py9DF4K3guM45AQgA2ap6zfD8BCEY9j0XTIDMgBYstR1XQyOrku2XjivT7ZOAI5PUMz3+8cIFy5cuHDhwoULFy5cuHDhwoULFy5cuHDhwoULFy5cuHDhwoULFy5cuHDhwoULFy5cuHDhwv97bkEBSZIR4GcpAwCd3loLaX7YWnM6bzjprV5LQVQhUq61Oblu7kuZTwfEtS2nuSwOIIO+lPP0hmNglTOdy+JEBr3O0ysOoT3RNFcnMs3r+Z2X4BLqXB1cN0c5RDdc1QkD7E71Ge/bzd27+APu1Sr+ATqP3j0zgxPtAAAAAElFTkSuQmCC" + height="1" + width="1" /></mask><mask + id="mask3384" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3386"><g + id="g3388" + clip-path="url(#clipPath3380)"><g + id="g3390"><g + id="g3392" + transform="matrix(92,0,0,157,888,469)"><image + id="image3394" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFwAAACdCAYAAAA5Wx9JAAAABHNCSVQICAgIfAhkiAAABIZJREFUeJzt111rs0gYxvHL92AipbYHIe1Jv//3CjlopMYXMmqcPdgdH03s7lOWvWDh+sPQUDWUX4c7Ew+AxUqe5639Wv1m1q6ywsMduOd5E/b8tfq9rLUT9vy1K3QvHKzv+w9rfl2t52DHcXxY8+vh/CHf9xGGIaIomlYYhkL/h+bYwzCg7/tpDcMwoQN/gXueN2EnSYI0TbHdbrHdbpEkyYQu8PWstRO2MQZN06BpGrRtCwATurV2CR5FEdI0RZ7neHl5QZ7nyLIMSZIgCALN9JXcnL7dbjDGoKoqFEWB8/kM4NeIcfeF89kdRRF2ux1eX1/x/v6Ow+GAPM+RpimiKJpGi1o2jiP6vkfbtiiKAsfjEZ7noes6GGPQ9z1utxs8z/t+hx8OB3x8fGC/3yPLMsRxrLGykhsnXdehqiqcTicAQNu2+Pr6wuVymdweRoqb4bvdDnmeY7/f4+3tDU9PT9hsNgJfyYFfr1eUZQkAKMsSu91u9fNv9ZTiPjizLMPT0xOen58Xc1z9aj6/AeByuSBN0wX2vMU53O30IAgQRRHiOEaSJEiSBJvNRuArOXAASJIEcRwjiiIEQTDt7LlZeP8GDn2OP18CX+bO4M5nbrdm9QDucv+ZtaWW/cRI5zxyAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInF353wVq7utSynzo9gFtrMY7j9PN2u00LADzP++/++v9h1tqF0dxuDT6cPzhH7vseXdfBGANjDAAgCAKB3+XAnVPXdej7foE/h1/s8HEcMQwDjDFo2xZVVaEsSwDAZrOB7/sCv8tt0uv1irIsUVUV2raFMQbDMGAcx8X94fwhh13XNYqiwOl0AgBcLhfEcSzwlZxd13Woqgqn0wlFUaCu6wW62+UL8L7v0bYtiqLA8XgEAJRliTRNEUURfF+HmrXW7IqiQNu26Pt+CW6thed500N1XePz8xPWWjRNgyzLkCTJNL+1w5e5Ge3meFVVKIoC5/MZdV1P4O7e1R0OAMYYlGWJJEkQhqHGyd90P5KbpkHTNKs73ANggT+Pe77vIwxDRFE0LYft7lGPOUyH3vf9tO5n+AIcAHzff1jz62q9Ofr9ml+fwF3zOa2Z/fPm5+61b50P4NMFQf+rvvt6/we8Kp4iURf8WgAAAABJRU5ErkJggg==" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3380" + clipPathUnits="userSpaceOnUse"><path + id="path3382" + d="m 888,626 92,0 0,-157 -92,0 0,157 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3376" + clipPathUnits="userSpaceOnUse"><path + id="path3378" + d="m 888,626 92,0 0,-157 -92,0 0,157 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3354" + clipPathUnits="userSpaceOnUse"><path + id="path3356" + d="m 1116,527 26.006,0 0,3 -26.006,0 0,-3 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3350" + clipPathUnits="userSpaceOnUse"><path + id="path3352" + d="m 1116,530 26.01,0 0,-3 -26.01,0 0,3 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3328" + clipPathUnits="userSpaceOnUse"><path + id="path3330" + d="m 1057.994,527 11.006,0 0,3 -11.006,0 0,-3 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3324" + clipPathUnits="userSpaceOnUse"><path + id="path3326" + d="m 1057.99,530 26,0 0,-3 -26,0 0,3 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3302" + clipPathUnits="userSpaceOnUse"><path + id="path3304" + d="m 1000,527 26.006,0 0,3 -26.006,0 0,-3 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3298" + clipPathUnits="userSpaceOnUse"><path + id="path3300" + d="m 1000,530 26.01,0 0,-3 -26.01,0 0,3 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3272" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3274" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABUCAAAAAD/xdukAAAAAXNCSVQI5gpbmQAAAZZJREFUWIXt2L1u3DAQBOBZijoZsg9GLikMO03e/72MK85CLvrxUeTuuJCCJB0lA6m4tT4tl6x2BAAAwdbiHycC2fYDEuTCBc455zacgDAzMxAegPN1Xft8T5jGOKuBHuJ8097fN95lc9MwjdMtKTzE1e3p6+nYVJnzkxbGn28dafACVz98+/58amuX2z29X8+1zlF17f784+l4yD29xenSxKF/j7LM/nB6enm8y+bzeLhd2kMl68037fHxS1Nlzm6zn9rGOxF4QMRV9aFp7rK5C96B5PLuECeuqqpcLk6oKamtHJClsjgAWNKkBHMf69/+NFMzErs4uBR2coAksJ+vVXjhhRdeeOGFF1544YUXXvh/5usO+3srzKm/v/UAQKOpamZ0QlU1GldOmsY5BOQu4BrCHNXIpbulMPVX5IYPtNu1n0IyAB60FIbujF+50Qdt7s/dEJIRHrQ4da+45gcvFqfutZuiEZ5icbhw3BL7aOi7tyEauHRHuG4KnVIYxykaIYDsiLxSjDGt/BOB2+fjPmB/2PgBJp8FYb3sImYAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><mask + id="mask3260" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3262"><g + id="g3264" + clip-path="url(#clipPath3256)"><g + id="g3266"><g + id="g3268" + transform="matrix(62,0,0,84,1107,495)"><image + id="image3270" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABUCAYAAADaroR4AAAABHNCSVQICAgIfAhkiAAAA1pJREFUeJztnMtuqzoYRheES0QSRaUdRGknff/3qjJIUCmXYIzhDI6MTC5765wR1F6SFQvHESvmByb+PGDgAZ7nPTq8OIbhoR4eN+Ke543SZn9pDMMwSpt9TaA7WtD3/btmjs8dLdj3/V0zxwNzku/7BEFAGIZjC4JgMfKmtFIKKSVSStq2RSk1kQ/gXyEtHccxSZKw2WzYbDbEcTzKL0FcSwshqOuaqqqo65qmaei6DqUUwFQ8DEOSJCFNU15fX0nTlN1uRxzHrFarWde8ruO+7xFCUFUV39/fXC4XsiybjAMEZm2HYch2u+Xt7Y2Pjw+OxyNpmpIkCWEYjpf8XBmGga7ruF6v5HnO6XQiDEOUUrRti5QSpRRKqecrfjwe+fz85HA4sNvtiKJo9pd73/dIKanrmvP5TBzHSCkpy5KiKLher0gp8TzvcY1vt1vSNOVwOPD+/s5+v2e9Xi9CvG1bqqoiiiKapuF8PpMkCVEUjeUKT+7q+ga32+3Y7/e8vLxM6nyO6Ppt25YgCKjrmiRJ7m7Od+L6oO/7rFYrwjAkiiLiOCaOY9br9SLEfd9HCDF5DOsbm/kiE9z+gJY3/wSzzVncPPdhGFBK0XXd+Bjr+/65uEZfAY/aEuj7fhTWn+Yr7LyfT/8D83mtX2Z037zUf5043Nf0bX3DLxXXPBLW/GrxP+HEbcOJ24YTtw0nbhtO3DacuG04cdtw4rbhxG3DiduGE7cNJ24bTtw2nLhtOHHbcOK24cRtw4nbhhO3DSduG07cNpy4bThx23DituHEbcOJ24YTtw1rxZ/uLf3bTr258V/P905c78s0gyZ0g/kmg+jdw7qZDo/+gMCcaMrqGBEhBEIIgNlvo9ZpIEKISSbE7YZauFlxvfVYR4kURUGe5wCzj0rQi9Y0DXmeUxQFdV0jhKDrujENRBOYk7R0WZZkWcbpdALg5+dn9uEYZlRCURScTieyLKMsy4n8ZOO8nqQTNbIs4+vrC4A8zxcTh/LIIcsy6rpGSjkV1xEDelJZlpzPZ4ZhoKqqxQXg6DovioIsy7hcLpRlOYrr7z5ccQAhBHmeLzLySJdsVVVj5NHtio+xZmYWzG8Iueq6bgy5klLe1fhEHOyJNbM2yO5OfBxYqPAtz15b/wHsvBSUT5t0gwAAAABJRU5ErkJggg==" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3256" + clipPathUnits="userSpaceOnUse"><path + id="path3258" + d="m 1107,579 62,0 0,-84 -62,0 0,84 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3252" + clipPathUnits="userSpaceOnUse"><path + id="path3254" + d="m 1107,579 62,0 0,-84 -62,0 0,84 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3226" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3228" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABUCAAAAAD/xdukAAAAAXNCSVQI5gpbmQAAAZZJREFUWIXt2L1u3DAQBOBZijoZsg9GLikMO03e/72MK85CLvrxUeTuuJCCJB0lA6m4tT4tl6x2BAAAwdbiHycC2fYDEuTCBc455zacgDAzMxAegPN1Xft8T5jGOKuBHuJ8097fN95lc9MwjdMtKTzE1e3p6+nYVJnzkxbGn28dafACVz98+/58amuX2z29X8+1zlF17f784+l4yD29xenSxKF/j7LM/nB6enm8y+bzeLhd2kMl68037fHxS1Nlzm6zn9rGOxF4QMRV9aFp7rK5C96B5PLuECeuqqpcLk6oKamtHJClsjgAWNKkBHMf69/+NFMzErs4uBR2coAksJ+vVXjhhRdeeOGFF1544YUXXvh/5usO+3srzKm/v/UAQKOpamZ0QlU1GldOmsY5BOQu4BrCHNXIpbulMPVX5IYPtNu1n0IyAB60FIbujF+50Qdt7s/dEJIRHrQ4da+45gcvFqfutZuiEZ5icbhw3BL7aOi7tyEauHRHuG4KnVIYxykaIYDsiLxSjDGt/BOB2+fjPmB/2PgBJp8FYb3sImYAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><mask + id="mask3214" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3216"><g + id="g3218" + clip-path="url(#clipPath3210)"><g + id="g3220"><g + id="g3222" + transform="matrix(62,0,0,84,1049,495)"><image + id="image3224" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABUCAYAAADaroR4AAAABHNCSVQICAgIfAhkiAAAA1pJREFUeJztnMtuqzoYRheES0QSRaUdRGknff/3qjJIUCmXYIzhDI6MTC5765wR1F6SFQvHESvmByb+PGDgAZ7nPTq8OIbhoR4eN+Ke543SZn9pDMMwSpt9TaA7WtD3/btmjs8dLdj3/V0zxwNzku/7BEFAGIZjC4JgMfKmtFIKKSVSStq2RSk1kQ/gXyEtHccxSZKw2WzYbDbEcTzKL0FcSwshqOuaqqqo65qmaei6DqUUwFQ8DEOSJCFNU15fX0nTlN1uRxzHrFarWde8ruO+7xFCUFUV39/fXC4XsiybjAMEZm2HYch2u+Xt7Y2Pjw+OxyNpmpIkCWEYjpf8XBmGga7ruF6v5HnO6XQiDEOUUrRti5QSpRRKqecrfjwe+fz85HA4sNvtiKJo9pd73/dIKanrmvP5TBzHSCkpy5KiKLher0gp8TzvcY1vt1vSNOVwOPD+/s5+v2e9Xi9CvG1bqqoiiiKapuF8PpMkCVEUjeUKT+7q+ga32+3Y7/e8vLxM6nyO6Ppt25YgCKjrmiRJ7m7Od+L6oO/7rFYrwjAkiiLiOCaOY9br9SLEfd9HCDF5DOsbm/kiE9z+gJY3/wSzzVncPPdhGFBK0XXd+Bjr+/65uEZfAY/aEuj7fhTWn+Yr7LyfT/8D83mtX2Z037zUf5043Nf0bX3DLxXXPBLW/GrxP+HEbcOJ24YTtw0nbhtO3DacuG04cdtw4rbhxG3DiduGE7cNJ24bTtw2nLhtOHHbcOK24cRtw4nbhhO3DSduG07cNpy4bThx23DituHEbcOJ24YTtw1rxZ/uLf3bTr258V/P905c78s0gyZ0g/kmg+jdw7qZDo/+gMCcaMrqGBEhBEIIgNlvo9ZpIEKISSbE7YZauFlxvfVYR4kURUGe5wCzj0rQi9Y0DXmeUxQFdV0jhKDrujENRBOYk7R0WZZkWcbpdALg5+dn9uEYZlRCURScTieyLKMsy4n8ZOO8nqQTNbIs4+vrC4A8zxcTh/LIIcsy6rpGSjkV1xEDelJZlpzPZ4ZhoKqqxQXg6DovioIsy7hcLpRlOYrr7z5ccQAhBHmeLzLySJdsVVVj5NHtio+xZmYWzG8Iueq6bgy5klLe1fhEHOyJNbM2yO5OfBxYqPAtz15b/wHsvBSUT5t0gwAAAABJRU5ErkJggg==" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3210" + clipPathUnits="userSpaceOnUse"><path + id="path3212" + d="m 1049,579 62,0 0,-84 -62,0 0,84 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3206" + clipPathUnits="userSpaceOnUse"><path + id="path3208" + d="m 1049,579 62,0 0,-84 -62,0 0,84 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3180" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3182" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABUCAAAAAD/xdukAAAAAXNCSVQI5gpbmQAAAZZJREFUWIXt2L1u3DAQBOBZijoZsg9GLikMO03e/72MK85CLvrxUeTuuJCCJB0lA6m4tT4tl6x2BAAAwdbiHycC2fYDEuTCBc455zacgDAzMxAegPN1Xft8T5jGOKuBHuJ8097fN95lc9MwjdMtKTzE1e3p6+nYVJnzkxbGn28dafACVz98+/58amuX2z29X8+1zlF17f784+l4yD29xenSxKF/j7LM/nB6enm8y+bzeLhd2kMl68037fHxS1Nlzm6zn9rGOxF4QMRV9aFp7rK5C96B5PLuECeuqqpcLk6oKamtHJClsjgAWNKkBHMf69/+NFMzErs4uBR2coAksJ+vVXjhhRdeeOGFF1544YUXXvh/5usO+3srzKm/v/UAQKOpamZ0QlU1GldOmsY5BOQu4BrCHNXIpbulMPVX5IYPtNu1n0IyAB60FIbujF+50Qdt7s/dEJIRHrQ4da+45gcvFqfutZuiEZ5icbhw3BL7aOi7tyEauHRHuG4KnVIYxykaIYDsiLxSjDGt/BOB2+fjPmB/2PgBJp8FYb3sImYAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><mask + id="mask3168" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3170"><g + id="g3172" + clip-path="url(#clipPath3164)"><g + id="g3174"><g + id="g3176" + transform="matrix(62,0,0,84,991,495)"><image + id="image3178" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABUCAYAAADaroR4AAAABHNCSVQICAgIfAhkiAAAA1pJREFUeJztnMtuqzoYRheES0QSRaUdRGknff/3qjJIUCmXYIzhDI6MTC5765wR1F6SFQvHESvmByb+PGDgAZ7nPTq8OIbhoR4eN+Ke543SZn9pDMMwSpt9TaA7WtD3/btmjs8dLdj3/V0zxwNzku/7BEFAGIZjC4JgMfKmtFIKKSVSStq2RSk1kQ/gXyEtHccxSZKw2WzYbDbEcTzKL0FcSwshqOuaqqqo65qmaei6DqUUwFQ8DEOSJCFNU15fX0nTlN1uRxzHrFarWde8ruO+7xFCUFUV39/fXC4XsiybjAMEZm2HYch2u+Xt7Y2Pjw+OxyNpmpIkCWEYjpf8XBmGga7ruF6v5HnO6XQiDEOUUrRti5QSpRRKqecrfjwe+fz85HA4sNvtiKJo9pd73/dIKanrmvP5TBzHSCkpy5KiKLher0gp8TzvcY1vt1vSNOVwOPD+/s5+v2e9Xi9CvG1bqqoiiiKapuF8PpMkCVEUjeUKT+7q+ga32+3Y7/e8vLxM6nyO6Ppt25YgCKjrmiRJ7m7Od+L6oO/7rFYrwjAkiiLiOCaOY9br9SLEfd9HCDF5DOsbm/kiE9z+gJY3/wSzzVncPPdhGFBK0XXd+Bjr+/65uEZfAY/aEuj7fhTWn+Yr7LyfT/8D83mtX2Z037zUf5043Nf0bX3DLxXXPBLW/GrxP+HEbcOJ24YTtw0nbhtO3DacuG04cdtw4rbhxG3DiduGE7cNJ24bTtw2nLhtOHHbcOK24cRtw4nbhhO3DSduG07cNpy4bThx23DituHEbcOJ24YTtw1rxZ/uLf3bTr258V/P905c78s0gyZ0g/kmg+jdw7qZDo/+gMCcaMrqGBEhBEIIgNlvo9ZpIEKISSbE7YZauFlxvfVYR4kURUGe5wCzj0rQi9Y0DXmeUxQFdV0jhKDrujENRBOYk7R0WZZkWcbpdALg5+dn9uEYZlRCURScTieyLKMsy4n8ZOO8nqQTNbIs4+vrC4A8zxcTh/LIIcsy6rpGSjkV1xEDelJZlpzPZ4ZhoKqqxQXg6DovioIsy7hcLpRlOYrr7z5ccQAhBHmeLzLySJdsVVVj5NHtio+xZmYWzG8Iueq6bgy5klLe1fhEHOyJNbM2yO5OfBxYqPAtz15b/wHsvBSUT5t0gwAAAABJRU5ErkJggg==" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3164" + clipPathUnits="userSpaceOnUse"><path + id="path3166" + d="m 991,579 62,0 0,-84 -62,0 0,84 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3160" + clipPathUnits="userSpaceOnUse"><path + id="path3162" + d="m 991,579 62,0 0,-84 -62,0 0,84 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3152" + clipPathUnits="userSpaceOnUse"><path + id="path3154" + d="m 897,482 239.999,0 0,135 -239.999,0 0,-135 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3126" + clipPathUnits="userSpaceOnUse"><path + id="path3128" + d="m 887,628 270,0 0,-182 -270,0 0,182 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3118" + clipPathUnits="userSpaceOnUse"><path + id="path3120" + d="m 0,1080 1920,0 L 1920,0 0,0 0,1080 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3634-8" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3636-7" + d="m 570.26,532 c 0,-30.785 24.955,-55.742 55.74,-55.742 l 0,0 c 30.784,0 55.74,24.957 55.74,55.742 l 0,0 c 0,30.784 -24.956,55.74 -55.74,55.74 l 0,0 c -30.785,0 -55.74,-24.956 -55.74,-55.74" /></clipPath><clipPath + id="clipPath3642-3" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3644-4" + d="m 558.314,543.945 139.351,0 0,-78.633 -139.351,0 0,78.633 z" /></clipPath><mask + id="mask3650-5" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3652-7"><g + id="g3654-7" + clip-path="url(#clipPath3646-3)"><g + id="g3656-5"><g + id="g3658-1" + transform="matrix(139.35082,0,0,78.633677,558.31445,465.31115)"><image + id="image3660-3" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAABPCAYAAAA5vC0kAAAABHNCSVQICAgIfAhkiAAABCJJREFUeJzt3UFvskwYheEDAmNQYkq7MLab/v//1bhQUgqMwjDMt3gzBJTmy7Ol50omNSLdcAcfcEEAwGFBEARLb9Mf4dxiFgjwEEwQBGMs09f0Nzjnxlimr73Iv/BhhGH4tKbbaZ18GMMwPK3p9mi6UxiGiKIIcRyPK4oiRrNy01istTDGwBiDrutgrZ1FEwH/QvCxKKWQpil2ux12ux2UUmM0DGadnHNjLG3bQmuNpmmgtcb9fkff97DWAsA8mDiOkaYp8jzH6+sr8jxHlmVQSmGz2XCmWSE/pwzDgLZt0TQNvr+/cb1eURTFbDsARNPZJY5j7Pd7vL294ePjA6fTCXmeI01TxHE8fjXRujjn0Pc9brcbyrLE+XxGHMew1qLrOhhjYK2Ftfb3M8zpdMLn5yeOxyOyLEOSJPxaWqlhGGCMgdYal8sFSikYY1DXNaqqwu12gzEGQRAszzD7/R55nuN4POL9/R2HwwHb7ZbBrNQwDOi6Dk3TIEkS3O93XC4XpGmKJEnGcQT45SrJD75ZluFwOODl5WU2x9B6+Pmk6zpEUQStNdI0fbrYeQrGvxmGITabDeI4RpIkUEpBKYXtdstgVsgHE4Yh2rad3UbxA+/0Bl70+A98NNN4povBrItzbnbMnXOw1qLv+/FyehiG34Px/BlnadF6DcMwhuL/Tn8q4HUyAZjfj/E38fzr6VcSg6HR48zyOL8ADIYWLIXiMRgSYTAkwmBIhMGQCIMhEQZDIgyGRBgMiTAYEmEwJMJgSITBkAiDIREGQyIMhkQYDIkwGBJhMCTCYEiEwZAIgyERBkMiDIZEGAyJMBgSYTAkwmBIhMGQCIMhEQZDIgyGRBgMiTAYEmEwJMJgSITBkAiDIREGQyIMhkQYDIkwGBJhMCTCYEiEwZAIgyERBkMiDIZEGAyJMBgSYTAkwmBI5NfHEP/fwyJpHaTH+SkY/yha/9daOy4AfG71yvgHm/s1PfZL4UTTHaeRGGPQdR3atkXbtgCAzWbDYFbGB+OPc9d1MMbM4pmGMzvD+Keit20LrTWqqkJZlgCA7XaLMAwZzMr4k8T9fkdZlqiqClprtG2Lvu8xDMPs89F0Jx9LXdcoigLn8xkA8PPzgyRJGMwK+WPfdR2qqsL5fEZRFKjrehaNP8vMgjHGQGuNoijw9fUFACjLEmmaIo5jhCEvqtZo6dgXRQGtNYwx82CccwiCYNyprmtcLhc459A0DbIsg1JqnF94hlkXP6P4OaaqKhRFgev1irqux2D8ZxfPMADQti3KsoRSClEU8etoxR5HkqZp0DTN4hkmAOCAf5fLYRgiiiLEcTwuH4v/DK2Pj8FHY4wZ1+MMMwsGAMIwfFrT7bRO02ge13T7GIw3nVM4s/w90/suS3d9n4IZNzCUP+23nwf+AzNnFIrywW/wAAAAAElFTkSuQmCC" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3646-3" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3648-7" + d="m 558.314,543.945 139.351,0 0,-78.634 -139.351,0 0,78.634 z" /></clipPath><mask + id="mask3662-9" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3664-6" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAABPCAAAAAAc13L4AAAAAXNCSVQI5gpbmQAAAdJJREFUaIHt2rFu2zAUheFDirICJUZQt0OQdun7v1fgwRHqylJMkbyng1S0He5aarj/C/gDLWnhcQAAONSNfxTOwdXkkCBXjIP33vtqp0OIiAiIAMCHtm1DLQ0hJaWlCBjgfOj6x8cu+EoYKXGe5nsuCHC+7U+fT8euqfLckBKnH+8DKQgOvn368u311Le+ggVg/rie27KkUraTef3+cjzU+Z8kzZcu3caP5NZn5un08vX5oRJmmQ73S39o3PY2df3x+VPXVHlmZAlz3wXvHALgnG/aQ9c9VML4GDxIrt8ZOO980zR1MM47lpyLbBjArVXAAIDkkgvBOq/zP5EiRYTEDjDgGnaBAUgCe8FsGUbLMFqG0TKMlmG0DKNlGC3DaBlGyzBahtEyjJZhtAyjZRgtw2gZRsswWobRMoyWYbQMo2UYLcNoGUZru0r+fWX5//v7lwMAUCillCprHpZShMINQ0pJS4yoc+NfYlxSEXI9GclxHq+osxKh3K/jHLMACKDkeBvO+FlnP0NZxvNwi1mIAEqahzdcay2LJM3D2zAnIQKdpNuFU73NVYnj8H5LAq4ng3ituEbLcZrmJIQDXPWdXk4p5Q2zmwXj3radwF5Wr78ATrQFVxEFtwQAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><clipPath + id="clipPath3634-8-0" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3636-7-9" + d="m 570.26,532 c 0,-30.785 24.955,-55.742 55.74,-55.742 l 0,0 c 30.784,0 55.74,24.957 55.74,55.742 l 0,0 c 0,30.784 -24.956,55.74 -55.74,55.74 l 0,0 c -30.785,0 -55.74,-24.956 -55.74,-55.74" /></clipPath><clipPath + id="clipPath3642-3-4" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3644-4-2" + d="m 558.314,543.945 139.351,0 0,-78.633 -139.351,0 0,78.633 z" /></clipPath><mask + id="mask3650-5-0" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3652-7-6"><g + id="g3654-7-6" + clip-path="url(#clipPath3646-3-3)"><g + id="g3656-5-4"><g + id="g3658-1-6" + transform="matrix(139.35082,0,0,78.633677,558.31445,465.31115)"><image + id="image3660-3-1" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAABPCAYAAAA5vC0kAAAABHNCSVQICAgIfAhkiAAABCJJREFUeJzt3UFvskwYheEDAmNQYkq7MLab/v//1bhQUgqMwjDMt3gzBJTmy7Ol50omNSLdcAcfcEEAwGFBEARLb9Mf4dxiFgjwEEwQBGMs09f0Nzjnxlimr73Iv/BhhGH4tKbbaZ18GMMwPK3p9mi6UxiGiKIIcRyPK4oiRrNy01istTDGwBiDrutgrZ1FEwH/QvCxKKWQpil2ux12ux2UUmM0DGadnHNjLG3bQmuNpmmgtcb9fkff97DWAsA8mDiOkaYp8jzH6+sr8jxHlmVQSmGz2XCmWSE/pwzDgLZt0TQNvr+/cb1eURTFbDsARNPZJY5j7Pd7vL294ePjA6fTCXmeI01TxHE8fjXRujjn0Pc9brcbyrLE+XxGHMew1qLrOhhjYK2Ftfb3M8zpdMLn5yeOxyOyLEOSJPxaWqlhGGCMgdYal8sFSikYY1DXNaqqwu12gzEGQRAszzD7/R55nuN4POL9/R2HwwHb7ZbBrNQwDOi6Dk3TIEkS3O93XC4XpGmKJEnGcQT45SrJD75ZluFwOODl5WU2x9B6+Pmk6zpEUQStNdI0fbrYeQrGvxmGITabDeI4RpIkUEpBKYXtdstgVsgHE4Yh2rad3UbxA+/0Bl70+A98NNN4povBrItzbnbMnXOw1qLv+/FyehiG34Px/BlnadF6DcMwhuL/Tn8q4HUyAZjfj/E38fzr6VcSg6HR48zyOL8ADIYWLIXiMRgSYTAkwmBIhMGQCIMhEQZDIgyGRBgMiTAYEmEwJMJgSITBkAiDIREGQyIMhkQYDIkwGBJhMCTCYEiEwZAIgyERBkMiDIZEGAyJMBgSYTAkwmBIhMGQCIMhEQZDIgyGRBgMiTAYEmEwJMJgSITBkAiDIREGQyIMhkQYDIkwGBJhMCTCYEiEwZAIgyERBkMiDIZEGAyJMBgSYTAkwmBI5NfHEP/fwyJpHaTH+SkY/yha/9daOy4AfG71yvgHm/s1PfZL4UTTHaeRGGPQdR3atkXbtgCAzWbDYFbGB+OPc9d1MMbM4pmGMzvD+Keit20LrTWqqkJZlgCA7XaLMAwZzMr4k8T9fkdZlqiqClprtG2Lvu8xDMPs89F0Jx9LXdcoigLn8xkA8PPzgyRJGMwK+WPfdR2qqsL5fEZRFKjrehaNP8vMgjHGQGuNoijw9fUFACjLEmmaIo5jhCEvqtZo6dgXRQGtNYwx82CccwiCYNyprmtcLhc459A0DbIsg1JqnF94hlkXP6P4OaaqKhRFgev1irqux2D8ZxfPMADQti3KsoRSClEU8etoxR5HkqZp0DTN4hkmAOCAf5fLYRgiiiLEcTwuH4v/DK2Pj8FHY4wZ1+MMMwsGAMIwfFrT7bRO02ge13T7GIw3nVM4s/w90/suS3d9n4IZNzCUP+23nwf+AzNnFIrywW/wAAAAAElFTkSuQmCC" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3646-3-3" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3648-7-6" + d="m 558.314,543.945 139.351,0 0,-78.634 -139.351,0 0,78.634 z" /></clipPath><mask + id="mask3662-9-4" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3664-6-5" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAABPCAAAAAAc13L4AAAAAXNCSVQI5gpbmQAAAdJJREFUaIHt2rFu2zAUheFDirICJUZQt0OQdun7v1fgwRHqylJMkbyng1S0He5aarj/C/gDLWnhcQAAONSNfxTOwdXkkCBXjIP33vtqp0OIiAiIAMCHtm1DLQ0hJaWlCBjgfOj6x8cu+EoYKXGe5nsuCHC+7U+fT8euqfLckBKnH+8DKQgOvn368u311Le+ggVg/rie27KkUraTef3+cjzU+Z8kzZcu3caP5NZn5un08vX5oRJmmQ73S39o3PY2df3x+VPXVHlmZAlz3wXvHALgnG/aQ9c9VML4GDxIrt8ZOO980zR1MM47lpyLbBjArVXAAIDkkgvBOq/zP5EiRYTEDjDgGnaBAUgCe8FsGUbLMFqG0TKMlmG0DKNlGC3DaBlGyzBahtEyjJZhtAyjZRgtw2gZRsswWobRMoyWYbQMo2UYLcNoGUZru0r+fWX5//v7lwMAUCillCprHpZShMINQ0pJS4yoc+NfYlxSEXI9GclxHq+osxKh3K/jHLMACKDkeBvO+FlnP0NZxvNwi1mIAEqahzdcay2LJM3D2zAnIQKdpNuFU73NVYnj8H5LAq4ng3ituEbLcZrmJIQDXPWdXk4p5Q2zmwXj3radwF5Wr78ATrQFVxEFtwQAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><clipPath + id="clipPath3592-5" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3594-9" + d="m 730.778,549 12,0 0,-12 -12,0 0,12 z" /></clipPath><clipPath + id="clipPath3566-8" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3568-8" + d="m 679,547.865 32,0 0,-12.002 -32,0 0,12.002 z" /></clipPath><clipPath + id="clipPath3570-6" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3572-0" + d="m 679,535.865 32,0 0,12 -32,0 0,-12 z" /></clipPath><clipPath + id="clipPath3520-6" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3522-3" + d="m 667,561 93,0 0,-68 -93,0 0,68 z" /></clipPath><mask + id="mask3528-3" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3530-7"><g + id="g3532-3" + clip-path="url(#clipPath3524-5)"><g + id="g3534-0"><g + id="g3536-4" + transform="matrix(93,0,0,68,667,493)"><image + id="image3538-4" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAYAAADjqDmQAAAABHNCSVQICAgIfAhkiAAAA51JREFUeJztnEtv4koQRo/BpokBoThZIJJN/v/vCkoUYuSAbYwfPYu57duOzWPm3lEvpo5UwqLbXhyXihaLzwM0A3ieN/S1cCNaD2oFwOObdM/zWuH2tXAbWutWuH1t45sLI3c0GvXKXheGMXKbpumVvQ6WdPgp3Pd9giBoy/d9EX8FW3hd15RlSVmWnE4n6rruiffhp0wjXClFGIbMZjNmsxlKqVa8SB9Ga90KL4qCLMvIsow0TTkej1RVRV3X7f6O9CAICMOQKIp4eHggiiIWiwVKKcbjscz4AczcbpqG0+lEmqbsdjviOGY0GrXrZo/WGt+e5UEQMJ/PeXx85Pn5mfV6TRRFhGFIEATtmBG6aK2pqorj8UiSJLy/v6OUomkayrK8vdPX6zUvLy+sVisWiwWTyURGzBmapqGqKvI8J45jwjBEa02e5+2IKcvy306H/kyfz+dEUcRqteLp6Ynlcsl0OhXpZzDSsyxjNpvRNA37/Z7tdst2u22nhBnPg6cX82O6WCxYLpfc39935rrQxYyX6XQKwH6/Z7lcMp/PW2/2aO6c003Hj8djgiBgMpmglEIpxXQ6FelnMNIB8jwnDEPu7u5QShEEQe8Q4n9/gBFvvwC7RHofc/42zer7flv2WDH0pBvMxqES+pgmtctuYBs5A/4BrjWoSHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASP8D2GlGQ5zNBrBvvPaQvx07LsouO0LKpifd3mjCwEyBJNYNYaJHTFJdVVVtGZeDEYH22zI3n04niqKgKAoAiR45g5GeZRl5nrefRVFQliV1XXfEdzrdxCKZmLv9fk+SJAASJ3UBO07q8/OTOI5JkoTD4UBRFJ1sRvhHuulwI/xwOBDHMW9vbwB8fX1JcNoFvgenvb6+8vHxQZIk5HneCU1rg9OM9LIsybKMOI7ZbDYAJEkiEYFXGIoI3Gw2xHFMmqYd6QC+1hrP81rph8OB7XaL1po0TSUM8wqXwjB3ux15nlNVVf+H9HunAxRFQZIkEvt6A5diX+2ZbsS3Ud52NqMEHP8atwQc26eXjnSQKO/f5VeivCW0/n/mltD6nvR2QWT/Jy79ZfIDbR7YvKqk0OoAAAAASUVORK5CYII=" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3524-5" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3526-4" + d="m 667,561 93,0 0,-68 -93,0 0,68 z" /></clipPath><mask + id="mask3540-4" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3542-1" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAAAAADGw2ZMAAAAAXNCSVQI5gpbmQAAAZJJREFUWIXt2DFv2zAQhuHvTlTkyDaMuBmCtEv//+9q0KKuAtWWZJnkfR0UAwY69jyVXAhoeEQcyOUVAAAEvos3rAjE0ydBfugCVVV1Oz9hZmYgEABoqOs6ePGE5Rgv2UAEiIamXa+boE665Xkch3PKQIBo3e4/7bdN5TJ70i7De6ckjUGg9eb5y+u+rdUBB5jO/Y/G4s3ZX7++bB98RmNp6lpOwzkal7lv9i+fdysvfVzb8XCoVWS5M0273T01lYvOtMJxt2kqBQIgolX90DQrLx1T+9jUlQgCAIiKVlXlpKOqQwgqsrwmALIsDx2iqioqAHxu4V8/+DjoffTrKnrRi170ohe96EUvetGLXvSiF/3/0bkkvWsnIHn98u+ymRmNV51Gyzn7RD2mHFNKxqUYkpbjZZ7h1WfGaZzmmEkEAJbm8djDr1z96vrTnA0IoKX51H3Hb8fq9u1nP0UjA2hx7N7QuxbDt26IRgSKxdOBg3PtfJ8Sl8nEEXPvXWrnbIQAcqfKTN65kN+97t9sfv6y/QG64fFP78GtbgAAAABJRU5ErkJggg==" + height="1" + width="1" /></mask><clipPath + id="clipPath3592-5-6" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3594-9-5" + d="m 730.778,549 12,0 0,-12 -12,0 0,12 z" /></clipPath><clipPath + id="clipPath3566-8-1" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3568-8-2" + d="m 679,547.865 32,0 0,-12.002 -32,0 0,12.002 z" /></clipPath><clipPath + id="clipPath3570-6-5" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3572-0-0" + d="m 679,535.865 32,0 0,12 -32,0 0,-12 z" /></clipPath><clipPath + id="clipPath3520-6-0" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3522-3-3" + d="m 667,561 93,0 0,-68 -93,0 0,68 z" /></clipPath><mask + id="mask3528-3-8" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3530-7-0"><g + id="g3532-3-9" + clip-path="url(#clipPath3524-5-5)"><g + id="g3534-0-9"><g + id="g3536-4-3" + transform="matrix(93,0,0,68,667,493)"><image + id="image3538-4-0" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAYAAADjqDmQAAAABHNCSVQICAgIfAhkiAAAA51JREFUeJztnEtv4koQRo/BpokBoThZIJJN/v/vCkoUYuSAbYwfPYu57duOzWPm3lEvpo5UwqLbXhyXihaLzwM0A3ieN/S1cCNaD2oFwOObdM/zWuH2tXAbWutWuH1t45sLI3c0GvXKXheGMXKbpumVvQ6WdPgp3Pd9giBoy/d9EX8FW3hd15RlSVmWnE4n6rruiffhp0wjXClFGIbMZjNmsxlKqVa8SB9Ga90KL4qCLMvIsow0TTkej1RVRV3X7f6O9CAICMOQKIp4eHggiiIWiwVKKcbjscz4AczcbpqG0+lEmqbsdjviOGY0GrXrZo/WGt+e5UEQMJ/PeXx85Pn5mfV6TRRFhGFIEATtmBG6aK2pqorj8UiSJLy/v6OUomkayrK8vdPX6zUvLy+sVisWiwWTyURGzBmapqGqKvI8J45jwjBEa02e5+2IKcvy306H/kyfz+dEUcRqteLp6Ynlcsl0OhXpZzDSsyxjNpvRNA37/Z7tdst2u22nhBnPg6cX82O6WCxYLpfc39935rrQxYyX6XQKwH6/Z7lcMp/PW2/2aO6c003Hj8djgiBgMpmglEIpxXQ6FelnMNIB8jwnDEPu7u5QShEEQe8Q4n9/gBFvvwC7RHofc/42zer7flv2WDH0pBvMxqES+pgmtctuYBs5A/4BrjWoSHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASP8D2GlGQ5zNBrBvvPaQvx07LsouO0LKpifd3mjCwEyBJNYNYaJHTFJdVVVtGZeDEYH22zI3n04niqKgKAoAiR45g5GeZRl5nrefRVFQliV1XXfEdzrdxCKZmLv9fk+SJAASJ3UBO07q8/OTOI5JkoTD4UBRFJ1sRvhHuulwI/xwOBDHMW9vbwB8fX1JcNoFvgenvb6+8vHxQZIk5HneCU1rg9OM9LIsybKMOI7ZbDYAJEkiEYFXGIoI3Gw2xHFMmqYd6QC+1hrP81rph8OB7XaL1po0TSUM8wqXwjB3ux15nlNVVf+H9HunAxRFQZIkEvt6A5diX+2ZbsS3Ud52NqMEHP8atwQc26eXjnSQKO/f5VeivCW0/n/mltD6nvR2QWT/Jy79ZfIDbR7YvKqk0OoAAAAASUVORK5CYII=" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3524-5-5" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3526-4-5" + d="m 667,561 93,0 0,-68 -93,0 0,68 z" /></clipPath><mask + id="mask3540-4-8" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3542-1-9" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAAAAADGw2ZMAAAAAXNCSVQI5gpbmQAAAZJJREFUWIXt2DFv2zAQhuHvTlTkyDaMuBmCtEv//+9q0KKuAtWWZJnkfR0UAwY69jyVXAhoeEQcyOUVAAAEvos3rAjE0ydBfugCVVV1Oz9hZmYgEABoqOs6ePGE5Rgv2UAEiIamXa+boE665Xkch3PKQIBo3e4/7bdN5TJ70i7De6ckjUGg9eb5y+u+rdUBB5jO/Y/G4s3ZX7++bB98RmNp6lpOwzkal7lv9i+fdysvfVzb8XCoVWS5M0273T01lYvOtMJxt2kqBQIgolX90DQrLx1T+9jUlQgCAIiKVlXlpKOqQwgqsrwmALIsDx2iqioqAHxu4V8/+DjoffTrKnrRi170ohe96EUvetGLXvSiF/3/0bkkvWsnIHn98u+ymRmNV51Gyzn7RD2mHFNKxqUYkpbjZZ7h1WfGaZzmmEkEAJbm8djDr1z96vrTnA0IoKX51H3Hb8fq9u1nP0UjA2hx7N7QuxbDt26IRgSKxdOBg3PtfJ8Sl8nEEXPvXWrnbIQAcqfKTN65kN+97t9sfv6y/QG64fFP78GtbgAAAABJRU5ErkJggg==" + height="1" + width="1" /></mask><clipPath + id="clipPath3942-2" + clipPathUnits="userSpaceOnUse"><path + id="path3944-1" + d="m 1337.7,554.569 67.31,0 0,-64.569 -67.31,0 0,64.569 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3912-3" + clipPathUnits="userSpaceOnUse"><path + id="path3914-9" + d="m 1404.777,549.002 12,0 0,11.998 -12,0 0,-11.998 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3908-4" + clipPathUnits="userSpaceOnUse"><path + id="path3910-0" + d="m 1404.78,561 12,0 0,-12 -12,0 0,12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3886-1" + clipPathUnits="userSpaceOnUse"><path + id="path3888-7" + d="m 1363,547.865 32,0 0,12 -32,0 0,-12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3882-9" + clipPathUnits="userSpaceOnUse"><path + id="path3884-9" + d="m 1363,559.865 32,0 0,-12.002 -32,0 0,12.002 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3852-6" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3854-6" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHEAAABECAAAAACTooUSAAAAAXNCSVQI5gpbmQAAAXhJREFUWIXt2T9v3DAMBfBHWj4Fzh2CXjsEaZd+/+8VZGiN+v4Y1cni6+ADmqUjnQ7kqEE/ULQXPgEAQLBB8S8lAnE3SZCrKFBVVd8+CTMzA5EAaOr7PrmShC211sWABNGUh8fHnNRTtKVcrzMWY4JoPxw/Hw+585sl2cp5/AkzMgm033/59nIcevUCAavz+Cq3Upvce3z5/nzY+T0r7XZ+w/zrpMJ1jvvj89enB0/x94Rpn5PK/VvNw+HpU+78xFZwGnJSAAkQ0a7f5fzgKSLv+k5FgAQAoqJd1zmK6DqVdWppPZK1vES8u93xj/hHhRhiiCGGGGKIIYYYYoghhhhiiCGGGOL/Jt73ciRJuinvr08AQKO11vzCALbWjMa7SFqrt1LgutEtt9qMXHu0pcznCc5b6/NcFgOQQFvKZXzDyXszP17KYkQCrc7jKyb/9GGcqxGJYvXyg9ctEpZLNXDtEWXaJEWqRgggWyZl/IA08EMST2DTVPcPY4fdi0eNNAgAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><mask + id="mask3840-6" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3842-8"><g + id="g3844-1" + clip-path="url(#clipPath3836-1)"><g + id="g3846-7"><g + id="g3848-5" + transform="matrix(113,0,0,68,1351,505)"><image + id="image3850-5" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHEAAABECAYAAAC2ydrOAAAABHNCSVQICAgIfAhkiAAAA1NJREFUeJztnc1uozAURj8HjCMCikq7iNJu+v7vVXXRovJn1RDiWUztMQnttIuQmat7pKugAFn4yDZk8V0BwGIGIcTc18wVsXZWFQROJAohvMDwmLke1lovMDx2xO7AyVqtVmcVnmeWw8k6Ho9nFZ6Pw5tWqxXiOIaU0lccxyzyCoQCD4cDhmHwdTgcvEjgQ6IQwgtUSiFNU2w2G2w2GyilvEiWuBzWWi/QGIOu69B1HbTWAOBFWmunEqWUSNMURVHg9vYWRVEgz3MopRBFEe+RC+H2vXEcYYxB0zQoyxKvr68A/iyv7ro43AullMiyDHd3d3h4eMB+v0dRFEjTFFJKv6wyl+d4PGIYBmitUZYlnp6eIIRA3/cwxmAYBozjCCHE5zNxv9/j8fERu90OeZ4jSRJeUhfCLaV936NpGjw/PwMAtNZ4e3tDXdfexdly6vbELMtQFAV2ux3u7++x3W6xXq9Z4kI4ie/v76iqCgBQVRWyLJt9Rpl9OnUPN3meY7vd4ubmZrIvMpcl3A8BoK5rpGk6ERgyeU90MzKKIkgpkSQJlFJQSmG9XrPEhXASAUAphSRJIKVEFEV+BoYe4tMfcCJDoWGxxMvj3hHdmIc+5sb/TKLD2Z4r5vL8ZNz5nYEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEALJEAn2a7uWji02Iuz0/H/kyiC0x1n+M4+gI4kX8JXFSmq9DHnMw4vDEUNwyDz5t24akclbkMYWitMQZ93/vM7zDA3TGZiWGEv9YaTdP4+GKOj16O0/jopmmgtYYx5qwnBvAh8bQHQ9u2KMvSB4jXdc1B7gsyF+ReliXatp2InHSocTedRvgDvwPEuaXC8sz5KMsSWmsMwzCVaK2FEMLf1LYtXl5eYK1F13Xc3OQKfNXcpG1bL9FdOzsTAcAYg6qquM3QlfiqzdDpTPSt98LeGNzw6/p8p+HXrESAW+/9S3y39R43wfwP+FsTzDOJ/gTL++f47K+3XyWNnXDxB1SBAAAAAElFTkSuQmCC" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3836-1" + clipPathUnits="userSpaceOnUse"><path + id="path3838-6" + d="m 1351,573 113,0 0,-68 -113,0 0,68 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3832-3" + clipPathUnits="userSpaceOnUse"><path + id="path3834-3" + d="m 1351,573 113,0 0,-68 -113,0 0,68 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3824-4" + clipPathUnits="userSpaceOnUse"><path + id="path3826-5" + d="m 0,1080 1920,0 L 1920,0 0,0 0,1080 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3798-6" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3800-3" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHEAAABECAAAAACTooUSAAAAAXNCSVQI5gpbmQAAAZ9JREFUWIXt2U9v1DAQBfA348lmyXa1FdBSgRDf/4tVe4CI7J+oXtvzOKQIOCOnF8/Ft/lpZCeHeQIAgGCF4h9KBFLdJEEuokBVVevOSbi7OwiDiIZN14WqJOE5pZQdMEBtO+yGPmhN0XO8Xmdkp4mEfv/+w/2u13p3SZZ4Hn/AnTRo2B6evjwd3lnFGT3N47PcYipiIrY9PH77+nHotBpIv52PmH+eVGiQsBnuHz5/2m1qii8TprveVJa3av2wP9xt6j0dlojT0JsCMJAk1LptVRH9pgsqAhjoJedC0YqfBxGCytLfCJZcsgM1/3Qi8ru7gnQv7mQ17t9SgEutBEIBYEXvVVy1mtjEJjaxiU1sYhOb2MQmNrGJTWxiE5v4P2XLUXlt9Xd7AwA6vZRSLwxgKcXpfBVJL+kWI0LNjW68peLkMqPnOJ8nbCvuV/1lOs8xO5aNbo6X8YhTzR2y387H8RKzEwZ6msdnTDWzgCV9GOfkhFE8Xb7zuu9D9YTlkhxcZkScelshRUpOCCBqXdfZOkkZ3yANfJPEE1g11f0FocoCRBRb0tkAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><mask + id="mask3786-0" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3788-7"><g + id="g3790-3" + clip-path="url(#clipPath3782-0)"><g + id="g3792-9"><g + id="g3794-3" + transform="matrix(113,0,0,68,1351,444)"><image + id="image3796-9" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAHEAAABECAYAAAC2ydrOAAAABHNCSVQICAgIfAhkiAAAA59JREFUeJztnclurDoURTdgmkAhSmlLiaL8/49FGSQodFZM5zd4sstUkdsMQnKPzpKsQgVMWDo2ZrCPB0BjBc/z1v5mvhGtV1XBw4lEz/OsQPeY+T601lage2wQ5sDI8n3/bLjnme0wsuZ5PhvueQEcK873fQRBgCiKEIYhwjBEEAQs8htwBY7jiGEY7BjH0YoEnEr0fR9CCCRJgjRNkWUZ0jRFHMdWJEvcDq21FaiUQtd16LoOUkoAsCK11hCmCoMgQBzHyPMcl5eXuLq6wn6/R5ZliOPYSmSRX49Z96ZpglIKTdOgLEu8vb0BOE6v5joBwE6jSZKgKAocDgc8PDzgcDigKApcXFxACMECN2SeZwzDACklyrLE8/MzPM9D3/dQSmEYBkzTBM/zjpVoptKiKHB7e4unpyc8Pj7i+voaaZoiDEO7NjJfi5lK+75H0zR4eXkBAEgp8f7+jrqu7cxoK9FMp1EUIU1T7Pd73Nzc4P7+Hnd3d8iyDFEUscSNMBI/Pj5QVRUAoKoq7HY7xHEMIcTiHeXs7VQIgTiOkaYp8jxHURTY7XZWIk+pX4+7HgJAXdf2JdMIdBHmJncAx7fVMAyRJAlL3BAjEQDiOLZbPneX4HqwEud5xjRNGMcR4zhimiZorRf7R5a4DaaQgiBYPPfPnr9wP+cYiebX3VAC/BluS8yzdsdn+MBxOjX7j2mazvYizM/FrpCn6+LpGsn8XM72DCzv34M3fgRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQRgiQQQn53gdKnv42+f/ZlEk/HmJi+aAXAi/xaYsEQzXB9rMoV7oytuGAabN23CU4MgYIkb4IbWKqXQ973N/F4LTVxUohvhL6VE0zQ2vjhJEs473YjT+OimaSClhFJqNcJ0EVprBLZti7IsbYB4XdecPLwha0HuZVmibduFyEWHGnPTaYQ/8H+AOKfxb8+aj7IsIaXEMAxLiSYi2tzUti1eX1+htUbXdcjz3Hap4eThbfhVc5O2ba1Ec+1qJQKAUgpVVa1G+DNfz6/aDJ1Wom2957ZUMM2+wjBcRPizxO34k4ZfqxIBbr33k/jT1nvcBPMf4HdNMM8k2hMs78fx2ae3/wBR6gt9OOvm0AAAAABJRU5ErkJggg==" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3782-0" + clipPathUnits="userSpaceOnUse"><path + id="path3784-8" + d="m 1351,512 113,0 0,-68 -113,0 0,68 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3778-1" + clipPathUnits="userSpaceOnUse"><path + id="path3780-0" + d="m 1351,512 113,0 0,-68 -113,0 0,68 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3770-5" + clipPathUnits="userSpaceOnUse"><path + id="path3772-0" + d="m 1341,490 129,0 0,89 -129,0 0,-89 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3748-6" + clipPathUnits="userSpaceOnUse"><path + id="path3750-3" + d="m 1214,628 270,0 0,-182 -270,0 0,182 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3726-6" + clipPathUnits="userSpaceOnUse"><path + id="path3728-1" + d="m 652.002,520.002 12,0 0,11.998 -12,0 0,-11.998 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3722-1" + clipPathUnits="userSpaceOnUse"><path + id="path3724-4" + d="m 652,532 12.002,0 0,-12 -12.002,0 0,12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3700-1" + clipPathUnits="userSpaceOnUse"><path + id="path3702-8" + d="m 592,518.865 32,0 0,12 -32,0 0,-12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3696-9" + clipPathUnits="userSpaceOnUse"><path + id="path3698-6" + d="m 592,530.865 32,0 0,-12.002 -32,0 0,12.002 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3688-4" + clipPathUnits="userSpaceOnUse"><path + id="path3690-8" + d="m 0,1080 1920,0 L 1920,0 0,0 0,1080 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3662-6" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3664-9" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAABPCAAAAAAc13L4AAAAAXNCSVQI5gpbmQAAAdJJREFUaIHt2rFu2zAUheFDirICJUZQt0OQdun7v1fgwRHqylJMkbyng1S0He5aarj/C/gDLWnhcQAAONSNfxTOwdXkkCBXjIP33vtqp0OIiAiIAMCHtm1DLQ0hJaWlCBjgfOj6x8cu+EoYKXGe5nsuCHC+7U+fT8euqfLckBKnH+8DKQgOvn368u311Le+ggVg/rie27KkUraTef3+cjzU+Z8kzZcu3caP5NZn5un08vX5oRJmmQ73S39o3PY2df3x+VPXVHlmZAlz3wXvHALgnG/aQ9c9VML4GDxIrt8ZOO980zR1MM47lpyLbBjArVXAAIDkkgvBOq/zP5EiRYTEDjDgGnaBAUgCe8FsGUbLMFqG0TKMlmG0DKNlGC3DaBlGyzBahtEyjJZhtAyjZRgtw2gZRsswWobRMoyWYbQMo2UYLcNoGUZru0r+fWX5//v7lwMAUCillCprHpZShMINQ0pJS4yoc+NfYlxSEXI9GclxHq+osxKh3K/jHLMACKDkeBvO+FlnP0NZxvNwi1mIAEqahzdcay2LJM3D2zAnIQKdpNuFU73NVYnj8H5LAq4ng3ituEbLcZrmJIQDXPWdXk4p5Q2zmwXj3radwF5Wr78ATrQFVxEFtwQAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><mask + id="mask3650-6" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3652-6"><g + id="g3654-8" + clip-path="url(#clipPath3646-6)"><g + id="g3656-3"><g + id="g3658-9" + transform="matrix(139.35082,0,0,78.633677,558.31445,465.31115)"><image + id="image3660-2" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAABPCAYAAAA5vC0kAAAABHNCSVQICAgIfAhkiAAABCJJREFUeJzt3UFvskwYheEDAmNQYkq7MLab/v//1bhQUgqMwjDMt3gzBJTmy7Ol50omNSLdcAcfcEEAwGFBEARLb9Mf4dxiFgjwEEwQBGMs09f0Nzjnxlimr73Iv/BhhGH4tKbbaZ18GMMwPK3p9mi6UxiGiKIIcRyPK4oiRrNy01istTDGwBiDrutgrZ1FEwH/QvCxKKWQpil2ux12ux2UUmM0DGadnHNjLG3bQmuNpmmgtcb9fkff97DWAsA8mDiOkaYp8jzH6+sr8jxHlmVQSmGz2XCmWSE/pwzDgLZt0TQNvr+/cb1eURTFbDsARNPZJY5j7Pd7vL294ePjA6fTCXmeI01TxHE8fjXRujjn0Pc9brcbyrLE+XxGHMew1qLrOhhjYK2Ftfb3M8zpdMLn5yeOxyOyLEOSJPxaWqlhGGCMgdYal8sFSikYY1DXNaqqwu12gzEGQRAszzD7/R55nuN4POL9/R2HwwHb7ZbBrNQwDOi6Dk3TIEkS3O93XC4XpGmKJEnGcQT45SrJD75ZluFwOODl5WU2x9B6+Pmk6zpEUQStNdI0fbrYeQrGvxmGITabDeI4RpIkUEpBKYXtdstgVsgHE4Yh2rad3UbxA+/0Bl70+A98NNN4povBrItzbnbMnXOw1qLv+/FyehiG34Px/BlnadF6DcMwhuL/Tn8q4HUyAZjfj/E38fzr6VcSg6HR48zyOL8ADIYWLIXiMRgSYTAkwmBIhMGQCIMhEQZDIgyGRBgMiTAYEmEwJMJgSITBkAiDIREGQyIMhkQYDIkwGBJhMCTCYEiEwZAIgyERBkMiDIZEGAyJMBgSYTAkwmBIhMGQCIMhEQZDIgyGRBgMiTAYEmEwJMJgSITBkAiDIREGQyIMhkQYDIkwGBJhMCTCYEiEwZAIgyERBkMiDIZEGAyJMBgSYTAkwmBI5NfHEP/fwyJpHaTH+SkY/yha/9daOy4AfG71yvgHm/s1PfZL4UTTHaeRGGPQdR3atkXbtgCAzWbDYFbGB+OPc9d1MMbM4pmGMzvD+Keit20LrTWqqkJZlgCA7XaLMAwZzMr4k8T9fkdZlqiqClprtG2Lvu8xDMPs89F0Jx9LXdcoigLn8xkA8PPzgyRJGMwK+WPfdR2qqsL5fEZRFKjrehaNP8vMgjHGQGuNoijw9fUFACjLEmmaIo5jhCEvqtZo6dgXRQGtNYwx82CccwiCYNyprmtcLhc459A0DbIsg1JqnF94hlkXP6P4OaaqKhRFgev1irqux2D8ZxfPMADQti3KsoRSClEU8etoxR5HkqZp0DTN4hkmAOCAf5fLYRgiiiLEcTwuH4v/DK2Pj8FHY4wZ1+MMMwsGAMIwfFrT7bRO02ge13T7GIw3nVM4s/w90/suS3d9n4IZNzCUP+23nwf+AzNnFIrywW/wAAAAAElFTkSuQmCC" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3646-6" + clipPathUnits="userSpaceOnUse"><path + id="path3648-8" + d="m 558.314,543.945 139.351,0 0,-78.634 -139.351,0 0,78.634 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3642-7" + clipPathUnits="userSpaceOnUse"><path + id="path3644-3" + d="m 558.314,543.945 139.351,0 0,-78.633 -139.351,0 0,78.633 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3634-3" + clipPathUnits="userSpaceOnUse"><path + id="path3636-8" + d="m 570.26,532 c 0,-30.785 24.955,-55.742 55.74,-55.742 l 0,0 c 30.784,0 55.74,24.957 55.74,55.742 l 0,0 c 0,30.784 -24.956,55.74 -55.74,55.74 l 0,0 c -30.785,0 -55.74,-24.956 -55.74,-55.74" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3610-5" + clipPathUnits="userSpaceOnUse"><path + id="path3612-4" + d="m 652.333,574.333 101,0 0,-79.333 -101,0 0,79.333 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3592-6" + clipPathUnits="userSpaceOnUse"><path + id="path3594-98" + d="m 730.778,549 12,0 0,-12 -12,0 0,12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3570-0" + clipPathUnits="userSpaceOnUse"><path + id="path3572-8" + d="m 679,535.865 32,0 0,12 -32,0 0,-12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3566-5" + clipPathUnits="userSpaceOnUse"><path + id="path3568-3" + d="m 679,547.865 32,0 0,-12.002 -32,0 0,12.002 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3540-6" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3542-0" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAAAAADGw2ZMAAAAAXNCSVQI5gpbmQAAAZJJREFUWIXt2DFv2zAQhuHvTlTkyDaMuBmCtEv//+9q0KKuAtWWZJnkfR0UAwY69jyVXAhoeEQcyOUVAAAEvos3rAjE0ydBfugCVVV1Oz9hZmYgEABoqOs6ePGE5Rgv2UAEiIamXa+boE665Xkch3PKQIBo3e4/7bdN5TJ70i7De6ckjUGg9eb5y+u+rdUBB5jO/Y/G4s3ZX7++bB98RmNp6lpOwzkal7lv9i+fdysvfVzb8XCoVWS5M0273T01lYvOtMJxt2kqBQIgolX90DQrLx1T+9jUlQgCAIiKVlXlpKOqQwgqsrwmALIsDx2iqioqAHxu4V8/+DjoffTrKnrRi170ohe96EUvetGLXvSiF/3/0bkkvWsnIHn98u+ymRmNV51Gyzn7RD2mHFNKxqUYkpbjZZ7h1WfGaZzmmEkEAJbm8djDr1z96vrTnA0IoKX51H3Hb8fq9u1nP0UjA2hx7N7QuxbDt26IRgSKxdOBg3PtfJ8Sl8nEEXPvXWrnbIQAcqfKTN65kN+97t9sfv6y/QG64fFP78GtbgAAAABJRU5ErkJggg==" + height="1" + width="1" /></mask><mask + id="mask3528-8" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3530-9"><g + id="g3532-7" + clip-path="url(#clipPath3524-3)"><g + id="g3534-3"><g + id="g3536-8" + transform="matrix(93,0,0,68,667,493)"><image + id="image3538-8" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAYAAADjqDmQAAAABHNCSVQICAgIfAhkiAAAA51JREFUeJztnEtv4koQRo/BpokBoThZIJJN/v/vCkoUYuSAbYwfPYu57duOzWPm3lEvpo5UwqLbXhyXihaLzwM0A3ieN/S1cCNaD2oFwOObdM/zWuH2tXAbWutWuH1t45sLI3c0GvXKXheGMXKbpumVvQ6WdPgp3Pd9giBoy/d9EX8FW3hd15RlSVmWnE4n6rruiffhp0wjXClFGIbMZjNmsxlKqVa8SB9Ga90KL4qCLMvIsow0TTkej1RVRV3X7f6O9CAICMOQKIp4eHggiiIWiwVKKcbjscz4AczcbpqG0+lEmqbsdjviOGY0GrXrZo/WGt+e5UEQMJ/PeXx85Pn5mfV6TRRFhGFIEATtmBG6aK2pqorj8UiSJLy/v6OUomkayrK8vdPX6zUvLy+sVisWiwWTyURGzBmapqGqKvI8J45jwjBEa02e5+2IKcvy306H/kyfz+dEUcRqteLp6Ynlcsl0OhXpZzDSsyxjNpvRNA37/Z7tdst2u22nhBnPg6cX82O6WCxYLpfc39935rrQxYyX6XQKwH6/Z7lcMp/PW2/2aO6c003Hj8djgiBgMpmglEIpxXQ6FelnMNIB8jwnDEPu7u5QShEEQe8Q4n9/gBFvvwC7RHofc/42zer7flv2WDH0pBvMxqES+pgmtctuYBs5A/4BrjWoSHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASP8D2GlGQ5zNBrBvvPaQvx07LsouO0LKpifd3mjCwEyBJNYNYaJHTFJdVVVtGZeDEYH22zI3n04niqKgKAoAiR45g5GeZRl5nrefRVFQliV1XXfEdzrdxCKZmLv9fk+SJAASJ3UBO07q8/OTOI5JkoTD4UBRFJ1sRvhHuulwI/xwOBDHMW9vbwB8fX1JcNoFvgenvb6+8vHxQZIk5HneCU1rg9OM9LIsybKMOI7ZbDYAJEkiEYFXGIoI3Gw2xHFMmqYd6QC+1hrP81rph8OB7XaL1po0TSUM8wqXwjB3ux15nlNVVf+H9HunAxRFQZIkEvt6A5diX+2ZbsS3Ud52NqMEHP8atwQc26eXjnSQKO/f5VeivCW0/n/mltD6nvR2QWT/Jy79ZfIDbR7YvKqk0OoAAAAASUVORK5CYII=" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3524-3" + clipPathUnits="userSpaceOnUse"><path + id="path3526-7" + d="m 667,561 93,0 0,-68 -93,0 0,68 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3520-9" + clipPathUnits="userSpaceOnUse"><path + id="path3522-1" + d="m 667,561 93,0 0,-68 -93,0 0,68 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3498-7" + clipPathUnits="userSpaceOnUse"><path + id="path3500-1" + d="m 560,628 270,0 0,-182 -270,0 0,182 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3490-4" + clipPathUnits="userSpaceOnUse"><path + id="path3492-5" + d="m 0,1080 1920,0 L 1920,0 0,0 0,1080 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3476-8" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3478-3" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABHcAAAK/CAAAAADGr34kAAAAAXNCSVQI5gpbmQAACLFJREFUeJzt1DEBACAMwDDAv+fhohwkCnp1zwJIndcBwHd8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4DaBSkuBn0AocgUAAAAAElFTkSuQmCC" + height="1" + width="1" /></mask><clipPath + id="clipPath3470-9" + clipPathUnits="userSpaceOnUse"><path + id="path3472-6" + d="m 538,215 954,0 0,118 -954,0 0,-118 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3460-8" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3462-0" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABHcAAAK/CAAAAADGr34kAAAAAXNCSVQI5gpbmQAACLFJREFUeJzt1DEBACAMwDDAv+fhohwkCnp1zwJIndcBwHd8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4Ca7wA13wFqvgPUfAeo+Q5Q8x2g5jtAzXeAmu8ANd8Bar4D1HwHqPkOUPMdoOY7QM13gJrvADXfAWq+A9R8B6j5DlDzHaDmO0DNd4DaBSkuBn0AocgUAAAAAElFTkSuQmCC" + height="1" + width="1" /></mask><clipPath + id="clipPath3454-4" + clipPathUnits="userSpaceOnUse"><path + id="path3456-3" + d="m 554,720 958,0 0,204 -958,0 0,-204 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3432-5" + clipPathUnits="userSpaceOnUse"><path + id="path3434-1" + d="m 904,587 32,0 0,12 -32,0 0,-12 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3428-5" + clipPathUnits="userSpaceOnUse"><path + id="path3430-0" + d="m 904,599 32,0 0,-12.002 -32,0 0,12.002 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3420-8" + clipPathUnits="userSpaceOnUse"><path + id="path3422-5" + d="m 0,1080 1920,0 L 1920,0 0,0 0,1080 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3396-6" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3398-2" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFwAAACdCAAAAAAcMECVAAAAAXNCSVQI5gpbmQAAAZdJREFUaIHt27tu20AQheEzy6Vo0BKMKCkMJ03e/70MFzYR3YisljsnBQXETZpg1J0pt/gwGGz7GwAAhtjhX9UMFsmTIFfckFJKKWx7wt3dQWQAKfd9n6N0wpda6+JAhqU8jI+PQ05BuC/lcpmxODMs9eP+6343dCF3J1s5TR9wJ7Mh9dtvP172Y58CbMDrPL3atdRmt81ffj7vNiF3oV9Pb5h/HZNxvfl2//z96SEI/33AYTvkZLffMoy7py9DF4K3guM45AQgA2ap6zfD8BCEY9j0XTIDMgBYstR1XQyOrku2XjivT7ZOAI5PUMz3+8cIFy5cuHDhwoULFy5cuHDhwoULFy5cuHDhwoULFy5cuHDhwoULFy5cuHDhwoULFy5cuHDhwv97bkEBSZIR4GcpAwCd3loLaX7YWnM6bzjprV5LQVQhUq61Oblu7kuZTwfEtS2nuSwOIIO+lPP0hmNglTOdy+JEBr3O0ysOoT3RNFcnMs3r+Z2X4BLqXB1cN0c5RDdc1QkD7E71Ge/bzd27+APu1Sr+ATqP3j0zgxPtAAAAAElFTkSuQmCC" + height="1" + width="1" /></mask><mask + id="mask3384-8" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3386-8"><g + id="g3388-5" + clip-path="url(#clipPath3380-6)"><g + id="g3390-8"><g + id="g3392-8" + transform="matrix(92,0,0,157,888,469)"><image + id="image3394-9" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFwAAACdCAYAAAA5Wx9JAAAABHNCSVQICAgIfAhkiAAABIZJREFUeJzt111rs0gYxvHL92AipbYHIe1Jv//3CjlopMYXMmqcPdgdH03s7lOWvWDh+sPQUDWUX4c7Ew+AxUqe5639Wv1m1q6ywsMduOd5E/b8tfq9rLUT9vy1K3QvHKzv+w9rfl2t52DHcXxY8+vh/CHf9xGGIaIomlYYhkL/h+bYwzCg7/tpDcMwoQN/gXueN2EnSYI0TbHdbrHdbpEkyYQu8PWstRO2MQZN06BpGrRtCwATurV2CR5FEdI0RZ7neHl5QZ7nyLIMSZIgCALN9JXcnL7dbjDGoKoqFEWB8/kM4NeIcfeF89kdRRF2ux1eX1/x/v6Ow+GAPM+RpimiKJpGi1o2jiP6vkfbtiiKAsfjEZ7noes6GGPQ9z1utxs8z/t+hx8OB3x8fGC/3yPLMsRxrLGykhsnXdehqiqcTicAQNu2+Pr6wuVymdweRoqb4bvdDnmeY7/f4+3tDU9PT9hsNgJfyYFfr1eUZQkAKMsSu91u9fNv9ZTiPjizLMPT0xOen58Xc1z9aj6/AeByuSBN0wX2vMU53O30IAgQRRHiOEaSJEiSBJvNRuArOXAASJIEcRwjiiIEQTDt7LlZeP8GDn2OP18CX+bO4M5nbrdm9QDucv+ZtaWW/cRI5zxyAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInJ3ByAicncHICJydwcgInF353wVq7utSynzo9gFtrMY7j9PN2u00LADzP++/++v9h1tqF0dxuDT6cPzhH7vseXdfBGANjDAAgCAKB3+XAnVPXdej7foE/h1/s8HEcMQwDjDFo2xZVVaEsSwDAZrOB7/sCv8tt0uv1irIsUVUV2raFMQbDMGAcx8X94fwhh13XNYqiwOl0AgBcLhfEcSzwlZxd13Woqgqn0wlFUaCu6wW62+UL8L7v0bYtiqLA8XgEAJRliTRNEUURfF+HmrXW7IqiQNu26Pt+CW6thed500N1XePz8xPWWjRNgyzLkCTJNL+1w5e5Ge3meFVVKIoC5/MZdV1P4O7e1R0OAMYYlGWJJEkQhqHGyd90P5KbpkHTNKs73ANggT+Pe77vIwxDRFE0LYft7lGPOUyH3vf9tO5n+AIcAHzff1jz62q9Ofr9ml+fwF3zOa2Z/fPm5+61b50P4NMFQf+rvvt6/we8Kp4iURf8WgAAAABJRU5ErkJggg==" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3380-6" + clipPathUnits="userSpaceOnUse"><path + id="path3382-6" + d="m 888,626 92,0 0,-157 -92,0 0,157 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3376-1" + clipPathUnits="userSpaceOnUse"><path + id="path3378-8" + d="m 888,626 92,0 0,-157 -92,0 0,157 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3354-1" + clipPathUnits="userSpaceOnUse"><path + id="path3356-9" + d="m 1116,527 26.006,0 0,3 -26.006,0 0,-3 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3350-2" + clipPathUnits="userSpaceOnUse"><path + id="path3352-7" + d="m 1116,530 26.01,0 0,-3 -26.01,0 0,3 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3328-2" + clipPathUnits="userSpaceOnUse"><path + id="path3330-1" + d="m 1057.994,527 11.006,0 0,3 -11.006,0 0,-3 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3324-6" + clipPathUnits="userSpaceOnUse"><path + id="path3326-2" + d="m 1057.99,530 26,0 0,-3 -26,0 0,3 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3302-2" + clipPathUnits="userSpaceOnUse"><path + id="path3304-7" + d="m 1000,527 26.006,0 0,3 -26.006,0 0,-3 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3298-9" + clipPathUnits="userSpaceOnUse"><path + id="path3300-4" + d="m 1000,530 26.01,0 0,-3 -26.01,0 0,3 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3272-6" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3274-5" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABUCAAAAAD/xdukAAAAAXNCSVQI5gpbmQAAAZZJREFUWIXt2L1u3DAQBOBZijoZsg9GLikMO03e/72MK85CLvrxUeTuuJCCJB0lA6m4tT4tl6x2BAAAwdbiHycC2fYDEuTCBc455zacgDAzMxAegPN1Xft8T5jGOKuBHuJ8097fN95lc9MwjdMtKTzE1e3p6+nYVJnzkxbGn28dafACVz98+/58amuX2z29X8+1zlF17f784+l4yD29xenSxKF/j7LM/nB6enm8y+bzeLhd2kMl68037fHxS1Nlzm6zn9rGOxF4QMRV9aFp7rK5C96B5PLuECeuqqpcLk6oKamtHJClsjgAWNKkBHMf69/+NFMzErs4uBR2coAksJ+vVXjhhRdeeOGFF1544YUXXvh/5usO+3srzKm/v/UAQKOpamZ0QlU1GldOmsY5BOQu4BrCHNXIpbulMPVX5IYPtNu1n0IyAB60FIbujF+50Qdt7s/dEJIRHrQ4da+45gcvFqfutZuiEZ5icbhw3BL7aOi7tyEauHRHuG4KnVIYxykaIYDsiLxSjDGt/BOB2+fjPmB/2PgBJp8FYb3sImYAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><mask + id="mask3260-5" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3262-2"><g + id="g3264-6" + clip-path="url(#clipPath3256-0)"><g + id="g3266-6"><g + id="g3268-0" + transform="matrix(62,0,0,84,1107,495)"><image + id="image3270-6" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABUCAYAAADaroR4AAAABHNCSVQICAgIfAhkiAAAA1pJREFUeJztnMtuqzoYRheES0QSRaUdRGknff/3qjJIUCmXYIzhDI6MTC5765wR1F6SFQvHESvmByb+PGDgAZ7nPTq8OIbhoR4eN+Ke543SZn9pDMMwSpt9TaA7WtD3/btmjs8dLdj3/V0zxwNzku/7BEFAGIZjC4JgMfKmtFIKKSVSStq2RSk1kQ/gXyEtHccxSZKw2WzYbDbEcTzKL0FcSwshqOuaqqqo65qmaei6DqUUwFQ8DEOSJCFNU15fX0nTlN1uRxzHrFarWde8ruO+7xFCUFUV39/fXC4XsiybjAMEZm2HYch2u+Xt7Y2Pjw+OxyNpmpIkCWEYjpf8XBmGga7ruF6v5HnO6XQiDEOUUrRti5QSpRRKqecrfjwe+fz85HA4sNvtiKJo9pd73/dIKanrmvP5TBzHSCkpy5KiKLher0gp8TzvcY1vt1vSNOVwOPD+/s5+v2e9Xi9CvG1bqqoiiiKapuF8PpMkCVEUjeUKT+7q+ga32+3Y7/e8vLxM6nyO6Ppt25YgCKjrmiRJ7m7Od+L6oO/7rFYrwjAkiiLiOCaOY9br9SLEfd9HCDF5DOsbm/kiE9z+gJY3/wSzzVncPPdhGFBK0XXd+Bjr+/65uEZfAY/aEuj7fhTWn+Yr7LyfT/8D83mtX2Z037zUf5043Nf0bX3DLxXXPBLW/GrxP+HEbcOJ24YTtw0nbhtO3DacuG04cdtw4rbhxG3DiduGE7cNJ24bTtw2nLhtOHHbcOK24cRtw4nbhhO3DSduG07cNpy4bThx23DituHEbcOJ24YTtw1rxZ/uLf3bTr258V/P905c78s0gyZ0g/kmg+jdw7qZDo/+gMCcaMrqGBEhBEIIgNlvo9ZpIEKISSbE7YZauFlxvfVYR4kURUGe5wCzj0rQi9Y0DXmeUxQFdV0jhKDrujENRBOYk7R0WZZkWcbpdALg5+dn9uEYZlRCURScTieyLKMsy4n8ZOO8nqQTNbIs4+vrC4A8zxcTh/LIIcsy6rpGSjkV1xEDelJZlpzPZ4ZhoKqqxQXg6DovioIsy7hcLpRlOYrr7z5ccQAhBHmeLzLySJdsVVVj5NHtio+xZmYWzG8Iueq6bgy5klLe1fhEHOyJNbM2yO5OfBxYqPAtz15b/wHsvBSUT5t0gwAAAABJRU5ErkJggg==" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3256-0" + clipPathUnits="userSpaceOnUse"><path + id="path3258-5" + d="m 1107,579 62,0 0,-84 -62,0 0,84 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3252-1" + clipPathUnits="userSpaceOnUse"><path + id="path3254-3" + d="m 1107,579 62,0 0,-84 -62,0 0,84 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3226-6" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3228-8" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABUCAAAAAD/xdukAAAAAXNCSVQI5gpbmQAAAZZJREFUWIXt2L1u3DAQBOBZijoZsg9GLikMO03e/72MK85CLvrxUeTuuJCCJB0lA6m4tT4tl6x2BAAAwdbiHycC2fYDEuTCBc455zacgDAzMxAegPN1Xft8T5jGOKuBHuJ8097fN95lc9MwjdMtKTzE1e3p6+nYVJnzkxbGn28dafACVz98+/58amuX2z29X8+1zlF17f784+l4yD29xenSxKF/j7LM/nB6enm8y+bzeLhd2kMl68037fHxS1Nlzm6zn9rGOxF4QMRV9aFp7rK5C96B5PLuECeuqqpcLk6oKamtHJClsjgAWNKkBHMf69/+NFMzErs4uBR2coAksJ+vVXjhhRdeeOGFF1544YUXXvh/5usO+3srzKm/v/UAQKOpamZ0QlU1GldOmsY5BOQu4BrCHNXIpbulMPVX5IYPtNu1n0IyAB60FIbujF+50Qdt7s/dEJIRHrQ4da+45gcvFqfutZuiEZ5icbhw3BL7aOi7tyEauHRHuG4KnVIYxykaIYDsiLxSjDGt/BOB2+fjPmB/2PgBJp8FYb3sImYAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><mask + id="mask3214-5" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3216-2"><g + id="g3218-9" + clip-path="url(#clipPath3210-9)"><g + id="g3220-8"><g + id="g3222-2" + transform="matrix(62,0,0,84,1049,495)"><image + id="image3224-4" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABUCAYAAADaroR4AAAABHNCSVQICAgIfAhkiAAAA1pJREFUeJztnMtuqzoYRheES0QSRaUdRGknff/3qjJIUCmXYIzhDI6MTC5765wR1F6SFQvHESvmByb+PGDgAZ7nPTq8OIbhoR4eN+Ke543SZn9pDMMwSpt9TaA7WtD3/btmjs8dLdj3/V0zxwNzku/7BEFAGIZjC4JgMfKmtFIKKSVSStq2RSk1kQ/gXyEtHccxSZKw2WzYbDbEcTzKL0FcSwshqOuaqqqo65qmaei6DqUUwFQ8DEOSJCFNU15fX0nTlN1uRxzHrFarWde8ruO+7xFCUFUV39/fXC4XsiybjAMEZm2HYch2u+Xt7Y2Pjw+OxyNpmpIkCWEYjpf8XBmGga7ruF6v5HnO6XQiDEOUUrRti5QSpRRKqecrfjwe+fz85HA4sNvtiKJo9pd73/dIKanrmvP5TBzHSCkpy5KiKLher0gp8TzvcY1vt1vSNOVwOPD+/s5+v2e9Xi9CvG1bqqoiiiKapuF8PpMkCVEUjeUKT+7q+ga32+3Y7/e8vLxM6nyO6Ppt25YgCKjrmiRJ7m7Od+L6oO/7rFYrwjAkiiLiOCaOY9br9SLEfd9HCDF5DOsbm/kiE9z+gJY3/wSzzVncPPdhGFBK0XXd+Bjr+/65uEZfAY/aEuj7fhTWn+Yr7LyfT/8D83mtX2Z037zUf5043Nf0bX3DLxXXPBLW/GrxP+HEbcOJ24YTtw0nbhtO3DacuG04cdtw4rbhxG3DiduGE7cNJ24bTtw2nLhtOHHbcOK24cRtw4nbhhO3DSduG07cNpy4bThx23DituHEbcOJ24YTtw1rxZ/uLf3bTr258V/P905c78s0gyZ0g/kmg+jdw7qZDo/+gMCcaMrqGBEhBEIIgNlvo9ZpIEKISSbE7YZauFlxvfVYR4kURUGe5wCzj0rQi9Y0DXmeUxQFdV0jhKDrujENRBOYk7R0WZZkWcbpdALg5+dn9uEYZlRCURScTieyLKMsy4n8ZOO8nqQTNbIs4+vrC4A8zxcTh/LIIcsy6rpGSjkV1xEDelJZlpzPZ4ZhoKqqxQXg6DovioIsy7hcLpRlOYrr7z5ccQAhBHmeLzLySJdsVVVj5NHtio+xZmYWzG8Iueq6bgy5klLe1fhEHOyJNbM2yO5OfBxYqPAtz15b/wHsvBSUT5t0gwAAAABJRU5ErkJggg==" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3210-9" + clipPathUnits="userSpaceOnUse"><path + id="path3212-3" + d="m 1049,579 62,0 0,-84 -62,0 0,84 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3206-7" + clipPathUnits="userSpaceOnUse"><path + id="path3208-1" + d="m 1049,579 62,0 0,-84 -62,0 0,84 z" + inkscape:connector-curvature="0" /></clipPath><mask + id="mask3180-7" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3182-1" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABUCAAAAAD/xdukAAAAAXNCSVQI5gpbmQAAAZZJREFUWIXt2L1u3DAQBOBZijoZsg9GLikMO03e/72MK85CLvrxUeTuuJCCJB0lA6m4tT4tl6x2BAAAwdbiHycC2fYDEuTCBc455zacgDAzMxAegPN1Xft8T5jGOKuBHuJ8097fN95lc9MwjdMtKTzE1e3p6+nYVJnzkxbGn28dafACVz98+/58amuX2z29X8+1zlF17f784+l4yD29xenSxKF/j7LM/nB6enm8y+bzeLhd2kMl68037fHxS1Nlzm6zn9rGOxF4QMRV9aFp7rK5C96B5PLuECeuqqpcLk6oKamtHJClsjgAWNKkBHMf69/+NFMzErs4uBR2coAksJ+vVXjhhRdeeOGFF1544YUXXvh/5usO+3srzKm/v/UAQKOpamZ0QlU1GldOmsY5BOQu4BrCHNXIpbulMPVX5IYPtNu1n0IyAB60FIbujF+50Qdt7s/dEJIRHrQ4da+45gcvFqfutZuiEZ5icbhw3BL7aOi7tyEauHRHuG4KnVIYxykaIYDsiLxSjDGt/BOB2+fjPmB/2PgBJp8FYb3sImYAAAAASUVORK5CYII=" + height="1" + width="1" /></mask><mask + id="mask3168-6" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3170-1"><g + id="g3172-4" + clip-path="url(#clipPath3164-3)"><g + id="g3174-6"><g + id="g3176-0" + transform="matrix(62,0,0,84,991,495)"><image + id="image3178-0" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABUCAYAAADaroR4AAAABHNCSVQICAgIfAhkiAAAA1pJREFUeJztnMtuqzoYRheES0QSRaUdRGknff/3qjJIUCmXYIzhDI6MTC5765wR1F6SFQvHESvmByb+PGDgAZ7nPTq8OIbhoR4eN+Ke543SZn9pDMMwSpt9TaA7WtD3/btmjs8dLdj3/V0zxwNzku/7BEFAGIZjC4JgMfKmtFIKKSVSStq2RSk1kQ/gXyEtHccxSZKw2WzYbDbEcTzKL0FcSwshqOuaqqqo65qmaei6DqUUwFQ8DEOSJCFNU15fX0nTlN1uRxzHrFarWde8ruO+7xFCUFUV39/fXC4XsiybjAMEZm2HYch2u+Xt7Y2Pjw+OxyNpmpIkCWEYjpf8XBmGga7ruF6v5HnO6XQiDEOUUrRti5QSpRRKqecrfjwe+fz85HA4sNvtiKJo9pd73/dIKanrmvP5TBzHSCkpy5KiKLher0gp8TzvcY1vt1vSNOVwOPD+/s5+v2e9Xi9CvG1bqqoiiiKapuF8PpMkCVEUjeUKT+7q+ga32+3Y7/e8vLxM6nyO6Ppt25YgCKjrmiRJ7m7Od+L6oO/7rFYrwjAkiiLiOCaOY9br9SLEfd9HCDF5DOsbm/kiE9z+gJY3/wSzzVncPPdhGFBK0XXd+Bjr+/65uEZfAY/aEuj7fhTWn+Yr7LyfT/8D83mtX2Z037zUf5043Nf0bX3DLxXXPBLW/GrxP+HEbcOJ24YTtw0nbhtO3DacuG04cdtw4rbhxG3DiduGE7cNJ24bTtw2nLhtOHHbcOK24cRtw4nbhhO3DSduG07cNpy4bThx23DituHEbcOJ24YTtw1rxZ/uLf3bTr258V/P905c78s0gyZ0g/kmg+jdw7qZDo/+gMCcaMrqGBEhBEIIgNlvo9ZpIEKISSbE7YZauFlxvfVYR4kURUGe5wCzj0rQi9Y0DXmeUxQFdV0jhKDrujENRBOYk7R0WZZkWcbpdALg5+dn9uEYZlRCURScTieyLKMsy4n8ZOO8nqQTNbIs4+vrC4A8zxcTh/LIIcsy6rpGSjkV1xEDelJZlpzPZ4ZhoKqqxQXg6DovioIsy7hcLpRlOYrr7z5ccQAhBHmeLzLySJdsVVVj5NHtio+xZmYWzG8Iueq6bgy5klLe1fhEHOyJNbM2yO5OfBxYqPAtz15b/wHsvBSUT5t0gwAAAABJRU5ErkJggg==" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3164-3" + clipPathUnits="userSpaceOnUse"><path + id="path3166-1" + d="m 991,579 62,0 0,-84 -62,0 0,84 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3160-9" + clipPathUnits="userSpaceOnUse"><path + id="path3162-3" + d="m 991,579 62,0 0,-84 -62,0 0,84 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3152-4" + clipPathUnits="userSpaceOnUse"><path + id="path3154-4" + d="m 897,482 239.999,0 0,135 -239.999,0 0,-135 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3126-1" + clipPathUnits="userSpaceOnUse"><path + id="path3128-0" + d="m 887,628 270,0 0,-182 -270,0 0,182 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3118-8" + clipPathUnits="userSpaceOnUse"><path + id="path3120-5" + d="m 0,1080 1920,0 L 1920,0 0,0 0,1080 z" + inkscape:connector-curvature="0" /></clipPath><clipPath + id="clipPath3722-1-6" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3724-4-6" + d="m 652,532 12.002,0 0,-12 -12.002,0 0,12 z" /></clipPath><clipPath + id="clipPath3726-6-9" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3728-1-7" + d="m 652.002,520.002 12,0 0,11.998 -12,0 0,-11.998 z" /></clipPath><clipPath + id="clipPath3696-9-7" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3698-6-3" + d="m 592,530.865 32,0 0,-12.002 -32,0 0,12.002 z" /></clipPath><clipPath + id="clipPath3700-1-1" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3702-8-2" + d="m 592,518.865 32,0 0,12 -32,0 0,-12 z" /></clipPath><clipPath + id="clipPath3696-9-7-9" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3698-6-3-5" + d="m 592,530.865 32,0 0,-12.002 -32,0 0,12.002 z" /></clipPath><clipPath + id="clipPath3700-1-1-8" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3702-8-2-6" + d="m 592,518.865 32,0 0,12 -32,0 0,-12 z" /></clipPath><clipPath + id="clipPath3722-1-6-1" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3724-4-6-5" + d="m 652,532 12.002,0 0,-12 -12.002,0 0,12 z" /></clipPath><clipPath + id="clipPath3726-6-9-4" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3728-1-7-6" + d="m 652.002,520.002 12,0 0,11.998 -12,0 0,-11.998 z" /></clipPath><clipPath + id="clipPath3086-4-0"><path + inkscape:connector-curvature="0" + d="m 1058,722 374,0 0,-374 -374,0 0,374 z" + id="path3088-8-7" /></clipPath><clipPath + id="clipPath3100-8-2"><path + inkscape:connector-curvature="0" + d="m 1029,344 432,0 0,-32 -432,0 0,32 z" + id="path3102-2-9" /></clipPath><clipPath + id="clipPath3116-4-9"><path + inkscape:connector-curvature="0" + d="m 1029,756 432,0 0,-32 -432,0 0,32 z" + id="path3118-5-1" /></clipPath><clipPath + id="clipPath3592-5-68" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3594-9-1" + d="m 730.778,549 12,0 0,-12 -12,0 0,12 z" /></clipPath><clipPath + id="clipPath3566-8-9" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3568-8-22" + d="m 679,547.865 32,0 0,-12.002 -32,0 0,12.002 z" /></clipPath><clipPath + id="clipPath3570-6-4" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3572-0-00" + d="m 679,535.865 32,0 0,12 -32,0 0,-12 z" /></clipPath><clipPath + id="clipPath3520-6-4" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3522-3-32" + d="m 667,561 93,0 0,-68 -93,0 0,68 z" /></clipPath><mask + id="mask3528-3-5" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><g + id="g3530-7-3"><g + id="g3532-3-5" + clip-path="url(#clipPath3524-5-2)"><g + id="g3534-0-0"><g + id="g3536-4-5" + transform="matrix(93,0,0,68,667,493)"><image + id="image3538-4-00" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAYAAADjqDmQAAAABHNCSVQICAgIfAhkiAAAA51JREFUeJztnEtv4koQRo/BpokBoThZIJJN/v/vCkoUYuSAbYwfPYu57duOzWPm3lEvpo5UwqLbXhyXihaLzwM0A3ieN/S1cCNaD2oFwOObdM/zWuH2tXAbWutWuH1t45sLI3c0GvXKXheGMXKbpumVvQ6WdPgp3Pd9giBoy/d9EX8FW3hd15RlSVmWnE4n6rruiffhp0wjXClFGIbMZjNmsxlKqVa8SB9Ga90KL4qCLMvIsow0TTkej1RVRV3X7f6O9CAICMOQKIp4eHggiiIWiwVKKcbjscz4AczcbpqG0+lEmqbsdjviOGY0GrXrZo/WGt+e5UEQMJ/PeXx85Pn5mfV6TRRFhGFIEATtmBG6aK2pqorj8UiSJLy/v6OUomkayrK8vdPX6zUvLy+sVisWiwWTyURGzBmapqGqKvI8J45jwjBEa02e5+2IKcvy306H/kyfz+dEUcRqteLp6Ynlcsl0OhXpZzDSsyxjNpvRNA37/Z7tdst2u22nhBnPg6cX82O6WCxYLpfc39935rrQxYyX6XQKwH6/Z7lcMp/PW2/2aO6c003Hj8djgiBgMpmglEIpxXQ6FelnMNIB8jwnDEPu7u5QShEEQe8Q4n9/gBFvvwC7RHofc/42zer7flv2WDH0pBvMxqES+pgmtctuYBs5A/4BrjWoSHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASHeASP8D2GlGQ5zNBrBvvPaQvx07LsouO0LKpifd3mjCwEyBJNYNYaJHTFJdVVVtGZeDEYH22zI3n04niqKgKAoAiR45g5GeZRl5nrefRVFQliV1XXfEdzrdxCKZmLv9fk+SJAASJ3UBO07q8/OTOI5JkoTD4UBRFJ1sRvhHuulwI/xwOBDHMW9vbwB8fX1JcNoFvgenvb6+8vHxQZIk5HneCU1rg9OM9LIsybKMOI7ZbDYAJEkiEYFXGIoI3Gw2xHFMmqYd6QC+1hrP81rph8OB7XaL1po0TSUM8wqXwjB3ux15nlNVVf+H9HunAxRFQZIkEvt6A5diX+2ZbsS3Ud52NqMEHP8atwQc26eXjnSQKO/f5VeivCW0/n/mltD6nvR2QWT/Jy79ZfIDbR7YvKqk0OoAAAAASUVORK5CYII=" + transform="matrix(1,0,0,-1,0,1)" + height="1" + width="1" /></g></g></g></g></mask><clipPath + id="clipPath3524-5-2" + clipPathUnits="userSpaceOnUse"><path + inkscape:connector-curvature="0" + id="path3526-4-1" + d="m 667,561 93,0 0,-68 -93,0 0,68 z" /></clipPath><mask + id="mask3540-4-88" + height="1" + width="1" + y="0" + x="0" + maskUnits="userSpaceOnUse"><image + id="image3542-1-5" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAAAAADGw2ZMAAAAAXNCSVQI5gpbmQAAAZJJREFUWIXt2DFv2zAQhuHvTlTkyDaMuBmCtEv//+9q0KKuAtWWZJnkfR0UAwY69jyVXAhoeEQcyOUVAAAEvos3rAjE0ydBfugCVVV1Oz9hZmYgEABoqOs6ePGE5Rgv2UAEiIamXa+boE665Xkch3PKQIBo3e4/7bdN5TJ70i7De6ckjUGg9eb5y+u+rdUBB5jO/Y/G4s3ZX7++bB98RmNp6lpOwzkal7lv9i+fdysvfVzb8XCoVWS5M0273T01lYvOtMJxt2kqBQIgolX90DQrLx1T+9jUlQgCAIiKVlXlpKOqQwgqsrwmALIsDx2iqioqAHxu4V8/+DjoffTrKnrRi170ohe96EUvetGLXvSiF/3/0bkkvWsnIHn98u+ymRmNV51Gyzn7RD2mHFNKxqUYkpbjZZ7h1WfGaZzmmEkEAJbm8djDr1z96vrTnA0IoKX51H3Hb8fq9u1nP0UjA2hx7N7QuxbDt26IRgSKxdOBg3PtfJ8Sl8nEEXPvXWrnbIQAcqfKTN65kN+97t9sfv6y/QG64fFP78GtbgAAAABJRU5ErkJggg==" + height="1" + width="1" /></mask></defs><g + inkscape:groupmode="layer" + id="layer8" + inkscape:label="Layer5" + transform="translate(436.0495,72.4457)"><g + style="display:inline" + id="g3508-5-64" + transform="matrix(5.09,0,0,-5.09,-201.82504,927.02677)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + inkscape:connector-curvature="0" + d="m 0,0 c -2.209,0 -4,1.791 -4,4 l 0,92 c 0,2.209 1.791,4 4,4 l 92,0 c 2.209,0 4,-1.791 4,-4 L 96,4 C 96,1.791 94.209,0 92,0 L 0,0 z" + style="fill:#4fbdee;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3510-0-3" /></g><g + style="display:inline" + id="g3516-7-0" + transform="matrix(5.09,0,0,-5.09,-3586.6755,3426.2166)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3518-2-5" /><g + id="g3544-9-2"><g + style="opacity:0.119995" + clip-path="url(#clipPath3520-6-4)" + id="g3546-7-5"><g + id="g3548-8-3"><g + id="g3550-3-8" /><g + mask="url(#mask3528-3-5)" + id="g3552-8-72"><g + transform="matrix(93,0,0,68,667,493)" + id="g3554-9-8"><image + width="1" + height="1" + transform="matrix(1,0,0,-1,0,1)" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAYAAADjqDmQAAAABHNCSVQICAgIfAhkiAAAAP1JREFUeJzt3DGKhEAARcFWvP+VeyNBxJGFHX3BVmU2BvL4DBP1Muec48KyLFfH/NKHrGOMMbbzgdjfsXe8ir+dX+K7ruKv1cf8N8dRr+cDnmfpL9rHvVr5+yw9sIwxPv+h5BGWHhA9IHpA9IDoAdEDogdED4geED0gekD0gOgB0QOiB0QPiB4QPSB6QPSA6AHRA6IHRA+IHhA9IHpA9IDoAdEDogdED4geED0gekD0gOgB0QOiB0QPiB4QPSB6QPSA6AHRA6IHRA+IHhA9IHpA9JfNOUUvrHe3H/MMS3/RPvD1+MA7LP0lx2Fv50N3737X7aX155fE/5u7n+wfv04ph+lQnM8AAAAASUVORK5CYII=" + mask="url(#mask3540-4-88)" + id="image3556-9-3" /></g></g></g></g></g></g><g + style="display:inline" + id="g3558-6-1" + transform="matrix(5.09,0,0,-5.09,235.91496,860.85677)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + inkscape:connector-curvature="0" + d="m 0,0 c 0,-1.65 -1.35,-3 -3,-3 l -74,0 c -1.649,0 -3,1.35 -3,3 l 0,50 c 0,1.65 1.351,3 3,3 l 74,0 c 1.65,0 3,-1.35 3,-3 L 0,0 z" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3560-5-6" /></g><g + style="display:inline" + id="g3562-4-0" + transform="matrix(5.09,0,0,-5.09,-3586.6755,3426.2166)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3564-6-3" /><g + id="g3574-7-9"><g + style="opacity:0.5" + clip-path="url(#clipPath3566-8-9)" + id="g3576-7-8"><g + id="g3578-2-9"><g + clip-path="url(#clipPath3570-6-4)" + id="g3580-1-9"><path + inkscape:connector-curvature="0" + d="m 710.994,535.863 -31.988,0 0,12.002 31.988,0 0,-12.002 z" + style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3582-0-16" /></g></g></g></g></g><path + inkscape:connector-curvature="0" + d="m 123.93496,748.87677 -254.5,0 0,-25.45 254.5,0 0,25.45 z" + style="fill:#d1d2d3;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + id="path3584-1-9" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999" /><path + inkscape:connector-curvature="0" + d="m 6.8649591,799.77677 -137.4299991,0 0,-25.45 137.4299991,0 0,25.45 z" + style="fill:#d1d2d3;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + id="path3586-5-0" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999" /><g + style="display:inline" + id="g3588-5-0" + transform="matrix(5.09,0,0,-5.09,-3586.6755,3426.2166)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3590-3-9" /><g + id="g3596-7-2"><g + style="opacity:0" + clip-path="url(#clipPath3592-5-68)" + id="g3598-6-5"><path + inkscape:connector-curvature="0" + d="m 730.777,537 12,0 0,12 -12,0 0,-12 z" + style="fill:#03a9f4;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3600-8-1" /></g></g></g><g + style="display:inline" + id="g3602-7-0" + transform="matrix(5.09,0,0,-5.09,188.97176,661.07427)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + inkscape:connector-curvature="0" + d="m 0,0 c 0,0.414 -0.336,0.75 -0.75,0.75 l -2.75,0 -2.5,4 -1,0 1.25,-4 -2.75,0 -0.75,1 -0.75,0 0.5,-1.75 -0.5,-1.75 0.75,0 0.75,1 2.75,0 -1.25,-4 1,0 2.5,4 2.75,0 C -0.336,-0.75 0,-0.414 0,0" + style="fill:#00c853;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3604-3-8" /></g><g + transform="matrix(1.25,0,0,-1.25,-1884.887,1349.9021)" + id="g3012-8" + style="display:inline" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + transform="translate(1677.8121,922.30928)" + id="g3072-5" + style="fill:#333333;fill-opacity:1"><path + inkscape:connector-curvature="0" + d="m 0,0 -285.486,0 -14,-190.491 313.486,0 L 0,0 z" + id="path3074-5" + style="fill:#101010;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><g + transform="translate(1691.8121,352.84148)" + id="g3076-9" + style="fill:#333333;fill-opacity:1"><path + inkscape:connector-curvature="0" + d="m 0,0 -313.486,0 14,-190.491 286.486,0 L 0,0 z" + id="path3078-3" + style="fill:#101010;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><path + inkscape:connector-curvature="0" + d="m 1721.07,355.32978 -374,0 0,374 374,0 0,-374 z m 3.332,409 -378.666,0 c -14.729,0 -26.666,-11.938 -26.666,-26.667 l 0,-5.333 0,-380 0,-5.334 c 0,-14.727 11.937,-26.666 26.666,-26.666 l 378.666,0 c 14.729,0 26.668,11.939 26.668,26.666 l 0,5.334 0,380 0,5.333 c 0,14.729 -11.939,26.667 -26.668,26.667" + id="path3080-4" + style="fill:#101010;fill-opacity:1;fill-rule:nonzero;stroke:none" /><g + transform="translate(290.06807,8.3297801)" + id="g3082-3"><g + id="g3084-9" /><g + id="g3090-2"><g + clip-path="url(#clipPath3086-4-0)" + id="g3092-8" + style="opacity:0.10000598"><path + inkscape:connector-curvature="0" + d="m 1432.002,722 -374,0 0,-374 374,0 0,374 z m -3,-371 -368,0 0,368 368,0 0,-368 z" + id="path3094-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g><g + transform="translate(290.06807,8.3297801)" + id="g3096-6"><g + id="g3098-6" /><g + id="g3104-5"><g + clip-path="url(#clipPath3100-8-2)" + id="g3106-9" + style="opacity:0.10000598"><g + transform="translate(1434.334,317.334)" + id="g3108-9"><path + inkscape:connector-curvature="0" + d="m 0,0 -378.666,0 c -14.729,0 -26.666,11.938 -26.666,26.666 l 0,-5.334 c 0,-14.727 11.937,-26.666 26.666,-26.666 L 0,-5.334 c 14.729,0 26.668,11.939 26.668,26.666 l 0,5.334 C 26.668,11.938 14.729,0 0,0" + id="path3110-8" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g><g + transform="translate(290.06807,8.3297801)" + id="g3112-1"><g + id="g3114-5" /><g + id="g3120-7"><g + clip-path="url(#clipPath3116-4-9)" + id="g3122-5" + style="opacity:0.10000598"><g + transform="translate(1434.334,756)" + id="g3124-1"><path + inkscape:connector-curvature="0" + d="m 0,0 -378.666,0 c -14.729,0 -26.666,-11.938 -26.666,-26.667 l 0,-5.333 c 0,14.728 11.937,26.667 26.666,26.667 L 0,-5.333 c 14.729,0 26.668,-11.939 26.668,-26.667 l 0,5.333 C 26.668,-11.938 14.729,0 0,0" + id="path3126-0" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g></g></g><g + inkscape:groupmode="layer" + id="layer7" + inkscape:label="Layer4" + style="display:inline" + transform="translate(436.0495,72.4457)"><g + style="display:inline" + id="g3622-5-8" + transform="matrix(5.2235991,0,0,-5.1937884,507.13047,984.15494)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + inkscape:connector-curvature="0" + d="m 0,0 c -32.947,0 -59.75,26.804 -59.75,59.75 0,32.946 26.803,59.75 59.75,59.75 32.945,0 59.75,-26.804 59.75,-59.75 C 59.75,26.804 32.945,0 0,0" + style="fill:#ff4a3c;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3624-3-9" /></g><g + style="display:inline" + id="g3630-4-7" + transform="matrix(5.2235991,0,0,-5.1937884,-2762.8426,3436.9216)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3632-0-4" + clip-path="url(#clipPath3634-8-0)"><g + id="g3638-2-4"><g + id="g3640-4-1" /><g + id="g3666-9-6"><g + style="opacity:0.119995" + clip-path="url(#clipPath3642-3-4)" + id="g3668-8-7"><g + id="g3670-0-5"><g + id="g3672-4-4" /><g + mask="url(#mask3650-5-0)" + id="g3674-2-0"><g + transform="matrix(139.35082,0,0,78.633677,558.31445,465.31115)" + id="g3676-6-2"><image + width="1" + height="1" + transform="matrix(1,0,0,-1,0,1)" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAABPCAYAAAA5vC0kAAAABHNCSVQICAgIfAhkiAAAASdJREFUeJzt1rFuwyAUQFGw/P+/TIfKamQ5be7kRjlnshEDw9WDudZa48Kc82qZD/Eki7GfF4TCGD8dnMPZzxvg0Tmc7c7D8D6OcLbHH/iLCcPL5pxjjjGun8NwwYQhEQyJYEgEQyIYEsGQCIZEMCSCIREMiWBIBEMiGBLBkAiGRDAkgiERDIlgSARDIhgSwZAIhkQwJIIhEQyJYEgEQyIYEsGQCIZEMCSCIREMiWBIBEMiGBLBkAiGRDAkgiERDIlgSARDIhgSwZAIhkQwJIIhEQyJYEgEQyIYEsGQCIZEMCSCIREMiWBIBEMiGBLBkAiGRDAkgiERDMm21rr7DLyJtZYJQ7ON8V0O/OZoxIQh2Y+Po6A5522H4f853z77sw3C+WzPnilfB04mnX6avLgAAAAASUVORK5CYII=" + mask="url(#mask3662-9-4)" + id="image3678-1-3" /></g></g></g></g></g></g><g + id="g3680-5-3" + transform="translate(689.7031,476.2588)"><path + inkscape:connector-curvature="0" + d="m 0,0 c 0,-1.642 -1.344,-2.984 -2.986,-2.984 l -121.434,0 c -1.643,0 -2.986,1.342 -2.986,2.984 l 0,60.719 c 0,1.641 1.343,2.985 2.986,2.985 l 121.434,0 C -1.344,63.704 0,62.36 0,60.719 L 0,0 z" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3682-6-2" /></g></g></g><g + id="layer3" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + transform="matrix(1.25,0,0,-1.25,715.58308,453.4259)" + id="g3024-4" + style="fill:#000000;display:inline"><path + inkscape:connector-curvature="0" + d="m 0,0 -12.195,205.05 -307.49,0 L -331.88,0 c 44.595,34.886 102.563,58.974 165.94,58.974 C -102.563,58.974 -44.595,34.886 0,0" + id="path3026-3" + style="fill:#2e2e2e;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><g + transform="matrix(1.25,0,0,-1.25,300.90228,894.5124)" + id="g3028-0" + style="fill:#000000;display:inline"><path + inkscape:connector-curvature="0" + d="m 0,0 12.06,-202.039 307.49,0 L 331.609,0 C 287.033,-34.822 229.119,-58.869 165.805,-58.869 102.491,-58.869 44.576,-34.822 0,0" + id="path3030-8" + style="fill:#2e2e2e;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><g + transform="matrix(1.25,0,0,-1.25,456.87948,388.9154)" + id="g3032-2" + style="display:inline"><path + inkscape:connector-curvature="0" + d="m 0,0 c 5.706,1.02 11.485,1.83 17.328,2.423 3.895,0.395 7.819,0.694 11.769,0.895 3.95,0.2 7.926,0.301 11.926,0.301 4,0 7.976,-0.101 11.926,-0.301 3.95,-0.201 7.874,-0.5 11.77,-0.895 C 70.561,1.83 76.341,1.02 82.047,0 c 108.425,-19.367 190.726,-114.139 190.726,-228.132 0,-127.991 -103.756,-231.75 -231.75,-231.75 -127.99,0 -231.751,103.759 -231.751,231.75 0,113.993 82.305,208.765 190.728,228.132 m 41.023,26.794 c -140.792,0 -254.926,-114.133 -254.926,-254.926 0,-140.792 114.134,-254.926 254.926,-254.926 140.79,0 254.926,114.134 254.926,254.926 0,140.793 -114.136,254.926 -254.926,254.926" + id="path3034-1" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><g + transform="matrix(1.25,0,0,-1.25,508.15818,355.4224)" + id="g3036-8" + style="fill:#000000;display:inline"><path + inkscape:connector-curvature="0" + d="m 0,0 c -140.792,0 -254.926,-114.134 -254.926,-254.926 0,-140.792 114.134,-254.926 254.926,-254.926 140.792,0 254.926,114.134 254.926,254.926 C 254.926,-114.134 140.792,0 0,0 m 231.75,-254.926 c 0,-127.991 -103.758,-231.75 -231.75,-231.75 -127.992,0 -231.75,103.759 -231.75,231.75 0,127.993 103.758,231.751 231.75,231.751 127.992,0 231.75,-103.758 231.75,-231.751" + id="path3038-3" + style="fill:#2c2c2c;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><g + transform="matrix(1.25,0,0,-1.25,-264.34372,1339.588)" + id="g3040-9" + style="display:inline"><g + id="g3042-1" /><g + id="g3048-2"><g + clip-path="url(#clipPath3044-8-3-2)" + id="g3050-4" + style="opacity:0.10000598"><g + transform="translate(844.249,532.4062)" + id="g3052-7"><path + inkscape:connector-curvature="0" + d="m 0,0 c 0,-124.952 -101.295,-226.248 -226.248,-226.248 -124.952,0 -226.247,101.296 -226.247,226.248 0,124.953 101.295,226.248 226.247,226.248 C -101.295,226.248 0,124.953 0,0" + id="path3054-5" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g><g + transform="matrix(1.25,0,0,-1.25,-264.34372,1339.588)" + id="g3056-2" + style="display:inline"><g + id="g3058-6" /><g + id="g3064-1"><g + clip-path="url(#clipPath3060-8-2-1)" + id="g3066-2" + style="opacity:0.10000598"><g + transform="translate(618.0015,787.7266)" + id="g3068-5"><path + inkscape:connector-curvature="0" + d="m 0,0 c -34.466,0 -67.903,-6.75 -99.383,-20.065 -30.404,-12.861 -57.707,-31.269 -81.155,-54.716 -23.446,-23.447 -41.856,-50.752 -54.715,-81.156 -13.314,-31.48 -20.066,-64.916 -20.066,-99.383 0,-34.465 6.752,-67.904 20.066,-99.381 12.859,-30.405 31.269,-57.709 54.715,-81.156 23.448,-23.447 50.751,-41.857 81.155,-54.715 31.48,-13.315 64.917,-20.066 99.383,-20.066 34.466,0 67.903,6.751 99.382,20.066 30.405,12.858 57.708,31.268 81.155,54.715 23.447,23.447 41.857,50.751 54.716,81.156 13.314,31.477 20.066,64.916 20.066,99.381 0,34.467 -6.752,67.903 -20.066,99.383 -12.859,30.404 -31.269,57.709 -54.716,81.156 -23.447,23.447 -50.75,41.855 -81.155,54.716 C 67.903,-6.75 34.466,0 0,0 m 0,-3.153 c 139.268,0 252.167,-112.897 252.167,-252.167 0,-139.267 -112.899,-252.166 -252.167,-252.166 -139.268,0 -252.167,112.899 -252.167,252.166 0,139.27 112.899,252.167 252.167,252.167" + id="path3070-2" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g></g><g + style="display:inline" + id="g3692-7-8" + transform="matrix(5.2956158,0,0,-5.2956158,-2815.7539,3491.418)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3694-5-3" /><g + id="g3704-5-3"><g + clip-path="url(#clipPath3696-9-7-9)" + id="g3706-2-5" + style="opacity:0.5"><g + id="g3708-6-9"><g + clip-path="url(#clipPath3700-1-1-8)" + id="g3710-3-0"><path + d="m 623.994,518.863 -31.988,0 0,12.002 31.988,0 0,-12.002 z" + style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3712-4-5" + inkscape:connector-curvature="0" /></g></g></g></g></g><path + d="m 584.03152,795.94967 -264.78075,0 0,-26.47808 264.78075,0 0,26.47808 z" + style="fill:#d1d2d3;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + id="path3714-2-5" + inkscape:connector-curvature="0" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999" /><path + d="m 462.23242,848.90583 -142.98165,0 0,-26.47808 142.98165,0 0,26.47808 z" + style="fill:#d1d2d3;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + id="path3716-3-1" + inkscape:connector-curvature="0" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999" /><g + style="display:inline" + id="g3718-7-1" + transform="matrix(5.2956158,0,0,-5.2956158,-2815.7539,3491.418)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3720-1-0" /><g + id="g3730-8-4"><g + clip-path="url(#clipPath3722-1-6-1)" + id="g3732-8-4" + style="opacity:0"><g + id="g3734-9-2"><g + clip-path="url(#clipPath3726-6-9-4)" + id="g3736-3-3"><path + d="m 664.001,520 -12.001,0 0,12 12.001,0 0,-12 z" + style="fill:#ee2a7b;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3738-7-6" + inkscape:connector-curvature="0" /></g></g></g></g></g><g + style="display:inline" + id="g3740-9-7" + transform="matrix(5.2956158,0,0,-5.2956158,644.93112,705.35546)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + d="m 0,0 4.5,0 0,-4.501 0.501,0 4,9.001 L 0,0.501 0,0 z" + style="fill:#03a9f4;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3742-8-7" + inkscape:connector-curvature="0" /></g></g><g + inkscape:groupmode="layer" + id="layer6" + inkscape:label="Layer3" + style="display:inline" + transform="translate(436.0495,72.4457)"><g + style="display:inline" + id="g3508-5-6" + transform="matrix(5.09,0,0,-5.09,742.55563,925.70096)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + inkscape:connector-curvature="0" + d="m 0,0 c -2.209,0 -4,1.791 -4,4 l 0,92 c 0,2.209 1.791,4 4,4 l 92,0 c 2.209,0 4,-1.791 4,-4 L 96,4 C 96,1.791 94.209,0 92,0 L 0,0 z" + style="fill:#9d65dc;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3510-0-8" /></g><g + style="display:inline" + id="g3516-7-9" + transform="matrix(5.09,0,0,-5.09,-2642.2948,3424.8908)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3518-2-7" /><g + id="g3544-9-6"><g + style="opacity:0.119995" + clip-path="url(#clipPath3520-6-0)" + id="g3546-7-3"><g + id="g3548-8-7"><g + id="g3550-3-6" /><g + mask="url(#mask3528-3-8)" + id="g3552-8-7"><g + transform="matrix(93,0,0,68,667,493)" + id="g3554-9-9"><image + width="1" + height="1" + transform="matrix(1,0,0,-1,0,1)" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAYAAADjqDmQAAAABHNCSVQICAgIfAhkiAAAAP1JREFUeJzt3DGKhEAARcFWvP+VeyNBxJGFHX3BVmU2BvL4DBP1Muec48KyLFfH/NKHrGOMMbbzgdjfsXe8ir+dX+K7ruKv1cf8N8dRr+cDnmfpL9rHvVr5+yw9sIwxPv+h5BGWHhA9IHpA9IDoAdEDogdED4geED0gekD0gOgB0QOiB0QPiB4QPSB6QPSA6AHRA6IHRA+IHhA9IHpA9IDoAdEDogdED4geED0gekD0gOgB0QOiB0QPiB4QPSB6QPSA6AHRA6IHRA+IHhA9IHpA9JfNOUUvrHe3H/MMS3/RPvD1+MA7LP0lx2Fv50N3737X7aX155fE/5u7n+wfv04ph+lQnM8AAAAASUVORK5CYII=" + mask="url(#mask3540-4-8)" + id="image3556-9-8" /></g></g></g></g></g></g><g + style="display:inline" + id="g3558-6-7" + transform="matrix(5.09,0,0,-5.09,1180.2956,859.53096)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + inkscape:connector-curvature="0" + d="m 0,0 c 0,-1.65 -1.35,-3 -3,-3 l -74,0 c -1.649,0 -3,1.35 -3,3 l 0,50 c 0,1.65 1.351,3 3,3 l 74,0 c 1.65,0 3,-1.35 3,-3 L 0,0 z" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3560-5-9" /></g><g + style="display:inline" + id="g3562-4-5" + transform="matrix(5.09,0,0,-5.09,-2642.2948,3424.8908)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3564-6-8" /><g + id="g3574-7-5"><g + style="opacity:0.5" + clip-path="url(#clipPath3566-8-1)" + id="g3576-7-7"><g + id="g3578-2-1"><g + clip-path="url(#clipPath3570-6-5)" + id="g3580-1-1"><path + inkscape:connector-curvature="0" + d="m 710.994,535.863 -31.988,0 0,12.002 31.988,0 0,-12.002 z" + style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3582-0-1" /></g></g></g></g></g><path + inkscape:connector-curvature="0" + d="m 1068.3156,747.55096 -254.49997,0 0,-25.45 254.49997,0 0,25.45 z" + style="fill:#d1d2d3;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + id="path3584-1-4" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999" /><path + inkscape:connector-curvature="0" + d="m 951.24563,798.45096 -137.43,0 0,-25.45 137.43,0 0,25.45 z" + style="fill:#d1d2d3;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + id="path3586-5-3" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999" /><g + style="display:inline" + id="g3588-5-2" + transform="matrix(5.09,0,0,-5.09,-2642.2948,3424.8908)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3590-3-5" /><g + id="g3596-7-7"><g + style="opacity:0" + clip-path="url(#clipPath3592-5-6)" + id="g3598-6-3"><path + inkscape:connector-curvature="0" + d="m 730.777,537 12,0 0,12 -12,0 0,-12 z" + style="fill:#03a9f4;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3600-8-8" /></g></g></g><g + style="display:inline" + id="g3602-7-1" + transform="matrix(5.09,0,0,-5.09,1133.3524,659.74846)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + inkscape:connector-curvature="0" + d="m 0,0 c 0,0.414 -0.336,0.75 -0.75,0.75 l -2.75,0 -2.5,4 -1,0 1.25,-4 -2.75,0 -0.75,1 -0.75,0 0.5,-1.75 -0.5,-1.75 0.75,0 0.75,1 2.75,0 -1.25,-4 1,0 2.5,4 2.75,0 C -0.336,-0.75 0,-0.414 0,0" + style="fill:#00c853;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3604-3-1" /></g><g + id="layer2" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + transform="matrix(1.25,0,0,-1.25,1156.7381,197.1134)" + id="g3072-2" + style="fill:#4d4d4d;display:inline"><path + inkscape:connector-curvature="0" + d="m 0,0 -285.486,0 -14,-190.491 313.486,0 L 0,0 z" + id="path3074-4" + style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><g + transform="matrix(1.25,0,0,-1.25,1174.2381,908.94815)" + id="g3076-2" + style="fill:#333333;display:inline"><path + inkscape:connector-curvature="0" + d="m 0,0 -313.486,0 14,-190.491 286.486,0 L 0,0 z" + id="path3078-2" + style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><path + inkscape:connector-curvature="0" + d="m 1210.8105,905.83777 -467.50004,0 0,-467.5 467.50004,0 0,467.5 z m 4.165,-511.25 -473.33254,0 c -18.41125,0 -33.3325,14.92251 -33.3325,33.33376 l 0,6.66624 0,475 0,6.66751 c 0,18.40874 14.92125,33.33249 33.3325,33.33249 l 473.33254,0 c 18.4112,0 33.335,-14.92375 33.335,-33.33249 l 0,-6.66751 0,-475 0,-6.66624 c 0,-18.41125 -14.9238,-33.33376 -33.335,-33.33376" + id="path3080-8" + style="fill:#4d4d4d;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" /><g + transform="matrix(1.25,0,0,-1.25,-577.94194,1339.5878)" + id="g3082-6" + style="display:inline"><g + id="g3084-6" /><g + id="g3090-6"><g + clip-path="url(#clipPath3086-0-0-4)" + id="g3092-6" + style="opacity:0.10000598"><path + inkscape:connector-curvature="0" + d="m 1432.002,722 -374,0 0,-374 374,0 0,374 z m -3,-371 -368,0 0,368 368,0 0,-368 z" + id="path3094-4" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g><g + transform="matrix(1.25,0,0,-1.25,-577.94194,1339.5878)" + id="g3096-1" + style="display:inline"><g + id="g3098-7" /><g + id="g3104-3"><g + clip-path="url(#clipPath3100-0-7-1)" + id="g3106-8" + style="opacity:0.10000598"><g + transform="translate(1434.334,317.334)" + id="g3108-5"><path + inkscape:connector-curvature="0" + d="m 0,0 -378.666,0 c -14.729,0 -26.666,11.938 -26.666,26.666 l 0,-5.334 c 0,-14.727 11.937,-26.666 26.666,-26.666 L 0,-5.334 c 14.729,0 26.668,11.939 26.668,26.666 l 0,5.334 C 26.668,11.938 14.729,0 0,0" + id="path3110-7" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g><g + transform="matrix(1.25,0,0,-1.25,-577.94194,1339.5878)" + id="g3112-0" + style="display:inline"><g + id="g3114-4" /><g + id="g3120-4"><g + clip-path="url(#clipPath3116-3-2-9)" + id="g3122-9" + style="opacity:0.10000598"><g + transform="translate(1434.334,756)" + id="g3124-5"><path + inkscape:connector-curvature="0" + d="m 0,0 -378.666,0 c -14.729,0 -26.666,-11.938 -26.666,-26.667 l 0,-5.333 c 0,14.728 11.937,26.667 26.666,26.667 L 0,-5.333 c 14.729,0 26.668,-11.939 26.668,-26.667 l 0,5.333 C 26.668,-11.938 14.729,0 0,0" + id="path3126-3" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g></g></g><g + inkscape:groupmode="layer" + id="layer5" + inkscape:label="Layer2" + style="display:inline" + transform="translate(436.0495,72.4457)"><g + style="display:inline" + id="g3622-5" + transform="matrix(5.2235991,0,0,-5.1937884,1450.0328,987.05631)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + inkscape:connector-curvature="0" + d="m 0,0 c -32.947,0 -59.75,26.804 -59.75,59.75 0,32.946 26.803,59.75 59.75,59.75 32.945,0 59.75,-26.804 59.75,-59.75 C 59.75,26.804 32.945,0 0,0" + style="fill:#0bda2f;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3624-3" /></g><g + style="display:inline" + id="g3630-4" + transform="matrix(5.2235991,0,0,-5.1937884,-1819.9402,3439.8229)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3632-0" + clip-path="url(#clipPath3634-8)"><g + id="g3638-2"><g + id="g3640-4" /><g + id="g3666-9"><g + style="opacity:0.119995" + clip-path="url(#clipPath3642-3)" + id="g3668-8"><g + id="g3670-0"><g + id="g3672-4" /><g + mask="url(#mask3650-5)" + id="g3674-2"><g + transform="matrix(139.35082,0,0,78.633677,558.31445,465.31115)" + id="g3676-6"><image + width="1" + height="1" + transform="matrix(1,0,0,-1,0,1)" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAABPCAYAAAA5vC0kAAAABHNCSVQICAgIfAhkiAAAASdJREFUeJzt1rFuwyAUQFGw/P+/TIfKamQ5be7kRjlnshEDw9WDudZa48Kc82qZD/Eki7GfF4TCGD8dnMPZzxvg0Tmc7c7D8D6OcLbHH/iLCcPL5pxjjjGun8NwwYQhEQyJYEgEQyIYEsGQCIZEMCSCIREMiWBIBEMiGBLBkAiGRDAkgiERDIlgSARDIhgSwZAIhkQwJIIhEQyJYEgEQyIYEsGQCIZEMCSCIREMiWBIBEMiGBLBkAiGRDAkgiERDIlgSARDIhgSwZAIhkQwJIIhEQyJYEgEQyIYEsGQCIZEMCSCIREMiWBIBEMiGBLBkAiGRDAkgiERDMm21rr7DLyJtZYJQ7ON8V0O/OZoxIQh2Y+Po6A5522H4f853z77sw3C+WzPnilfB04mnX6avLgAAAAASUVORK5CYII=" + mask="url(#mask3662-9)" + id="image3678-1" /></g></g></g></g></g></g><g + id="g3680-5" + transform="translate(689.7031,476.2588)"><path + inkscape:connector-curvature="0" + d="m 0,0 c 0,-1.642 -1.344,-2.984 -2.986,-2.984 l -121.434,0 c -1.643,0 -2.986,1.342 -2.986,2.984 l 0,60.719 c 0,1.641 1.343,2.985 2.986,2.985 l 121.434,0 C -1.344,63.704 0,62.36 0,60.719 L 0,0 z" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3682-6" /></g></g></g><g + transform="translate(2e-5,-3e-5)" + id="layer1" + style="display:inline" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + transform="matrix(1.25,0,0,-1.25,1656.802,453.73263)" + id="g3024" + style="fill:#000000"><path + inkscape:connector-curvature="0" + d="m 0,0 -12.195,205.05 -307.49,0 L -331.88,0 c 44.595,34.886 102.563,58.974 165.94,58.974 C -102.563,58.974 -44.595,34.886 0,0" + id="path3026" + style="fill:#606060;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><g + transform="matrix(1.25,0,0,-1.25,1242.1212,894.81914)" + id="g3028" + style="fill:#000000"><path + inkscape:connector-curvature="0" + d="m 0,0 12.06,-202.039 307.49,0 L 331.609,0 C 287.033,-34.822 229.119,-58.869 165.805,-58.869 102.491,-58.869 44.576,-34.822 0,0" + id="path3030" + style="fill:#606060;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><g + transform="matrix(1.25,0,0,-1.25,1398.0984,389.22214)" + id="g3032"><path + inkscape:connector-curvature="0" + d="m 0,0 c 5.706,1.02 11.485,1.83 17.328,2.423 3.895,0.395 7.819,0.694 11.769,0.895 3.95,0.2 7.926,0.301 11.926,0.301 4,0 7.976,-0.101 11.926,-0.301 3.95,-0.201 7.874,-0.5 11.77,-0.895 C 70.561,1.83 76.341,1.02 82.047,0 c 108.425,-19.367 190.726,-114.139 190.726,-228.132 0,-127.991 -103.756,-231.75 -231.75,-231.75 -127.99,0 -231.751,103.759 -231.751,231.75 0,113.993 82.305,208.765 190.728,228.132 m 41.023,26.794 c -140.792,0 -254.926,-114.133 -254.926,-254.926 0,-140.792 114.134,-254.926 254.926,-254.926 140.79,0 254.926,114.134 254.926,254.926 0,140.793 -114.136,254.926 -254.926,254.926" + id="path3034" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><g + transform="matrix(1.25,0,0,-1.25,1449.3771,355.72914)" + id="g3036" + style="fill:#000000"><path + inkscape:connector-curvature="0" + d="m 0,0 c -140.792,0 -254.926,-114.134 -254.926,-254.926 0,-140.792 114.134,-254.926 254.926,-254.926 140.792,0 254.926,114.134 254.926,254.926 C 254.926,-114.134 140.792,0 0,0 m 231.75,-254.926 c 0,-127.991 -103.758,-231.75 -231.75,-231.75 -127.992,0 -231.75,103.759 -231.75,231.75 0,127.993 103.758,231.751 231.75,231.751 127.992,0 231.75,-103.758 231.75,-231.751" + id="path3038" + style="fill:#606060;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><g + transform="matrix(1.25,0,0,-1.25,676.87523,1339.8947)" + id="g3040"><g + id="g3042" /><g + id="g3048"><g + clip-path="url(#clipPath3044-8-1)" + id="g3050" + style="opacity:0.10000598"><g + transform="translate(844.249,532.4062)" + id="g3052"><path + inkscape:connector-curvature="0" + d="m 0,0 c 0,-124.952 -101.295,-226.248 -226.248,-226.248 -124.952,0 -226.247,101.296 -226.247,226.248 0,124.953 101.295,226.248 226.247,226.248 C -101.295,226.248 0,124.953 0,0" + id="path3054" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g><g + transform="matrix(1.25,0,0,-1.25,676.87523,1339.8947)" + id="g3056"><g + id="g3058" /><g + id="g3064"><g + clip-path="url(#clipPath3060-8-27)" + id="g3066" + style="opacity:0.10000598"><g + transform="translate(618.0015,787.7266)" + id="g3068"><path + inkscape:connector-curvature="0" + d="m 0,0 c -34.466,0 -67.903,-6.75 -99.383,-20.065 -30.404,-12.861 -57.707,-31.269 -81.155,-54.716 -23.446,-23.447 -41.856,-50.752 -54.715,-81.156 -13.314,-31.48 -20.066,-64.916 -20.066,-99.383 0,-34.465 6.752,-67.904 20.066,-99.381 12.859,-30.405 31.269,-57.709 54.715,-81.156 23.448,-23.447 50.751,-41.857 81.155,-54.715 31.48,-13.315 64.917,-20.066 99.383,-20.066 34.466,0 67.903,6.751 99.382,20.066 30.405,12.858 57.708,31.268 81.155,54.715 23.447,23.447 41.857,50.751 54.716,81.156 13.314,31.477 20.066,64.916 20.066,99.381 0,34.467 -6.752,67.903 -20.066,99.383 -12.859,30.404 -31.269,57.709 -54.716,81.156 -23.447,23.447 -50.75,41.855 -81.155,54.716 C 67.903,-6.75 34.466,0 0,0 m 0,-3.153 c 139.268,0 252.167,-112.897 252.167,-252.167 0,-139.267 -112.899,-252.166 -252.167,-252.166 -139.268,0 -252.167,112.899 -252.167,252.166 0,139.27 112.899,252.167 252.167,252.167" + id="path3070" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g></g><g + style="display:inline" + id="g3692-7" + transform="matrix(5.2956158,0,0,-5.2956158,-1870.725,3488.2105)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3694-5" /><g + id="g3704-5"><g + clip-path="url(#clipPath3696-9-7)" + id="g3706-2" + style="opacity:0.5"><g + id="g3708-6"><g + clip-path="url(#clipPath3700-1-1)" + id="g3710-3"><path + d="m 623.994,518.863 -31.988,0 0,12.002 31.988,0 0,-12.002 z" + style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3712-4" + inkscape:connector-curvature="0" /></g></g></g></g></g><path + d="m 1529.0604,792.7421 -264.7808,0 0,-26.47808 264.7808,0 0,26.47808 z" + style="fill:#d1d2d3;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + id="path3714-2" + inkscape:connector-curvature="0" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999" /><path + d="m 1407.2613,845.69826 -142.9817,0 0,-26.47808 142.9817,0 0,26.47808 z" + style="fill:#d1d2d3;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + id="path3716-3" + inkscape:connector-curvature="0" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999" /><g + style="display:inline" + id="g3718-7" + transform="matrix(5.2956158,0,0,-5.2956158,-1870.725,3488.2105)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3720-1" /><g + id="g3730-8"><g + clip-path="url(#clipPath3722-1-6)" + id="g3732-8" + style="opacity:0"><g + id="g3734-9"><g + clip-path="url(#clipPath3726-6-9)" + id="g3736-3"><path + d="m 664.001,520 -12.001,0 0,12 12.001,0 0,-12 z" + style="fill:#ee2a7b;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3738-7" + inkscape:connector-curvature="0" /></g></g></g></g></g><g + style="display:inline" + id="g3740-9" + transform="matrix(5.2956158,0,0,-5.2956158,1589.96,702.14789)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + d="m 0,0 4.5,0 0,-4.501 0.501,0 4,9.001 L 0,0.501 0,0 z" + style="fill:#03a9f4;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3742-8" + inkscape:connector-curvature="0" /></g></g><g + inkscape:groupmode="layer" + id="layer4" + inkscape:label="Layer1" + style="display:inline" + transform="translate(436.0495,72.4457)"><g + style="display:inline" + id="g3508-5" + transform="matrix(5.09,0,0,-5.09,1683.0619,927.12472)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + inkscape:connector-curvature="0" + d="m 0,0 c -2.209,0 -4,1.791 -4,4 l 0,92 c 0,2.209 1.791,4 4,4 l 92,0 c 2.209,0 4,-1.791 4,-4 L 96,4 C 96,1.791 94.209,0 92,0 L 0,0 z" + style="fill:#ffed0d;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3510-0" /></g><g + style="display:inline" + id="g3516-7" + transform="matrix(5.09,0,0,-5.09,-1701.7885,3426.3146)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3518-2" /><g + id="g3544-9"><g + style="opacity:0.119995" + clip-path="url(#clipPath3520-6)" + id="g3546-7"><g + id="g3548-8"><g + id="g3550-3" /><g + mask="url(#mask3528-3)" + id="g3552-8"><g + transform="matrix(93,0,0,68,667,493)" + id="g3554-9"><image + width="1" + height="1" + transform="matrix(1,0,0,-1,0,1)" + xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAF0AAABECAYAAADjqDmQAAAABHNCSVQICAgIfAhkiAAAAP1JREFUeJzt3DGKhEAARcFWvP+VeyNBxJGFHX3BVmU2BvL4DBP1Muec48KyLFfH/NKHrGOMMbbzgdjfsXe8ir+dX+K7ruKv1cf8N8dRr+cDnmfpL9rHvVr5+yw9sIwxPv+h5BGWHhA9IHpA9IDoAdEDogdED4geED0gekD0gOgB0QOiB0QPiB4QPSB6QPSA6AHRA6IHRA+IHhA9IHpA9IDoAdEDogdED4geED0gekD0gOgB0QOiB0QPiB4QPSB6QPSA6AHRA6IHRA+IHhA9IHpA9JfNOUUvrHe3H/MMS3/RPvD1+MA7LP0lx2Fv50N3737X7aX155fE/5u7n+wfv04ph+lQnM8AAAAASUVORK5CYII=" + mask="url(#mask3540-4)" + id="image3556-9" /></g></g></g></g></g></g><g + style="display:inline" + id="g3558-6" + transform="matrix(5.09,0,0,-5.09,2120.8019,860.95472)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + inkscape:connector-curvature="0" + d="m 0,0 c 0,-1.65 -1.35,-3 -3,-3 l -74,0 c -1.649,0 -3,1.35 -3,3 l 0,50 c 0,1.65 1.351,3 3,3 l 74,0 c 1.65,0 3,-1.35 3,-3 L 0,0 z" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3560-5" /></g><g + style="display:inline" + id="g3562-4" + transform="matrix(5.09,0,0,-5.09,-1701.7885,3426.3146)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3564-6" /><g + id="g3574-7"><g + style="opacity:0.5" + clip-path="url(#clipPath3566-8)" + id="g3576-7"><g + id="g3578-2"><g + clip-path="url(#clipPath3570-6)" + id="g3580-1"><path + inkscape:connector-curvature="0" + d="m 710.994,535.863 -31.988,0 0,12.002 31.988,0 0,-12.002 z" + style="fill:#6d6e71;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3582-0" /></g></g></g></g></g><path + inkscape:connector-curvature="0" + d="m 2008.8219,748.97472 -254.5,0 0,-25.45 254.5,0 0,25.45 z" + style="fill:#d1d2d3;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + id="path3584-1" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999" /><path + inkscape:connector-curvature="0" + d="m 1891.7519,799.87472 -137.43,0 0,-25.45 137.43,0 0,25.45 z" + style="fill:#d1d2d3;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline" + id="path3586-5" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999" /><g + style="display:inline" + id="g3588-5" + transform="matrix(5.09,0,0,-5.09,-1701.7885,3426.3146)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><g + id="g3590-3" /><g + id="g3596-7"><g + style="opacity:0" + clip-path="url(#clipPath3592-5)" + id="g3598-6"><path + inkscape:connector-curvature="0" + d="m 730.777,537 12,0 0,12 -12,0 0,-12 z" + style="fill:#03a9f4;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3600-8" /></g></g></g><g + style="display:inline" + id="g3602-7" + transform="matrix(5.09,0,0,-5.09,2073.8587,661.17222)" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999"><path + inkscape:connector-curvature="0" + d="m 0,0 c 0,0.414 -0.336,0.75 -0.75,0.75 l -2.75,0 -2.5,4 -1,0 1.25,-4 -2.75,0 -0.75,1 -0.75,0 0.5,-1.75 -0.5,-1.75 0.75,0 0.75,1 2.75,0 -1.25,-4 1,0 2.5,4 2.75,0 C -0.336,-0.75 0,-0.414 0,0" + style="fill:#00c853;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3604-3" /></g><g + transform="matrix(1.25,0,0,-1.25,0,1350)" + id="g3012" + style="display:inline" + inkscape:export-xdpi="18.559999" + inkscape:export-ydpi="18.559999" + inkscape:export-filename="C:\Users\Joe Fernandez\Downloads\Android Wear Artwork\g3014.png"><g + transform="translate(1677.8121,922.30928)" + id="g3072" + style="fill:#333333;fill-opacity:1"><path + inkscape:connector-curvature="0" + d="m 0,0 -285.486,0 -14,-190.491 313.486,0 L 0,0 z" + id="path3074" + style="fill:#747474;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><g + transform="translate(1691.8121,352.84148)" + id="g3076" + style="fill:#333333;fill-opacity:1"><path + inkscape:connector-curvature="0" + d="m 0,0 -313.486,0 14,-190.491 286.486,0 L 0,0 z" + id="path3078" + style="fill:#747474;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g><path + inkscape:connector-curvature="0" + d="m 1721.07,355.32978 -374,0 0,374 374,0 0,-374 z m 3.332,409 -378.666,0 c -14.729,0 -26.666,-11.938 -26.666,-26.667 l 0,-5.333 0,-380 0,-5.334 c 0,-14.727 11.937,-26.666 26.666,-26.666 l 378.666,0 c 14.729,0 26.668,11.939 26.668,26.666 l 0,5.334 0,380 0,5.333 c 0,14.729 -11.939,26.667 -26.668,26.667" + id="path3080" + style="fill:#747474;fill-opacity:1;fill-rule:nonzero;stroke:none" /><g + transform="translate(290.06807,8.3297801)" + id="g3082"><g + id="g3084" /><g + id="g3090"><g + clip-path="url(#clipPath3086-4)" + id="g3092" + style="opacity:0.10000598"><path + inkscape:connector-curvature="0" + d="m 1432.002,722 -374,0 0,-374 374,0 0,374 z m -3,-371 -368,0 0,368 368,0 0,-368 z" + id="path3094" + style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g><g + transform="translate(290.06807,8.3297801)" + id="g3096"><g + id="g3098" /><g + id="g3104"><g + clip-path="url(#clipPath3100-8)" + id="g3106" + style="opacity:0.10000598"><g + transform="translate(1434.334,317.334)" + id="g3108"><path + inkscape:connector-curvature="0" + d="m 0,0 -378.666,0 c -14.729,0 -26.666,11.938 -26.666,26.666 l 0,-5.334 c 0,-14.727 11.937,-26.666 26.666,-26.666 L 0,-5.334 c 14.729,0 26.668,11.939 26.668,26.666 l 0,5.334 C 26.668,11.938 14.729,0 0,0" + id="path3110" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g><g + transform="translate(290.06807,8.3297801)" + id="g3112"><g + id="g3114" /><g + id="g3120"><g + clip-path="url(#clipPath3116-4)" + id="g3122" + style="opacity:0.10000598"><g + transform="translate(1434.334,756)" + id="g3124"><path + inkscape:connector-curvature="0" + d="m 0,0 -378.666,0 c -14.729,0 -26.666,-11.938 -26.666,-26.667 l 0,-5.333 c 0,14.728 11.937,26.667 26.666,26.667 L 0,-5.333 c 14.729,0 26.668,-11.939 26.668,-26.667 l 0,5.333 C 26.668,-11.938 14.729,0 0,0" + id="path3126" + style="fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none" /></g></g></g></g></g><g + id="g3744" + transform="matrix(1.25,0,0,-1.25,-298.02174,762.5543)"><g + id="g3746" /><g + id="g3752"><g + clip-path="url(#clipPath3748-6)" + id="g3754" + style="opacity:0"><path + d="m 1484,446 -270,0 0,182 270,0 0,-182 z" + style="fill:#ec008c;fill-opacity:1;fill-rule:nonzero;stroke:none" + id="path3756" + inkscape:connector-curvature="0" /></g></g></g><g + id="g3758" + transform="matrix(1.25,0,0,-1.25,1378.2283,155.0543)" /><g + id="g3762" + transform="matrix(1.25,0,0,-1.25,1539.4783,28.8043)" /></g></svg>
\ No newline at end of file diff --git a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java index 9bcad3e5be84..849faecb99d5 100644 --- a/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedStateListDrawable.java @@ -139,27 +139,15 @@ public class AnimatedStateListDrawable extends StateListDrawable { @Override protected boolean onStateChange(int[] stateSet) { - final int keyframeIndex = mState.indexOfKeyframe(stateSet); - if (keyframeIndex == getCurrentIndex()) { - // Propagate state change to current keyframe. - final Drawable current = getCurrent(); - if (current != null) { - return current.setState(stateSet); - } - return false; - } - - // Attempt to find a valid transition to the keyframe. - if (selectTransition(keyframeIndex)) { - return true; - } - - // No valid transition, attempt to jump directly to the keyframe. - if (selectDrawable(keyframeIndex)) { - return true; - } - - return super.onStateChange(stateSet); + // If we're not already at the target index, either attempt to find a + // valid transition to it or jump directly there. + final int targetIndex = mState.indexOfKeyframe(stateSet); + final boolean changedIndex = targetIndex != getCurrentIndex() + && (selectTransition(targetIndex) || selectDrawable(targetIndex)); + + // Always call super.onStateChanged() to propagate the state change to + // the current drawable. + return super.onStateChange(stateSet) || changedIndex; } private boolean selectTransition(int toIndex) { diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index bec1d381b84c..1fac5b6bd986 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -1058,54 +1058,72 @@ public abstract class Drawable { final Drawable drawable; final String name = parser.getName(); - if (name.equals("selector")) { - drawable = new StateListDrawable(); - } else if (name.equals("animated-selector")) { - drawable = new AnimatedStateListDrawable(); - } else if (name.equals("level-list")) { - drawable = new LevelListDrawable(); - } else if (name.equals("layer-list")) { - drawable = new LayerDrawable(); - } else if (name.equals("transition")) { - drawable = new TransitionDrawable(); - } else if (name.equals("ripple")) { - drawable = new RippleDrawable(); - } else if (name.equals("color")) { - drawable = new ColorDrawable(); - } else if (name.equals("shape")) { - drawable = new GradientDrawable(); - } else if (name.equals("vector")) { - drawable = new VectorDrawable(); - } else if (name.equals("animated-vector")) { - drawable = new AnimatedVectorDrawable(); - } else if (name.equals("scale")) { - drawable = new ScaleDrawable(); - } else if (name.equals("clip")) { - drawable = new ClipDrawable(); - } else if (name.equals("rotate")) { - drawable = new RotateDrawable(); - } else if (name.equals("animated-rotate")) { - drawable = new AnimatedRotateDrawable(); - } else if (name.equals("animation-list")) { - drawable = new AnimationDrawable(); - } else if (name.equals("inset")) { - drawable = new InsetDrawable(); - } else if (name.equals("bitmap")) { - //noinspection deprecation - drawable = new BitmapDrawable(r); - if (r != null) { - ((BitmapDrawable) drawable).setTargetDensity(r.getDisplayMetrics()); - } - } else if (name.equals("nine-patch")) { - drawable = new NinePatchDrawable(); - if (r != null) { - ((NinePatchDrawable) drawable).setTargetDensity(r.getDisplayMetrics()); - } - } else { - throw new XmlPullParserException(parser.getPositionDescription() + - ": invalid drawable tag " + name); - } + switch (name) { + case "selector": + drawable = new StateListDrawable(); + break; + case "animated-selector": + drawable = new AnimatedStateListDrawable(); + break; + case "level-list": + drawable = new LevelListDrawable(); + break; + case "layer-list": + drawable = new LayerDrawable(); + break; + case "transition": + drawable = new TransitionDrawable(); + break; + case "ripple": + drawable = new RippleDrawable(); + break; + case "color": + drawable = new ColorDrawable(); + break; + case "shape": + drawable = new GradientDrawable(); + break; + case "vector": + drawable = new VectorDrawable(); + break; + case "animated-vector": + drawable = new AnimatedVectorDrawable(); + break; + case "scale": + drawable = new ScaleDrawable(); + break; + case "clip": + drawable = new ClipDrawable(); + break; + case "rotate": + drawable = new RotateDrawable(); + break; + case "animated-rotate": + drawable = new AnimatedRotateDrawable(); + break; + case "animation-list": + drawable = new AnimationDrawable(); + break; + case "inset": + drawable = new InsetDrawable(); + break; + case "bitmap": + drawable = new BitmapDrawable(r); + if (r != null) { + ((BitmapDrawable) drawable).setTargetDensity(r.getDisplayMetrics()); + } + break; + case "nine-patch": + drawable = new NinePatchDrawable(); + if (r != null) { + ((NinePatchDrawable) drawable).setTargetDensity(r.getDisplayMetrics()); + } + break; + default: + throw new XmlPullParserException(parser.getPositionDescription() + + ": invalid drawable tag " + name); + } drawable.inflate(r, parser, attrs, theme); return drawable; } diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index eff5a3d938b1..47e0e46b0888 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -1395,9 +1395,12 @@ public class GradientDrawable extends Drawable { } else { radiusType = RADIUS_TYPE_FRACTION; } - } else { + } else if (tv.type == TypedValue.TYPE_DIMENSION) { radius = tv.getDimension(r.getDisplayMetrics()); radiusType = RADIUS_TYPE_PIXELS; + } else { + radius = tv.getFloat(); + radiusType = RADIUS_TYPE_PIXELS; } st.mGradientRadius = radius; @@ -1549,14 +1552,15 @@ public class GradientDrawable extends Drawable { public int mThickness = -1; public boolean mDither = false; - private float mCenterX = 0.5f; - private float mCenterY = 0.5f; - private float mGradientRadius = 0.5f; - private int mGradientRadiusType = RADIUS_TYPE_PIXELS; - private boolean mUseLevel; - private boolean mUseLevelForShape; - private boolean mOpaqueOverBounds; - private boolean mOpaqueOverShape; + float mCenterX = 0.5f; + float mCenterY = 0.5f; + float mGradientRadius = 0.5f; + int mGradientRadiusType = RADIUS_TYPE_PIXELS; + boolean mUseLevel = false; + boolean mUseLevelForShape = true; + + boolean mOpaqueOverBounds; + boolean mOpaqueOverShape; ColorStateList mTint = null; PorterDuff.Mode mTintMode = DEFAULT_TINT_MODE; diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk index 5808d201643e..1344dd9905d8 100644 --- a/libs/androidfw/tests/Android.mk +++ b/libs/androidfw/tests/Android.mk @@ -26,6 +26,7 @@ testFiles := \ Idmap_test.cpp \ ResTable_test.cpp \ Split_test.cpp \ + TestHelpers.cpp \ Theme_test.cpp \ TypeWrappers_test.cpp \ ZipUtils_test.cpp diff --git a/libs/androidfw/tests/ResTable_test.cpp b/libs/androidfw/tests/ResTable_test.cpp index 89d271d0bcd6..6a9314e5ffb8 100644 --- a/libs/androidfw/tests/ResTable_test.cpp +++ b/libs/androidfw/tests/ResTable_test.cpp @@ -37,8 +37,6 @@ namespace { #include "data/lib/lib_arsc.h" -enum { MAY_NOT_BE_BAG = false }; - TEST(ResTableTest, shouldLoadSuccessfully) { ResTable table; ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); @@ -48,15 +46,7 @@ TEST(ResTableTest, simpleTypeIsRetrievedCorrectly) { ResTable table; ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); - Res_value val; - ssize_t block = table.getResource(base::R::string::test1, &val, MAY_NOT_BE_BAG); - - ASSERT_GE(block, 0); - ASSERT_EQ(Res_value::TYPE_STRING, val.dataType); - - const ResStringPool* pool = table.getTableStringBlock(block); - ASSERT_TRUE(NULL != pool); - ASSERT_EQ(String8("test1"), pool->string8ObjectAt(val.data)); + EXPECT_TRUE(IsStringEqual(table, base::R::string::test1, "test1")); } TEST(ResTableTest, resourceNameIsResolved) { diff --git a/libs/androidfw/tests/Split_test.cpp b/libs/androidfw/tests/Split_test.cpp index f63f566fa444..b69d68572e6a 100644 --- a/libs/androidfw/tests/Split_test.cpp +++ b/libs/androidfw/tests/Split_test.cpp @@ -42,6 +42,9 @@ namespace { * Package: com.android.test.basic */ #include "data/basic/split_de_fr_arsc.h" +#include "data/basic/split_hdpi_v4_arsc.h" +#include "data/basic/split_xhdpi_v4_arsc.h" +#include "data/basic/split_xxhdpi_v4_arsc.h" /** * Include a binary resource table. This table @@ -163,6 +166,33 @@ TEST(SplitTest, TypeEntrySpecFlagsAreUpdated) { EXPECT_EQ(ResTable_config::CONFIG_LOCALE, frSpecFlags); } +TEST(SplitTest, SelectBestDensity) { + ResTable_config baseConfig; + memset(&baseConfig, 0, sizeof(baseConfig)); + baseConfig.density = ResTable_config::DENSITY_XHIGH; + baseConfig.sdkVersion = 21; + + ResTable table; + table.setParameters(&baseConfig); + ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); + ASSERT_EQ(NO_ERROR, table.add(split_hdpi_v4_arsc, split_hdpi_v4_arsc_len)); + + EXPECT_TRUE(IsStringEqual(table, base::R::string::density, "hdpi")); + + ASSERT_EQ(NO_ERROR, table.add(split_xhdpi_v4_arsc, split_xhdpi_v4_arsc_len)); + + EXPECT_TRUE(IsStringEqual(table, base::R::string::density, "xhdpi")); + + ASSERT_EQ(NO_ERROR, table.add(split_xxhdpi_v4_arsc, split_xxhdpi_v4_arsc_len)); + + EXPECT_TRUE(IsStringEqual(table, base::R::string::density, "xhdpi")); + + baseConfig.density = ResTable_config::DENSITY_XXHIGH; + table.setParameters(&baseConfig); + + EXPECT_TRUE(IsStringEqual(table, base::R::string::density, "xxhdpi")); +} + TEST(SplitFeatureTest, TestNewResourceIsAccessible) { ResTable table; ASSERT_EQ(NO_ERROR, table.add(basic_arsc, basic_arsc_len)); @@ -188,7 +218,7 @@ TEST(SplitFeatureTest, TestNewResourceNameHasCorrectName) { ASSERT_EQ(NO_ERROR, table.add(feature_arsc, feature_arsc_len)); - EXPECT_TRUE(table.getResourceName(base::R::string::test3, false, &name)); + ASSERT_TRUE(table.getResourceName(base::R::string::test3, false, &name)); EXPECT_EQ(String16("com.android.test.basic"), String16(name.package, name.packageLen)); diff --git a/libs/androidfw/tests/TestHelpers.cpp b/libs/androidfw/tests/TestHelpers.cpp new file mode 100644 index 000000000000..41a19a7f2b24 --- /dev/null +++ b/libs/androidfw/tests/TestHelpers.cpp @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2014 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 "TestHelpers.h" + +#include <androidfw/ResourceTypes.h> +#include <utils/String8.h> +#include <gtest/gtest.h> + +namespace android { + +::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resourceId, const char* expectedStr) { + Res_value val; + ssize_t block = table.getResource(resourceId, &val, MAY_NOT_BE_BAG); + if (block < 0) { + return ::testing::AssertionFailure() << "could not find resource"; + } + + if (val.dataType != Res_value::TYPE_STRING) { + return ::testing::AssertionFailure() << "resource is not a string"; + } + + const ResStringPool* pool = table.getTableStringBlock(block); + if (pool == NULL) { + return ::testing::AssertionFailure() << "table has no string pool for block " << block; + } + + const String8 actual = pool->string8ObjectAt(val.data); + if (String8(expectedStr) != actual) { + return ::testing::AssertionFailure() << actual.string(); + } + return ::testing::AssertionSuccess() << actual.string(); +} + +} // namespace android diff --git a/libs/androidfw/tests/TestHelpers.h b/libs/androidfw/tests/TestHelpers.h index fe2e5ce29eff..ac80d8868090 100644 --- a/libs/androidfw/tests/TestHelpers.h +++ b/libs/androidfw/tests/TestHelpers.h @@ -6,6 +6,7 @@ #include <androidfw/ResourceTypes.h> #include <utils/String8.h> #include <utils/String16.h> +#include <gtest/gtest.h> static inline ::std::ostream& operator<<(::std::ostream& out, const android::String8& str) { return out << str.string(); @@ -17,6 +18,8 @@ static inline ::std::ostream& operator<<(::std::ostream& out, const android::Str namespace android { +enum { MAY_NOT_BE_BAG = false }; + static inline bool operator==(const android::ResTable_config& a, const android::ResTable_config& b) { return memcmp(&a, &b, sizeof(a)) == 0; } @@ -25,6 +28,8 @@ static inline ::std::ostream& operator<<(::std::ostream& out, const android::Res return out << c.toString().string(); } +::testing::AssertionResult IsStringEqual(const ResTable& table, uint32_t resourceId, const char* expectedStr); + } // namespace android #endif // __TEST_HELPERS_H diff --git a/libs/androidfw/tests/data/app/R.h b/libs/androidfw/tests/data/app/R.h index 780a11610ef5..23e68e3e80dc 100644 --- a/libs/androidfw/tests/data/app/R.h +++ b/libs/androidfw/tests/data/app/R.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2014 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 __APP_R_H #define __APP_R_H diff --git a/libs/androidfw/tests/data/app/build b/libs/androidfw/tests/data/app/build index 89c464120ea3..62257bc26d4b 100755 --- a/libs/androidfw/tests/data/app/build +++ b/libs/androidfw/tests/data/app/build @@ -1,4 +1,19 @@ #!/bin/bash +# +# Copyright (C) 2014 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. +# aapt package -v -I ../system/bundle.apk -M AndroidManifest.xml -S res -F bundle.apk -f && \ unzip bundle.apk resources.arsc && \ diff --git a/libs/androidfw/tests/data/app/res/values/values.xml b/libs/androidfw/tests/data/app/res/values/values.xml index b0ead387b0a8..c1cf64c247a3 100644 --- a/libs/androidfw/tests/data/app/res/values/values.xml +++ b/libs/androidfw/tests/data/app/res/values/values.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + <resources> <attr name="number" format="integer"/> <style name="Theme.One" parent="@android:style/Theme.One"> diff --git a/libs/androidfw/tests/data/basic/R.h b/libs/androidfw/tests/data/basic/R.h index 363dcb9e170c..aaac74059f58 100644 --- a/libs/androidfw/tests/data/basic/R.h +++ b/libs/androidfw/tests/data/basic/R.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2014 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 __BASE_R_H #define __BASE_R_H @@ -21,9 +37,10 @@ namespace string { enum { test1 = 0x7f030000, // default test2 = 0x7f030001, // default + density = 0x7f030002, // default - test3 = 0x7f070000, // default (in feature) - test4 = 0x7f070001, // default (in feature) + test3 = 0x7f080000, // default (in feature) + test4 = 0x7f080001, // default (in feature) }; } @@ -32,7 +49,7 @@ namespace integer { number1 = 0x7f040000, // default, sv number2 = 0x7f040001, // default - test3 = 0x7f080000, // default (in feature) + test3 = 0x7f090000, // default (in feature) }; } diff --git a/libs/androidfw/tests/data/basic/basic_arsc.h b/libs/androidfw/tests/data/basic/basic_arsc.h index 61cb94c65828..13ab4fa0d0ea 100644 --- a/libs/androidfw/tests/data/basic/basic_arsc.h +++ b/libs/androidfw/tests/data/basic/basic_arsc.h @@ -1,5 +1,5 @@ unsigned char basic_arsc[] = { - 0x02, 0x00, 0x0c, 0x00, 0x60, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x0c, 0x00, 0x68, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, @@ -16,7 +16,7 @@ unsigned char basic_arsc[] = { 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, - 0x98, 0x06, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, + 0xa0, 0x06, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, @@ -101,61 +101,61 @@ unsigned char basic_arsc[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, - 0x6c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x44, 0x00, 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, - 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, - 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, - 0x6c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, + 0x03, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x6c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, - 0xc8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x7f, 0x01, 0x02, 0x44, 0x00, - 0x5c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x73, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, - 0x90, 0x01, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x90, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0xc8, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x06, 0x7f, 0x01, 0x02, 0x44, 0x00, 0x5c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x76, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x90, 0x01, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x44, 0x00, 0x90, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x01, 0x7f, 0x08, 0x00, 0x00, 0x10, 0x64, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x01, 0x7f, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x7f, - 0x10, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x7f, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f, 0x08, 0x00, 0x00, 0x10, - 0x2c, 0x01, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x44, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x07, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f, + 0x08, 0x00, 0x00, 0x10, 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x7f, + 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x04, 0x7f, 0x10, 0x00, 0x01, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x7f, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x7f, 0x08, 0x00, 0x00, 0x10, 0x2c, 0x01, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, + 0x7c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10, - 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10, - 0x03, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x00 }; -unsigned int basic_arsc_len = 1888; +unsigned int basic_arsc_len = 1896; diff --git a/libs/androidfw/tests/data/basic/build b/libs/androidfw/tests/data/basic/build index 036e46828189..fd289fad62b1 100755 --- a/libs/androidfw/tests/data/basic/build +++ b/libs/androidfw/tests/data/basic/build @@ -1,11 +1,39 @@ #!/bin/bash +# +# Copyright (C) 2014 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. +# PATH_TO_FRAMEWORK_RES=$(gettop)/prebuilts/sdk/current/android.jar -aapt package -M AndroidManifest.xml -S res -I $PATH_TO_FRAMEWORK_RES --split fr,de -F bundle.apk -f && \ +aapt package -M AndroidManifest.xml -S res -I $PATH_TO_FRAMEWORK_RES --split hdpi --split xhdpi --split xxhdpi --split fr,de -F bundle.apk -f && \ unzip bundle.apk resources.arsc && \ mv resources.arsc basic.arsc && \ xxd -i basic.arsc > basic_arsc.h && \ +\ unzip bundle_de_fr.apk resources.arsc && \ mv resources.arsc split_de_fr.arsc && \ -xxd -i split_de_fr.arsc > split_de_fr_arsc.h +xxd -i split_de_fr.arsc > split_de_fr_arsc.h && \ +\ +unzip bundle_hdpi-v4.apk resources.arsc && \ +mv resources.arsc split_hdpi_v4.arsc && \ +xxd -i split_hdpi_v4.arsc > split_hdpi_v4_arsc.h && \ +\ +unzip bundle_xhdpi-v4.apk resources.arsc && \ +mv resources.arsc split_xhdpi_v4.arsc && \ +xxd -i split_xhdpi_v4.arsc > split_xhdpi_v4_arsc.h && \ +\ +unzip bundle_xxhdpi-v4.apk resources.arsc && \ +mv resources.arsc split_xxhdpi_v4.arsc && \ +xxd -i split_xxhdpi_v4.arsc > split_xxhdpi_v4_arsc.h \ diff --git a/libs/androidfw/tests/data/basic/res/layout-fr-sw600dp/main.xml b/libs/androidfw/tests/data/basic/res/layout-fr-sw600dp/main.xml index 05ffd5856487..0dcf7e092577 100644 --- a/libs/androidfw/tests/data/basic/res/layout-fr-sw600dp/main.xml +++ b/libs/androidfw/tests/data/basic/res/layout-fr-sw600dp/main.xml @@ -1,3 +1,18 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> + <merge> </merge> diff --git a/libs/androidfw/tests/data/basic/res/layout/main.xml b/libs/androidfw/tests/data/basic/res/layout/main.xml index 05ffd5856487..0dcf7e092577 100644 --- a/libs/androidfw/tests/data/basic/res/layout/main.xml +++ b/libs/androidfw/tests/data/basic/res/layout/main.xml @@ -1,3 +1,18 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 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. +--> + <merge> </merge> diff --git a/libs/androidfw/tests/data/basic/res/values-de/values.xml b/libs/androidfw/tests/data/basic/res/values-de/values.xml index 103c6a3643c4..2683a7eee68c 100644 --- a/libs/androidfw/tests/data/basic/res/values-de/values.xml +++ b/libs/androidfw/tests/data/basic/res/values-de/values.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + <resources> <string name="test1">versuch 1</string> <string name="test2">versuch 2</string> diff --git a/libs/androidfw/tests/data/basic/res/values-fr/values.xml b/libs/androidfw/tests/data/basic/res/values-fr/values.xml index 1806a2dc12a9..7d3bed3f220f 100644 --- a/libs/androidfw/tests/data/basic/res/values-fr/values.xml +++ b/libs/androidfw/tests/data/basic/res/values-fr/values.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + <resources> <string name="test1">essai 1</string> <string name="test2">essai 2</string> diff --git a/libs/androidfw/tests/data/basic/res/values-hdpi/values.xml b/libs/androidfw/tests/data/basic/res/values-hdpi/values.xml new file mode 100644 index 000000000000..04bf943f7fe4 --- /dev/null +++ b/libs/androidfw/tests/data/basic/res/values-hdpi/values.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources> + <string name="density">hdpi</string> +</resources> diff --git a/libs/androidfw/tests/data/basic/res/values-sv/values.xml b/libs/androidfw/tests/data/basic/res/values-sv/values.xml index 9d523071dd07..7351b4989c92 100644 --- a/libs/androidfw/tests/data/basic/res/values-sv/values.xml +++ b/libs/androidfw/tests/data/basic/res/values-sv/values.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + <resources> <integer name="number1">400</integer> </resources> diff --git a/libs/androidfw/tests/data/basic/res/values-xhdpi/values.xml b/libs/androidfw/tests/data/basic/res/values-xhdpi/values.xml new file mode 100644 index 000000000000..845e9a02e9b0 --- /dev/null +++ b/libs/androidfw/tests/data/basic/res/values-xhdpi/values.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources> + <string name="density">xhdpi</string> +</resources> diff --git a/libs/androidfw/tests/data/basic/res/values-xxhdpi/values.xml b/libs/androidfw/tests/data/basic/res/values-xxhdpi/values.xml new file mode 100644 index 000000000000..964da020d847 --- /dev/null +++ b/libs/androidfw/tests/data/basic/res/values-xxhdpi/values.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources> + <string name="density">xxhdpi</string> +</resources> diff --git a/libs/androidfw/tests/data/basic/res/values/values.xml b/libs/androidfw/tests/data/basic/res/values/values.xml index 662eda6a4ed5..a010cca182ee 100644 --- a/libs/androidfw/tests/data/basic/res/values/values.xml +++ b/libs/androidfw/tests/data/basic/res/values/values.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + <resources> <attr name="attr1" format="reference|integer" /> <attr name="attr2" format="reference|integer" /> diff --git a/libs/androidfw/tests/data/basic/split_de_fr_arsc.h b/libs/androidfw/tests/data/basic/split_de_fr_arsc.h index a8eaf0b2f69d..b742d2811487 100644 --- a/libs/androidfw/tests/data/basic/split_de_fr_arsc.h +++ b/libs/androidfw/tests/data/basic/split_de_fr_arsc.h @@ -1,5 +1,5 @@ unsigned char split_de_fr_arsc[] = { - 0x02, 0x00, 0x0c, 0x00, 0xd8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x0c, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, @@ -10,7 +10,7 @@ unsigned char split_de_fr_arsc[] = { 0x32, 0x00, 0x00, 0x00, 0x07, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x61, 0x00, 0x69, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x07, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x61, 0x00, 0x69, 0x00, 0x20, 0x00, - 0x32, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x50, 0x03, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x5c, 0x03, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, @@ -55,24 +55,25 @@ unsigned char split_de_fr_arsc[] = { 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x6c, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, + 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x6c, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x72, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x44, 0x00, 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x66, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, @@ -82,4 +83,4 @@ unsigned char split_de_fr_arsc[] = { 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -unsigned int split_de_fr_arsc_len = 984; +unsigned int split_de_fr_arsc_len = 996; diff --git a/libs/androidfw/tests/data/basic/split_hdpi_v4_arsc.h b/libs/androidfw/tests/data/basic/split_hdpi_v4_arsc.h new file mode 100644 index 000000000000..e9fb7ea47b75 --- /dev/null +++ b/libs/androidfw/tests/data/basic/split_hdpi_v4_arsc.h @@ -0,0 +1,68 @@ +unsigned char split_hdpi_v4_arsc[] = { + 0x02, 0x00, 0x0c, 0x00, 0x08, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x1c, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x68, 0x00, + 0x64, 0x00, 0x70, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, + 0xd0, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, + 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, + 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, + 0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, + 0x69, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0xb0, 0x01, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, + 0x90, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00, 0x6f, 0x00, 0x75, 0x00, + 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, + 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x00, 0x00, 0x07, 0x00, 0x69, 0x00, + 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00, + 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, 0x79, 0x00, 0x6c, 0x00, + 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, 0x72, 0x00, 0x72, 0x00, + 0x61, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x64, 0x00, 0x65, 0x00, 0x6e, 0x00, + 0x73, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x44, 0x00, 0x60, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +unsigned int split_hdpi_v4_arsc_len = 776; diff --git a/libs/androidfw/tests/data/basic/split_xhdpi_v4_arsc.h b/libs/androidfw/tests/data/basic/split_xhdpi_v4_arsc.h new file mode 100644 index 000000000000..7835f71419f2 --- /dev/null +++ b/libs/androidfw/tests/data/basic/split_xhdpi_v4_arsc.h @@ -0,0 +1,68 @@ +unsigned char split_xhdpi_v4_arsc[] = { + 0x02, 0x00, 0x0c, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x1c, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x78, 0x00, + 0x68, 0x00, 0x64, 0x00, 0x70, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x20, 0x01, 0xd0, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, + 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, + 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00, + 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xb0, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x1c, 0x00, 0x90, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, + 0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00, + 0x6f, 0x00, 0x75, 0x00, 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x73, 0x00, + 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, + 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, + 0x79, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, + 0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x1c, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x64, 0x00, + 0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +unsigned int split_xhdpi_v4_arsc_len = 780; diff --git a/libs/androidfw/tests/data/basic/split_xxhdpi_v4_arsc.h b/libs/androidfw/tests/data/basic/split_xxhdpi_v4_arsc.h new file mode 100644 index 000000000000..f805db1b009e --- /dev/null +++ b/libs/androidfw/tests/data/basic/split_xxhdpi_v4_arsc.h @@ -0,0 +1,68 @@ +unsigned char split_xxhdpi_v4_arsc[] = { + 0x02, 0x00, 0x0c, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x1c, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x78, 0x00, + 0x78, 0x00, 0x68, 0x00, 0x64, 0x00, 0x70, 0x00, 0x69, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x20, 0x01, 0xd0, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, + 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, + 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, + 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00, + 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0xb0, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x1c, 0x00, 0x90, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, + 0x72, 0x00, 0x00, 0x00, 0x06, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x79, 0x00, + 0x6f, 0x00, 0x75, 0x00, 0x74, 0x00, 0x00, 0x00, 0x06, 0x00, 0x73, 0x00, + 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, + 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x05, 0x00, 0x73, 0x00, 0x74, 0x00, + 0x79, 0x00, 0x6c, 0x00, 0x65, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, + 0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x1c, 0x00, 0x34, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x64, 0x00, + 0x65, 0x00, 0x6e, 0x00, 0x73, 0x00, 0x69, 0x00, 0x74, 0x00, 0x79, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x60, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, + 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +unsigned int split_xxhdpi_v4_arsc_len = 780; diff --git a/libs/androidfw/tests/data/feature/build b/libs/androidfw/tests/data/feature/build index b547dc215595..0f3307f518ec 100755 --- a/libs/androidfw/tests/data/feature/build +++ b/libs/androidfw/tests/data/feature/build @@ -1,4 +1,19 @@ #!/bin/bash +# +# Copyright (C) 2014 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. +# aapt package -M AndroidManifest.xml -S res --feature-of ../basic/bundle.apk -F bundle.apk -f && \ unzip bundle.apk resources.arsc && \ diff --git a/libs/androidfw/tests/data/feature/feature_arsc.h b/libs/androidfw/tests/data/feature/feature_arsc.h index cf7647d71b05..cd299102e8f6 100644 --- a/libs/androidfw/tests/data/feature/feature_arsc.h +++ b/libs/androidfw/tests/data/feature/feature_arsc.h @@ -1,11 +1,11 @@ unsigned char feature_arsc[] = { - 0x02, 0x00, 0x0c, 0x00, 0x40, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x0c, 0x00, 0x44, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x33, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xf4, 0x02, 0x00, 0x00, + 0x34, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xf8, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, @@ -28,46 +28,46 @@ unsigned char feature_arsc[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x01, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x9c, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x7c, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, - 0x2e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x3c, 0x00, 0x65, 0x00, 0x6d, 0x00, - 0x70, 0x00, 0x74, 0x00, 0x79, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x04, 0x00, - 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x00, 0x00, 0x06, 0x00, - 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x67, 0x00, - 0x00, 0x00, 0x07, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x65, 0x00, - 0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, - 0x58, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x33, 0x00, - 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, - 0x34, 0x00, 0x00, 0x00, 0x07, 0x00, 0x6e, 0x00, 0x75, 0x00, 0x6d, 0x00, - 0x62, 0x00, 0x65, 0x00, 0x72, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x6c, 0x00, 0x00, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0xa0, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x80, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x1e, 0x00, 0x00, 0x00, 0x2e, 0x00, 0x00, 0x00, 0x07, 0x00, 0x3c, 0x00, + 0x65, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x74, 0x00, 0x79, 0x00, 0x3e, 0x00, + 0x00, 0x00, 0x04, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, + 0x00, 0x00, 0x06, 0x00, 0x73, 0x00, 0x74, 0x00, 0x72, 0x00, 0x69, 0x00, + 0x6e, 0x00, 0x67, 0x00, 0x00, 0x00, 0x07, 0x00, 0x69, 0x00, 0x6e, 0x00, + 0x74, 0x00, 0x65, 0x00, 0x67, 0x00, 0x65, 0x00, 0x72, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x1c, 0x00, 0x58, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, + 0x74, 0x00, 0x33, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, + 0x73, 0x00, 0x74, 0x00, 0x34, 0x00, 0x00, 0x00, 0x07, 0x00, 0x6e, 0x00, + 0x75, 0x00, 0x6d, 0x00, 0x62, 0x00, 0x65, 0x00, 0x72, 0x00, 0x33, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, + 0x6c, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x09, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x44, 0x00, 0x58, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, - 0xc8, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x10, 0xc8, 0x00, 0x00, 0x00 }; -unsigned int feature_arsc_len = 832; +unsigned int feature_arsc_len = 836; diff --git a/libs/androidfw/tests/data/feature/res/values/values.xml b/libs/androidfw/tests/data/feature/res/values/values.xml index d03445a33d72..343fd6c8389f 100644 --- a/libs/androidfw/tests/data/feature/res/values/values.xml +++ b/libs/androidfw/tests/data/feature/res/values/values.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + <resources> <string name="test3">test3</string> <string name="test4">test4</string> diff --git a/libs/androidfw/tests/data/lib/R.h b/libs/androidfw/tests/data/lib/R.h index 13bf09528c90..ff311208d61a 100644 --- a/libs/androidfw/tests/data/lib/R.h +++ b/libs/androidfw/tests/data/lib/R.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2014 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 __LIB_R_H #define __LIB_R_H diff --git a/libs/androidfw/tests/data/lib/build b/libs/androidfw/tests/data/lib/build index 8e6e70cdc553..41029031028c 100755 --- a/libs/androidfw/tests/data/lib/build +++ b/libs/androidfw/tests/data/lib/build @@ -1,4 +1,19 @@ #!/bin/bash +# +# Copyright (C) 2014 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. +# aapt package -M AndroidManifest.xml -S res -F bundle.apk -f --shared-lib && \ unzip bundle.apk resources.arsc && \ diff --git a/libs/androidfw/tests/data/lib/lib_arsc.h b/libs/androidfw/tests/data/lib/lib_arsc.h index d670c5be18a3..dd3dad5d5f3d 100644 --- a/libs/androidfw/tests/data/lib/lib_arsc.h +++ b/libs/androidfw/tests/data/lib/lib_arsc.h @@ -1,8 +1,8 @@ unsigned char lib_arsc[] = { - 0x02, 0x00, 0x0c, 0x00, 0xc8, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x0c, 0x00, 0xb8, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0xa0, 0x03, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x90, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, @@ -37,48 +37,25 @@ unsigned char lib_arsc[] = { 0x00, 0x00, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00, 0x05, 0x00, 0x61, 0x00, 0x74, 0x00, 0x74, 0x00, 0x72, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x54, 0x00, 0x68, 0x00, 0x65, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x00, 0x00, - 0x03, 0x02, 0x0c, 0x00, 0x10, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, - 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, - 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, - 0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, 0x69, 0x00, 0x63, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x64, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x08, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, - 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x64, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, - 0x08, 0x00, 0x00, 0x10, 0xbc, 0x02, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x08, 0x00, 0x00, 0x10, 0xbc, 0x02, 0x00, 0x00 }; -unsigned int lib_arsc_len = 968; +unsigned int lib_arsc_len = 696; diff --git a/libs/androidfw/tests/data/lib/res/values/values.xml b/libs/androidfw/tests/data/lib/res/values/values.xml index a77f0c79b74b..3ec79b1c7663 100644 --- a/libs/androidfw/tests/data/lib/res/values/values.xml +++ b/libs/androidfw/tests/data/lib/res/values/values.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + <resources> <attr name="attr1" format="integer" /> diff --git a/libs/androidfw/tests/data/overlay/build b/libs/androidfw/tests/data/overlay/build index 87cf6de4c933..f73767749274 100755 --- a/libs/androidfw/tests/data/overlay/build +++ b/libs/androidfw/tests/data/overlay/build @@ -1,4 +1,19 @@ #!/bin/bash +# +# Copyright (C) 2014 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. +# aapt package -M AndroidManifest.xml -S res -F bundle.apk -f && \ unzip bundle.apk resources.arsc && \ diff --git a/libs/androidfw/tests/data/overlay/res/values/values.xml b/libs/androidfw/tests/data/overlay/res/values/values.xml index 227e88973cc7..3e1af9878429 100644 --- a/libs/androidfw/tests/data/overlay/res/values/values.xml +++ b/libs/androidfw/tests/data/overlay/res/values/values.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + <resources> <string name="test2">test2-overlay</string> <integer-array name="integerArray1"> diff --git a/libs/androidfw/tests/data/system/R.h b/libs/androidfw/tests/data/system/R.h index 7a9d3db95586..27f25fec0d01 100644 --- a/libs/androidfw/tests/data/system/R.h +++ b/libs/androidfw/tests/data/system/R.h @@ -1,3 +1,19 @@ +/* + * Copyright (C) 2014 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 __ANDROID_R_H #define __ANDROID_R_H diff --git a/libs/androidfw/tests/data/system/build b/libs/androidfw/tests/data/system/build index 2a3ac0b9f7d4..1a70e84114b0 100755 --- a/libs/androidfw/tests/data/system/build +++ b/libs/androidfw/tests/data/system/build @@ -1,4 +1,19 @@ #!/bin/bash +# +# Copyright (C) 2014 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. +# aapt package -x -M AndroidManifest.xml -S res -F bundle.apk -f && \ unzip bundle.apk resources.arsc && \ diff --git a/libs/androidfw/tests/data/system/res/values/themes.xml b/libs/androidfw/tests/data/system/res/values/themes.xml index b29848efd023..35d43c77fc7a 100644 --- a/libs/androidfw/tests/data/system/res/values/themes.xml +++ b/libs/androidfw/tests/data/system/res/values/themes.xml @@ -1,4 +1,19 @@ <?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + <resources> <public name="background" type="attr" id="0x01010000"/> <public name="foreground" type="attr" id="0x01010001"/> diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp index 70ff6e5f575f..40cd13ef4f02 100644 --- a/libs/hwui/RenderNode.cpp +++ b/libs/hwui/RenderNode.cpp @@ -296,6 +296,9 @@ void RenderNode::pushStagingDisplayListChanges(TreeInfo& info) { mStagingDisplayListData->children()[i]->mRenderNode->incParentRefCount(); } } + // Damage with the old display list first then the new one to catch any + // changes in isRenderable or, in the future, bounds + damageSelf(info); deleteDisplayListData(); mDisplayListData = mStagingDisplayListData; mStagingDisplayListData = NULL; diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index 3bb47786b223..9d2ae8b6d8ad 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -42,7 +42,8 @@ CanvasContext::CanvasContext(RenderThread& thread, bool translucent, : mRenderThread(thread) , mEglManager(thread.eglManager()) , mEglSurface(EGL_NO_SURFACE) - , mDirtyRegionsEnabled(false) + , mBufferPreserved(false) + , mSwapBehavior(kSwap_default) , mOpaque(!translucent) , mCanvas(NULL) , mHaveNewSurface(false) @@ -82,7 +83,8 @@ void CanvasContext::setSurface(ANativeWindow* window) { } if (mEglSurface != EGL_NO_SURFACE) { - mDirtyRegionsEnabled = mEglManager.enableDirtyRegions(mEglSurface); + const bool preserveBuffer = (mSwapBehavior != kSwap_discardBuffer); + mBufferPreserved = mEglManager.setPreserveBuffer(mEglSurface, preserveBuffer); mHaveNewSurface = true; makeCurrent(); } else { @@ -103,6 +105,10 @@ void CanvasContext::requireSurface() { makeCurrent(); } +void CanvasContext::setSwapBehavior(SwapBehavior swapBehavior) { + mSwapBehavior = swapBehavior; +} + bool CanvasContext::initialize(ANativeWindow* window) { setSurface(window); if (mCanvas) return false; @@ -200,7 +206,7 @@ void CanvasContext::draw() { if (width != mCanvas->getViewportWidth() || height != mCanvas->getViewportHeight()) { mCanvas->setViewport(width, height); dirty.setEmpty(); - } else if (!mDirtyRegionsEnabled || mHaveNewSurface) { + } else if (!mBufferPreserved || mHaveNewSurface) { dirty.setEmpty(); } else { if (!dirty.isEmpty() && !dirty.intersect(0, 0, width, height)) { diff --git a/libs/hwui/renderthread/CanvasContext.h b/libs/hwui/renderthread/CanvasContext.h index d4282fada940..e20564b26124 100644 --- a/libs/hwui/renderthread/CanvasContext.h +++ b/libs/hwui/renderthread/CanvasContext.h @@ -48,6 +48,11 @@ namespace renderthread { class EglManager; +enum SwapBehavior { + kSwap_default, + kSwap_discardBuffer, +}; + // This per-renderer class manages the bridge between the global EGL context // and the render surface. // TODO: Rename to Renderer or some other per-window, top-level manager @@ -57,6 +62,9 @@ public: IContextFactory* contextFactory); virtual ~CanvasContext(); + // Won't take effect until next EGLSurface creation + void setSwapBehavior(SwapBehavior swapBehavior); + bool initialize(ANativeWindow* window); void updateSurface(ANativeWindow* window); void pauseSurface(ANativeWindow* window); @@ -111,7 +119,8 @@ private: EglManager& mEglManager; sp<ANativeWindow> mNativeWindow; EGLSurface mEglSurface; - bool mDirtyRegionsEnabled; + bool mBufferPreserved; + SwapBehavior mSwapBehavior; bool mOpaque; OpenGLRenderer* mCanvas; diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp index a87834ee0c63..760fc15a8cf7 100644 --- a/libs/hwui/renderthread/EglManager.cpp +++ b/libs/hwui/renderthread/EglManager.cpp @@ -70,12 +70,12 @@ EglManager::EglManager(RenderThread& thread) , mEglConfig(0) , mEglContext(EGL_NO_CONTEXT) , mPBufferSurface(EGL_NO_SURFACE) - , mRequestDirtyRegions(load_dirty_regions_property()) + , mAllowPreserveBuffer(load_dirty_regions_property()) , mCurrentSurface(EGL_NO_SURFACE) , mAtlasMap(NULL) , mAtlasMapSize(0) { - mCanSetDirtyRegions = mRequestDirtyRegions; - ALOGD("Render dirty regions requested: %s", mRequestDirtyRegions ? "true" : "false"); + mCanSetPreserveBuffer = mAllowPreserveBuffer; + ALOGD("Use EGL_SWAP_BEHAVIOR_PRESERVED: %s", mAllowPreserveBuffer ? "true" : "false"); } void EglManager::initialize() { @@ -113,7 +113,7 @@ void EglManager::requireGlContext() { } void EglManager::loadConfig() { - EGLint swapBehavior = mCanSetDirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; + EGLint swapBehavior = mCanSetPreserveBuffer ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0; EGLint attribs[] = { EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, @@ -131,10 +131,10 @@ void EglManager::loadConfig() { if (!eglChooseConfig(mEglDisplay, attribs, &mEglConfig, num_configs, &num_configs) || num_configs != 1) { // Failed to get a valid config - if (mCanSetDirtyRegions) { + if (mCanSetPreserveBuffer) { ALOGW("Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without..."); // Try again without dirty regions enabled - mCanSetDirtyRegions = false; + mCanSetPreserveBuffer = false; loadConfig(); } else { LOG_ALWAYS_FATAL("Failed to choose config, error = %s", egl_error_str()); @@ -273,25 +273,30 @@ bool EglManager::swapBuffers(EGLSurface surface) { return false; } -bool EglManager::enableDirtyRegions(EGLSurface surface) { - if (!mRequestDirtyRegions) return false; +bool EglManager::setPreserveBuffer(EGLSurface surface, bool preserve) { + if (CC_UNLIKELY(!mAllowPreserveBuffer)) return false; - if (mCanSetDirtyRegions) { - if (!eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, EGL_BUFFER_PRESERVED)) { + bool preserved = false; + if (mCanSetPreserveBuffer) { + preserved = eglSurfaceAttrib(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, + preserve ? EGL_BUFFER_PRESERVED : EGL_BUFFER_DESTROYED); + if (CC_UNLIKELY(!preserved)) { ALOGW("Failed to set EGL_SWAP_BEHAVIOR on surface %p, error=%s", (void*) surface, egl_error_str()); - return false; } - return true; } - // Perhaps it is already enabled? - EGLint value; - if (!eglQuerySurface(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, &value)) { - ALOGW("Failed to query EGL_SWAP_BEHAVIOR on surface %p, error=%p", - (void*) surface, egl_error_str()); - return false; + if (CC_UNLIKELY(!preserved)) { + // Maybe it's already set? + EGLint swapBehavior; + if (eglQuerySurface(mEglDisplay, surface, EGL_SWAP_BEHAVIOR, &swapBehavior)) { + preserved = (swapBehavior == EGL_BUFFER_PRESERVED); + } else { + ALOGW("Failed to query EGL_SWAP_BEHAVIOR on surface %p, error=%p", + (void*) surface, egl_error_str()); + } } - return value == EGL_BUFFER_PRESERVED; + + return preserved; } } /* namespace renderthread */ diff --git a/libs/hwui/renderthread/EglManager.h b/libs/hwui/renderthread/EglManager.h index 71213fbf9343..ae03ea1fc3b8 100644 --- a/libs/hwui/renderthread/EglManager.h +++ b/libs/hwui/renderthread/EglManager.h @@ -49,7 +49,8 @@ public: void beginFrame(EGLSurface surface, EGLint* width, EGLint* height); bool swapBuffers(EGLSurface surface); - bool enableDirtyRegions(EGLSurface surface); + // Returns true iff the surface is now preserving buffers. + bool setPreserveBuffer(EGLSurface surface, bool preserve); void setTextureAtlas(const sp<GraphicBuffer>& buffer, int64_t* map, size_t mapSize); @@ -71,8 +72,8 @@ private: EGLContext mEglContext; EGLSurface mPBufferSurface; - const bool mRequestDirtyRegions; - bool mCanSetDirtyRegions; + const bool mAllowPreserveBuffer; + bool mCanSetPreserveBuffer; EGLSurface mCurrentSurface; diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp index 047819de239a..8f99b4ed90c6 100644 --- a/libs/hwui/renderthread/RenderProxy.cpp +++ b/libs/hwui/renderthread/RenderProxy.cpp @@ -103,6 +103,18 @@ void RenderProxy::setFrameInterval(nsecs_t frameIntervalNanos) { post(task); } +CREATE_BRIDGE2(setSwapBehavior, CanvasContext* context, SwapBehavior swapBehavior) { + args->context->setSwapBehavior(args->swapBehavior); + return NULL; +} + +void RenderProxy::setSwapBehavior(SwapBehavior swapBehavior) { + SETUP_TASK(setSwapBehavior); + args->context = mContext; + args->swapBehavior = swapBehavior; + post(task); +} + CREATE_BRIDGE1(loadSystemProperties, CanvasContext* context) { bool needsRedraw = false; if (Caches::hasInstance()) { diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h index 678e7e261c77..dddf0c746249 100644 --- a/libs/hwui/renderthread/RenderProxy.h +++ b/libs/hwui/renderthread/RenderProxy.h @@ -31,6 +31,7 @@ #include "../Caches.h" #include "../IContextFactory.h" +#include "CanvasContext.h" #include "DrawFrameTask.h" namespace android { @@ -44,7 +45,6 @@ class Rect; namespace renderthread { -class CanvasContext; class ErrorChannel; class RenderThread; class RenderProxyBridge; @@ -63,6 +63,8 @@ public: ANDROID_API virtual ~RenderProxy(); ANDROID_API void setFrameInterval(nsecs_t frameIntervalNanos); + // Won't take effect until next EGLSurface creation + ANDROID_API void setSwapBehavior(SwapBehavior swapBehavior); ANDROID_API bool loadSystemProperties(); ANDROID_API bool initialize(const sp<ANativeWindow>& window); diff --git a/libs/hwui/renderthread/TimeLord.cpp b/libs/hwui/renderthread/TimeLord.cpp index cf3d0394fa57..9bd4eae1ea7c 100644 --- a/libs/hwui/renderthread/TimeLord.cpp +++ b/libs/hwui/renderthread/TimeLord.cpp @@ -20,7 +20,7 @@ namespace uirenderer { namespace renderthread { TimeLord::TimeLord() - : mFrameIntervalNanos(0) + : mFrameIntervalNanos(milliseconds_to_nanoseconds(16)) , mFrameTimeNanos(0) { } diff --git a/libs/hwui/tests/main.cpp b/libs/hwui/tests/main.cpp index 3e9a86f32c47..2d99e9f7686c 100644 --- a/libs/hwui/tests/main.cpp +++ b/libs/hwui/tests/main.cpp @@ -76,13 +76,14 @@ int main(int argc, char* argv[]) { sp<Surface> surface = control->getSurface(); RenderNode* rootNode = new RenderNode(); + rootNode->incStrong(0); rootNode->mutateStagingProperties().setLeftTopRightBottom(0, 0, width, height); rootNode->setPropertyFieldsDirty(RenderNode::X | RenderNode::Y); rootNode->mutateStagingProperties().setClipToBounds(false); rootNode->setPropertyFieldsDirty(RenderNode::GENERIC); - RenderProxy* proxy = new RenderProxy(false, rootNode, new ContextFactory()); - proxy->setFrameInterval(milliseconds_to_nanoseconds(16)); + ContextFactory factory; + RenderProxy* proxy = new RenderProxy(false, rootNode, &factory); proxy->loadSystemProperties(); proxy->initialize(surface); float lightX = width / 2.0; diff --git a/media/java/android/media/AudioDevicePort.java b/media/java/android/media/AudioDevicePort.java index 7975e04e49c8..b10736be1756 100644 --- a/media/java/android/media/AudioDevicePort.java +++ b/media/java/android/media/AudioDevicePort.java @@ -16,6 +16,8 @@ package android.media; +import android.media.AudioSystem; + /** * The AudioDevicePort is a specialized type of AudioPort * describing an input (e.g microphone) or output device (e.g speaker) @@ -85,8 +87,11 @@ public class AudioDevicePort extends AudioPort { @Override public String toString() { + String type = (mRole == ROLE_SOURCE ? + AudioSystem.getInputDeviceName(mType) : + AudioSystem.getOutputDeviceName(mType)); return "{" + super.toString() - + ", mType:" + mType + + ", mType: " + type + ", mAddress: " + mAddress + "}"; } diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java index 69c1142b5cd4..716ff992c008 100644 --- a/media/java/android/media/AudioManager.java +++ b/media/java/android/media/AudioManager.java @@ -353,21 +353,6 @@ public class AudioManager { */ @Deprecated public static final int NUM_STREAMS = AudioSystem.NUM_STREAMS; - - /** @hide Default volume index values for audio streams */ - public static final int[] DEFAULT_STREAM_VOLUME = new int[] { - 4, // STREAM_VOICE_CALL - 7, // STREAM_SYSTEM - 5, // STREAM_RING - 11, // STREAM_MUSIC - 6, // STREAM_ALARM - 5, // STREAM_NOTIFICATION - 7, // STREAM_BLUETOOTH_SCO - 7, // STREAM_SYSTEM_ENFORCED - 11, // STREAM_DTMF - 11 // STREAM_TTS - }; - /** * Increase the ringer volume. * @@ -512,8 +497,11 @@ public class AudioManager { */ public static final int RINGER_MODE_NORMAL = 2; - // maximum valid ringer mode value. Values must start from 0 and be contiguous. - private static final int RINGER_MODE_MAX = RINGER_MODE_NORMAL; + /** + * Maximum valid ringer mode value. Values must start from 0 and be contiguous. + * @hide + */ + public static final int RINGER_MODE_MAX = RINGER_MODE_NORMAL; /** * Vibrate type that corresponds to the ringer. @@ -887,7 +875,13 @@ public class AudioManager { if (ringerMode < 0 || ringerMode > RINGER_MODE_MAX) { return false; } - return true; + IAudioService service = getService(); + try { + return service.isValidRingerMode(ringerMode); + } catch (RemoteException e) { + Log.e(TAG, "Dead object in isValidRingerMode", e); + return false; + } } /** diff --git a/media/java/android/media/AudioPatch.java b/media/java/android/media/AudioPatch.java index 81eceb1e27e9..acadb413e429 100644 --- a/media/java/android/media/AudioPatch.java +++ b/media/java/android/media/AudioPatch.java @@ -52,4 +52,25 @@ public class AudioPatch { public AudioPortConfig[] sinks() { return mSinks; } + + @Override + public String toString() { + StringBuilder s = new StringBuilder(); + s.append("mHandle: "); + s.append(mHandle.toString()); + + s.append(" mSources: {"); + for (AudioPortConfig source : mSources) { + s.append(source.toString()); + s.append(", "); + } + s.append("} mSinks: {"); + for (AudioPortConfig sink : mSinks) { + s.append(sink.toString()); + s.append(", "); + } + s.append("}"); + + return s.toString(); + } } diff --git a/media/java/android/media/AudioPort.java b/media/java/android/media/AudioPort.java index 53212aa85e4e..1ab7e89273e9 100644 --- a/media/java/android/media/AudioPort.java +++ b/media/java/android/media/AudioPort.java @@ -67,7 +67,7 @@ public class AudioPort { AudioHandle mHandle; - private final int mRole; + protected final int mRole; private final int[] mSamplingRates; private final int[] mChannelMasks; private final int[] mFormats; @@ -176,8 +176,20 @@ public class AudioPort { @Override public String toString() { - return "{mHandle:" + mHandle - + ", mRole:" + mRole + String role = Integer.toString(mRole); + switch (mRole) { + case ROLE_NONE: + role = "NONE"; + break; + case ROLE_SOURCE: + role = "SOURCE"; + break; + case ROLE_SINK: + role = "SINK"; + break; + } + return "{mHandle: " + mHandle + + ", mRole: " + role + "}"; } } diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index b0bf4a148d71..a84fe440736e 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -248,7 +248,7 @@ public class AudioService extends IAudioService.Stub { private final int[][] SOUND_EFFECT_FILES_MAP = new int[AudioManager.NUM_SOUND_EFFECTS][2]; /** @hide Maximum volume index values for audio streams */ - private static final int[] MAX_STREAM_VOLUME = new int[] { + private static int[] MAX_STREAM_VOLUME = new int[] { 5, // STREAM_VOICE_CALL 7, // STREAM_SYSTEM 7, // STREAM_RING @@ -260,6 +260,20 @@ public class AudioService extends IAudioService.Stub { 15, // STREAM_DTMF 15 // STREAM_TTS }; + + private static int[] DEFAULT_STREAM_VOLUME = new int[] { + 4, // STREAM_VOICE_CALL + 7, // STREAM_SYSTEM + 5, // STREAM_RING + 11, // STREAM_MUSIC + 6, // STREAM_ALARM + 5, // STREAM_NOTIFICATION + 7, // STREAM_BLUETOOTH_SCO + 7, // STREAM_SYSTEM_ENFORCED + 11, // STREAM_DTMF + 11 // STREAM_TTS + }; + /* mStreamVolumeAlias[] indicates for each stream if it uses the volume settings * of another stream: This avoids multiplying the volume settings for hidden * stream types that follow other stream behavior for volume settings @@ -541,12 +555,18 @@ public class AudioService extends IAudioService.Stub { mHasVibrator = vibrator == null ? false : vibrator.hasVibrator(); // Intialized volume - MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = SystemProperties.getInt( - "ro.config.vc_call_vol_steps", - MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]); - MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = SystemProperties.getInt( - "ro.config.media_vol_steps", - MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]); + int maxVolume = SystemProperties.getInt("ro.config.vc_call_vol_steps", + MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]); + if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]) { + MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = maxVolume; + DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = (maxVolume * 3) / 4; + } + maxVolume = SystemProperties.getInt("ro.config.media_vol_steps", + MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]); + if (maxVolume != MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]) { + MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = maxVolume; + DEFAULT_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = (maxVolume * 3) / 4; + } sSoundEffectVolumeDb = context.getResources().getInteger( com.android.internal.R.integer.config_soundEffectVolumeDb); @@ -843,7 +863,7 @@ public class AudioService extends IAudioService.Stub { int ringerMode = ringerModeFromSettings; // sanity check in case the settings are restored from a device with incompatible // ringer modes - if (!AudioManager.isValidRingerMode(ringerMode)) { + if (!isValidRingerMode(ringerMode)) { ringerMode = AudioManager.RINGER_MODE_NORMAL; } if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { @@ -1625,6 +1645,10 @@ public class AudioService extends IAudioService.Stub { return MAX_STREAM_VOLUME[streamType]; } + public static int getDefaultStreamVolume(int streamType) { + return DEFAULT_STREAM_VOLUME[streamType]; + } + /** @see AudioManager#getStreamVolume(int) */ public int getStreamVolume(int streamType) { ensureValidStreamType(streamType); @@ -1733,17 +1757,22 @@ public class AudioService extends IAudioService.Stub { } private void ensureValidRingerMode(int ringerMode) { - if (!AudioManager.isValidRingerMode(ringerMode)) { + if (!isValidRingerMode(ringerMode)) { throw new IllegalArgumentException("Bad ringer mode " + ringerMode); } } + /** @see AudioManager#isValidRingerMode(int) */ + public boolean isValidRingerMode(int ringerMode) { + return ringerMode >= 0 && ringerMode <= AudioManager.RINGER_MODE_MAX; + } + /** @see AudioManager#setRingerMode(int) */ public void setRingerMode(int ringerMode, boolean checkZen) { if (mUseFixedVolume || isPlatformTelevision()) { return; } - + ensureValidRingerMode(ringerMode); if ((ringerMode == AudioManager.RINGER_MODE_VIBRATE) && !mHasVibrator) { ringerMode = AudioManager.RINGER_MODE_SILENT; } @@ -3351,7 +3380,7 @@ public class AudioService extends IAudioService.Stub { // only be stale values if ((mStreamType == AudioSystem.STREAM_SYSTEM) || (mStreamType == AudioSystem.STREAM_SYSTEM_ENFORCED)) { - int index = 10 * AudioManager.DEFAULT_STREAM_VOLUME[mStreamType]; + int index = 10 * DEFAULT_STREAM_VOLUME[mStreamType]; synchronized (mCameraSoundForced) { if (mCameraSoundForced) { index = mIndexMax; @@ -3375,7 +3404,7 @@ public class AudioService extends IAudioService.Stub { // if no volume stored for current stream and device, use default volume if default // device, continue otherwise int defaultIndex = (device == AudioSystem.DEVICE_OUT_DEFAULT) ? - AudioManager.DEFAULT_STREAM_VOLUME[mStreamType] : -1; + DEFAULT_STREAM_VOLUME[mStreamType] : -1; int index = Settings.System.getIntForUser( mContentResolver, name, defaultIndex, UserHandle.USER_CURRENT); if (index == -1) { diff --git a/media/java/android/media/AudioSystem.java b/media/java/android/media/AudioSystem.java index 9a76f9482369..e795fa74fc8b 100644 --- a/media/java/android/media/AudioSystem.java +++ b/media/java/android/media/AudioSystem.java @@ -255,6 +255,7 @@ public class AudioSystem public static final int DEVICE_OUT_SPDIF = 0x80000; public static final int DEVICE_OUT_FM = 0x100000; public static final int DEVICE_OUT_AUX_LINE = 0x200000; + public static final int DEVICE_OUT_SPEAKER_SAFE = 0x400000; public static final int DEVICE_OUT_DEFAULT = DEVICE_BIT_DEFAULT; @@ -280,6 +281,7 @@ public class AudioSystem DEVICE_OUT_SPDIF | DEVICE_OUT_FM | DEVICE_OUT_AUX_LINE | + DEVICE_OUT_SPEAKER_SAFE | DEVICE_OUT_DEFAULT); public static final int DEVICE_OUT_ALL_A2DP = (DEVICE_OUT_BLUETOOTH_A2DP | DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES | @@ -372,6 +374,27 @@ public class AudioSystem public static final String DEVICE_OUT_SPDIF_NAME = "spdif"; public static final String DEVICE_OUT_FM_NAME = "fm_transmitter"; public static final String DEVICE_OUT_AUX_LINE_NAME = "aux_line"; + public static final String DEVICE_OUT_SPEAKER_SAFE_NAME = "speaker_safe"; + + public static final String DEVICE_IN_COMMUNICATION_NAME = "communication"; + public static final String DEVICE_IN_AMBIENT_NAME = "ambient"; + public static final String DEVICE_IN_BUILTIN_MIC_NAME = "mic"; + public static final String DEVICE_IN_BLUETOOTH_SCO_HEADSET_NAME = "bt_sco_hs"; + public static final String DEVICE_IN_WIRED_HEADSET_NAME = "headset"; + public static final String DEVICE_IN_AUX_DIGITAL_NAME = "aux_digital"; + public static final String DEVICE_IN_TELEPHONY_RX_NAME = "telephony_rx"; + public static final String DEVICE_IN_BACK_MIC_NAME = "back_mic"; + public static final String DEVICE_IN_REMOTE_SUBMIX_NAME = "remote_submix"; + public static final String DEVICE_IN_ANLG_DOCK_HEADSET_NAME = "analog_dock"; + public static final String DEVICE_IN_DGTL_DOCK_HEADSET_NAME = "digital_dock"; + public static final String DEVICE_IN_USB_ACCESSORY_NAME = "usb_accessory"; + public static final String DEVICE_IN_USB_DEVICE_NAME = "usb_device"; + public static final String DEVICE_IN_FM_TUNER_NAME = "fm_tuner"; + public static final String DEVICE_IN_TV_TUNER_NAME = "tv_tuner"; + public static final String DEVICE_IN_LINE_NAME = "line"; + public static final String DEVICE_IN_SPDIF_NAME = "spdif"; + public static final String DEVICE_IN_BLUETOOTH_A2DP_NAME = "bt_a2dp"; + public static final String DEVICE_IN_LOOPBACK_NAME = "loopback"; public static String getOutputDeviceName(int device) { @@ -420,12 +443,60 @@ public class AudioSystem return DEVICE_OUT_FM_NAME; case DEVICE_OUT_AUX_LINE: return DEVICE_OUT_AUX_LINE_NAME; + case DEVICE_OUT_SPEAKER_SAFE: + return DEVICE_OUT_SPEAKER_SAFE_NAME; case DEVICE_OUT_DEFAULT: default: - return ""; + return Integer.toString(device); } } + public static String getInputDeviceName(int device) + { + switch(device) { + case DEVICE_IN_COMMUNICATION: + return DEVICE_IN_COMMUNICATION_NAME; + case DEVICE_IN_AMBIENT: + return DEVICE_IN_AMBIENT_NAME; + case DEVICE_IN_BUILTIN_MIC: + return DEVICE_IN_BUILTIN_MIC_NAME; + case DEVICE_IN_BLUETOOTH_SCO_HEADSET: + return DEVICE_IN_BLUETOOTH_SCO_HEADSET_NAME; + case DEVICE_IN_WIRED_HEADSET: + return DEVICE_IN_WIRED_HEADSET_NAME; + case DEVICE_IN_AUX_DIGITAL: + return DEVICE_IN_AUX_DIGITAL_NAME; + case DEVICE_IN_TELEPHONY_RX: + return DEVICE_IN_TELEPHONY_RX_NAME; + case DEVICE_IN_BACK_MIC: + return DEVICE_IN_BACK_MIC_NAME; + case DEVICE_IN_REMOTE_SUBMIX: + return DEVICE_IN_REMOTE_SUBMIX_NAME; + case DEVICE_IN_ANLG_DOCK_HEADSET: + return DEVICE_IN_ANLG_DOCK_HEADSET_NAME; + case DEVICE_IN_DGTL_DOCK_HEADSET: + return DEVICE_IN_DGTL_DOCK_HEADSET_NAME; + case DEVICE_IN_USB_ACCESSORY: + return DEVICE_IN_USB_ACCESSORY_NAME; + case DEVICE_IN_USB_DEVICE: + return DEVICE_IN_USB_DEVICE_NAME; + case DEVICE_IN_FM_TUNER: + return DEVICE_IN_FM_TUNER_NAME; + case DEVICE_IN_TV_TUNER: + return DEVICE_IN_TV_TUNER_NAME; + case DEVICE_IN_LINE: + return DEVICE_IN_LINE_NAME; + case DEVICE_IN_SPDIF: + return DEVICE_IN_SPDIF_NAME; + case DEVICE_IN_BLUETOOTH_A2DP: + return DEVICE_IN_BLUETOOTH_A2DP_NAME; + case DEVICE_IN_LOOPBACK: + return DEVICE_IN_LOOPBACK_NAME; + case DEVICE_IN_DEFAULT: + default: + return Integer.toString(device); + } + } // phone state, match audio_mode??? public static final int PHONE_STATE_OFFCALL = 0; diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl index 39b074e6bbf6..2d8042cb367e 100644 --- a/media/java/android/media/IAudioService.aidl +++ b/media/java/android/media/IAudioService.aidl @@ -80,6 +80,8 @@ interface IAudioService { int getRingerMode(); + boolean isValidRingerMode(int ringerMode); + void setVibrateSetting(int vibrateType, int vibrateSetting); int getVibrateSetting(int vibrateType); diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java index b3890d45f4d5..691df77e9541 100644 --- a/media/java/android/media/tv/TvContract.java +++ b/media/java/android/media/tv/TvContract.java @@ -1052,6 +1052,24 @@ public final class TvContract { /** The genre for Gaming. */ public static final String GAMING = "GAMING"; + /** The genre for Arts. */ + public static final String ARTS = "ARTS"; + + /** The genre for Entertainment. */ + public static final String ENTERTAINMENT = "ENTERTAINMENT"; + + /** The genre for Life Style. */ + public static final String LIFE_STYLE = "LIFE_STYLE"; + + /** The genre for Music. */ + public static final String MUSIC = "MUSIC"; + + /** The genre for Premier. */ + public static final String PREMIER = "PREMIER"; + + /** The genre for Tech/Science. */ + public static final String TECH_SCIENCE = "TECH_SCIENCE"; + private static final ArraySet<String> CANONICAL_GENRES = new ArraySet<String>(); static { CANONICAL_GENRES.add(FAMILY_KIDS); @@ -1065,6 +1083,12 @@ public final class TvContract { CANONICAL_GENRES.add(ANIMAL_WILDLIFE); CANONICAL_GENRES.add(NEWS); CANONICAL_GENRES.add(GAMING); + CANONICAL_GENRES.add(ARTS); + CANONICAL_GENRES.add(ENTERTAINMENT); + CANONICAL_GENRES.add(LIFE_STYLE); + CANONICAL_GENRES.add(MUSIC); + CANONICAL_GENRES.add(PREMIER); + CANONICAL_GENRES.add(TECH_SCIENCE); } private Genres() {} diff --git a/media/java/android/media/tv/TvInputInfo.java b/media/java/android/media/tv/TvInputInfo.java index 54ebc6aad10c..b9e99d2c14a4 100644 --- a/media/java/android/media/tv/TvInputInfo.java +++ b/media/java/android/media/tv/TvInputInfo.java @@ -241,6 +241,9 @@ public final class TvInputInfo implements Parcelable { if (DEBUG) { Log.d(TAG, "Setup activity loaded. [" + input.mSetupActivity + "] for " + si.name); } + if (inputType == TYPE_TUNER && TextUtils.isEmpty(input.mSetupActivity)) { + throw new XmlPullParserException("Setup activity not found in " + si.name); + } input.mSettingsActivity = sa.getString( com.android.internal.R.styleable.TvInputService_settingsActivity); if (DEBUG) { diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java index 78714d202649..51bd205dbf2d 100644 --- a/media/java/android/media/tv/TvInputManager.java +++ b/media/java/android/media/tv/TvInputManager.java @@ -159,12 +159,12 @@ public final class TvInputManager { private final Object mLock = new Object(); - // @GuardedBy(mLock) + // @GuardedBy("mLock") private final List<TvInputCallbackRecord> mCallbackRecords = new LinkedList<TvInputCallbackRecord>(); // A mapping from TV input ID to the state of corresponding input. - // @GuardedBy(mLock) + // @GuardedBy("mLock") private final Map<String, Integer> mStateMap = new ArrayMap<String, Integer>(); // A mapping from the sequence number of a session to its SessionCallbackRecord. @@ -207,7 +207,7 @@ public final class TvInputManager { /** * This is called when the channel of this session is changed by the underlying TV input - * with out any {@link TvInputManager.Session#tune(Uri)} request. + * without any {@link TvInputManager.Session#tune(Uri)} request. * * @param session A {@link TvInputManager.Session} associated with this callback. * @param channelUri The URI of a channel. @@ -227,7 +227,7 @@ public final class TvInputManager { /** * This is called when a track for a given type is selected. * - * @param session A {@link TvInputManager.Session} associated with this callback + * @param session A {@link TvInputManager.Session} associated with this callback. * @param type The type of the selected track. The type can be * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or * {@link TvTrackInfo#TYPE_SUBTITLE}. @@ -238,6 +238,18 @@ public final class TvInputManager { } /** + * This is invoked when the video size has been changed. It is also called when the first + * time video size information becomes available after the session is tuned to a specific + * channel. + * + * @param session A {@link TvInputManager.Session} associated with this callback. + * @param width The width of the video. + * @param height The height of the video. + */ + public void onVideoSizeChanged(Session session, int width, int height) { + } + + /** * This is called when the video is available, so the TV input starts the playback. * * @param session A {@link TvInputManager.Session} associated with this callback. @@ -312,13 +324,13 @@ public final class TvInputManager { private final Handler mHandler; private Session mSession; - public SessionCallbackRecord(SessionCallback sessionCallback, + SessionCallbackRecord(SessionCallback sessionCallback, Handler handler) { mSessionCallback = sessionCallback; mHandler = handler; } - public void postSessionCreated(final Session session) { + void postSessionCreated(final Session session) { mSession = session; mHandler.post(new Runnable() { @Override @@ -328,7 +340,7 @@ public final class TvInputManager { }); } - public void postSessionReleased() { + void postSessionReleased() { mHandler.post(new Runnable() { @Override public void run() { @@ -337,7 +349,7 @@ public final class TvInputManager { }); } - public void postChannelRetuned(final Uri channelUri) { + void postChannelRetuned(final Uri channelUri) { mHandler.post(new Runnable() { @Override public void run() { @@ -346,49 +358,34 @@ public final class TvInputManager { }); } - public void postTracksChanged(final List<TvTrackInfo> tracks) { + void postTracksChanged(final List<TvTrackInfo> tracks) { mHandler.post(new Runnable() { @Override public void run() { - mSession.mAudioTracks.clear(); - mSession.mVideoTracks.clear(); - mSession.mSubtitleTracks.clear(); - for (TvTrackInfo track : tracks) { - if (track.getType() == TvTrackInfo.TYPE_AUDIO) { - mSession.mAudioTracks.add(track); - } else if (track.getType() == TvTrackInfo.TYPE_VIDEO) { - mSession.mVideoTracks.add(track); - } else if (track.getType() == TvTrackInfo.TYPE_SUBTITLE) { - mSession.mSubtitleTracks.add(track); - } else { - // Silently ignore. - } - } mSessionCallback.onTracksChanged(mSession, tracks); } }); } - public void postTrackSelected(final int type, final String trackId) { + void postTrackSelected(final int type, final String trackId) { mHandler.post(new Runnable() { @Override public void run() { - if (type == TvTrackInfo.TYPE_AUDIO) { - mSession.mSelectedAudioTrackId = trackId; - } else if (type == TvTrackInfo.TYPE_VIDEO) { - mSession.mSelectedVideoTrackId = trackId; - } else if (type == TvTrackInfo.TYPE_SUBTITLE) { - mSession.mSelectedSubtitleTrackId = trackId; - } else { - // Silently ignore. - return; - } mSessionCallback.onTrackSelected(mSession, type, trackId); } }); } - public void postVideoAvailable() { + void postVideoSizeChanged(final int width, final int height) { + mHandler.post(new Runnable() { + @Override + public void run() { + mSessionCallback.onVideoSizeChanged(mSession, width, height); + } + }); + } + + void postVideoAvailable() { mHandler.post(new Runnable() { @Override public void run() { @@ -397,7 +394,7 @@ public final class TvInputManager { }); } - public void postVideoUnavailable(final int reason) { + void postVideoUnavailable(final int reason) { mHandler.post(new Runnable() { @Override public void run() { @@ -406,7 +403,7 @@ public final class TvInputManager { }); } - public void postContentAllowed() { + void postContentAllowed() { mHandler.post(new Runnable() { @Override public void run() { @@ -415,7 +412,7 @@ public final class TvInputManager { }); } - public void postContentBlocked(final TvContentRating rating) { + void postContentBlocked(final TvContentRating rating) { mHandler.post(new Runnable() { @Override public void run() { @@ -424,7 +421,7 @@ public final class TvInputManager { }); } - public void postLayoutSurface(final int left, final int top, final int right, + void postLayoutSurface(final int left, final int top, final int right, final int bottom) { mHandler.post(new Runnable() { @Override @@ -434,7 +431,7 @@ public final class TvInputManager { }); } - public void postSessionEvent(final String eventType, final Bundle eventArgs) { + void postSessionEvent(final String eventType, final Bundle eventArgs) { mHandler.post(new Runnable() { @Override public void run() { @@ -610,7 +607,10 @@ public final class TvInputManager { Log.e(TAG, "Callback not found for seq " + seq); return; } - record.postTracksChanged(tracks); + if (record.mSession.updateTracks(tracks)) { + record.postTracksChanged(tracks); + postVideoSizeChangedIfNeededLocked(record); + } } } @@ -622,7 +622,17 @@ public final class TvInputManager { Log.e(TAG, "Callback not found for seq " + seq); return; } - record.postTrackSelected(type, trackId); + if (record.mSession.updateTrackSelection(type, trackId)) { + record.postTrackSelected(type, trackId); + postVideoSizeChangedIfNeededLocked(record); + } + } + } + + private void postVideoSizeChangedIfNeededLocked(SessionCallbackRecord record) { + TvTrackInfo track = record.mSession.getVideoTrackToNotify(); + if (track != null) { + record.postVideoSizeChanged(track.getVideoWidth(), track.getVideoHeight()); } } @@ -778,7 +788,7 @@ public final class TvInputManager { } /** - * Returns the state of a given TV input. It retuns one of the following: + * Returns the state of a given TV input. It returns one of the following: * <ul> * <li>{@link #INPUT_STATE_CONNECTED} * <li>{@link #INPUT_STATE_CONNECTED_STANDBY} @@ -1133,12 +1143,24 @@ public final class TvInputManager { private IBinder mToken; private TvInputEventSender mSender; private InputChannel mChannel; + + private final Object mTrackLock = new Object(); + // @GuardedBy("mTrackLock") private final List<TvTrackInfo> mAudioTracks = new ArrayList<TvTrackInfo>(); + // @GuardedBy("mTrackLock") private final List<TvTrackInfo> mVideoTracks = new ArrayList<TvTrackInfo>(); + // @GuardedBy("mTrackLock") private final List<TvTrackInfo> mSubtitleTracks = new ArrayList<TvTrackInfo>(); + // @GuardedBy("mTrackLock") private String mSelectedAudioTrackId; + // @GuardedBy("mTrackLock") private String mSelectedVideoTrackId; + // @GuardedBy("mTrackLock") private String mSelectedSubtitleTrackId; + // @GuardedBy("mTrackLock") + private int mVideoWidth; + // @GuardedBy("mTrackLock") + private int mVideoHeight; private Session(IBinder token, InputChannel channel, ITvInputManager service, int userId, int seq, SparseArray<SessionCallbackRecord> sessionCallbackRecordMap) { @@ -1273,12 +1295,16 @@ public final class TvInputManager { Log.w(TAG, "The session has been already released"); return; } - mAudioTracks.clear(); - mVideoTracks.clear(); - mSubtitleTracks.clear(); - mSelectedAudioTrackId = null; - mSelectedVideoTrackId = null; - mSelectedSubtitleTrackId = null; + synchronized (mTrackLock) { + mAudioTracks.clear(); + mVideoTracks.clear(); + mSubtitleTracks.clear(); + mSelectedAudioTrackId = null; + mSelectedVideoTrackId = null; + mSelectedSubtitleTrackId = null; + mVideoWidth = 0; + mVideoHeight = 0; + } try { mService.tune(mToken, channelUri, params, mUserId); } catch (RemoteException e) { @@ -1314,23 +1340,25 @@ public final class TvInputManager { * @see #getTracks */ public void selectTrack(int type, String trackId) { - if (type == TvTrackInfo.TYPE_AUDIO) { - if (trackId != null && !containsTrack(mAudioTracks, trackId)) { - Log.w(TAG, "Invalid audio trackId: " + trackId); - return; - } - } else if (type == TvTrackInfo.TYPE_VIDEO) { - if (trackId != null && !containsTrack(mVideoTracks, trackId)) { - Log.w(TAG, "Invalid video trackId: " + trackId); - return; - } - } else if (type == TvTrackInfo.TYPE_SUBTITLE) { - if (trackId != null && !containsTrack(mSubtitleTracks, trackId)) { - Log.w(TAG, "Invalid subtitle trackId: " + trackId); - return; + synchronized (mTrackLock) { + if (type == TvTrackInfo.TYPE_AUDIO) { + if (trackId != null && !containsTrack(mAudioTracks, trackId)) { + Log.w(TAG, "Invalid audio trackId: " + trackId); + return; + } + } else if (type == TvTrackInfo.TYPE_VIDEO) { + if (trackId != null && !containsTrack(mVideoTracks, trackId)) { + Log.w(TAG, "Invalid video trackId: " + trackId); + return; + } + } else if (type == TvTrackInfo.TYPE_SUBTITLE) { + if (trackId != null && !containsTrack(mSubtitleTracks, trackId)) { + Log.w(TAG, "Invalid subtitle trackId: " + trackId); + return; + } + } else { + throw new IllegalArgumentException("invalid type: " + type); } - } else { - throw new IllegalArgumentException("invalid type: " + type); } if (mToken == null) { Log.w(TAG, "The session has been already released"); @@ -1361,21 +1389,23 @@ public final class TvInputManager { * @return the list of tracks for the given type. */ public List<TvTrackInfo> getTracks(int type) { - if (type == TvTrackInfo.TYPE_AUDIO) { - if (mAudioTracks == null) { - return null; - } - return mAudioTracks; - } else if (type == TvTrackInfo.TYPE_VIDEO) { - if (mVideoTracks == null) { - return null; - } - return mVideoTracks; - } else if (type == TvTrackInfo.TYPE_SUBTITLE) { - if (mSubtitleTracks == null) { - return null; + synchronized (mTrackLock) { + if (type == TvTrackInfo.TYPE_AUDIO) { + if (mAudioTracks == null) { + return null; + } + return new ArrayList<TvTrackInfo>(mAudioTracks); + } else if (type == TvTrackInfo.TYPE_VIDEO) { + if (mVideoTracks == null) { + return null; + } + return new ArrayList<TvTrackInfo>(mVideoTracks); + } else if (type == TvTrackInfo.TYPE_SUBTITLE) { + if (mSubtitleTracks == null) { + return null; + } + return new ArrayList<TvTrackInfo>(mSubtitleTracks); } - return mSubtitleTracks; } throw new IllegalArgumentException("invalid type: " + type); } @@ -1388,17 +1418,89 @@ public final class TvInputManager { * @see #selectTrack */ public String getSelectedTrack(int type) { - if (type == TvTrackInfo.TYPE_AUDIO) { - return mSelectedAudioTrackId; - } else if (type == TvTrackInfo.TYPE_VIDEO) { - return mSelectedVideoTrackId; - } else if (type == TvTrackInfo.TYPE_SUBTITLE) { - return mSelectedSubtitleTrackId; + synchronized (mTrackLock) { + if (type == TvTrackInfo.TYPE_AUDIO) { + return mSelectedAudioTrackId; + } else if (type == TvTrackInfo.TYPE_VIDEO) { + return mSelectedVideoTrackId; + } else if (type == TvTrackInfo.TYPE_SUBTITLE) { + return mSelectedSubtitleTrackId; + } } throw new IllegalArgumentException("invalid type: " + type); } /** + * Responds to onTracksChanged() and updates the internal track information. Returns true if + * there is an update. + */ + boolean updateTracks(List<TvTrackInfo> tracks) { + synchronized (mTrackLock) { + mAudioTracks.clear(); + mVideoTracks.clear(); + mSubtitleTracks.clear(); + for (TvTrackInfo track : tracks) { + if (track.getType() == TvTrackInfo.TYPE_AUDIO) { + mAudioTracks.add(track); + } else if (track.getType() == TvTrackInfo.TYPE_VIDEO) { + mVideoTracks.add(track); + } else if (track.getType() == TvTrackInfo.TYPE_SUBTITLE) { + mSubtitleTracks.add(track); + } + } + return !mAudioTracks.isEmpty() || !mVideoTracks.isEmpty() + || !mSubtitleTracks.isEmpty(); + } + } + + /** + * Responds to onTrackSelected() and updates the internal track selection information. + * Returns true if there is an update. + */ + boolean updateTrackSelection(int type, String trackId) { + synchronized (mTrackLock) { + if (type == TvTrackInfo.TYPE_AUDIO && trackId != mSelectedAudioTrackId) { + mSelectedAudioTrackId = trackId; + return true; + } else if (type == TvTrackInfo.TYPE_VIDEO && trackId != mSelectedVideoTrackId) { + mSelectedVideoTrackId = trackId; + return true; + } else if (type == TvTrackInfo.TYPE_SUBTITLE + && trackId != mSelectedSubtitleTrackId) { + mSelectedSubtitleTrackId = trackId; + return true; + } + } + return false; + } + + /** + * Returns the new/updated video track that contains new video size information. Returns + * null if there is no video track to notify. Subsequent calls of this method results in a + * non-null video track returned only by the first call and null returned by following + * calls. The caller should immediately notify of the video size change upon receiving the + * track. + */ + TvTrackInfo getVideoTrackToNotify() { + synchronized (mTrackLock) { + if (!mVideoTracks.isEmpty() && mSelectedVideoTrackId != null) { + for (TvTrackInfo track : mVideoTracks) { + if (track.getId().equals(mSelectedVideoTrackId)) { + int videoWidth = track.getVideoWidth(); + int videoHeight = track.getVideoHeight(); + if (mVideoWidth != videoWidth || mVideoHeight != videoHeight) { + mVideoWidth = videoWidth; + mVideoHeight = videoHeight; + return track; + } + } + } + } + } + return null; + } + + /** * Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle) * TvInputService.Session.appPrivateCommand()} on the current TvView. * diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java index 4f8facbbd502..5d5ea027f72a 100644 --- a/media/java/android/media/tv/TvInputService.java +++ b/media/java/android/media/tv/TvInputService.java @@ -332,8 +332,13 @@ public abstract class TvInputService extends Service { } /** - * Sends the change on the track information. This is expected to be called whenever a track - * is added/removed and the metadata of a track is modified. + * Sends the list of all audio/video/subtitle tracks. The is used by the framework to + * maintain the track information for a given session, which in turn is used by + * {@link TvView#getTracks} for the application to retrieve metadata for a given track type. + * The TV input service must call this method as soon as the track information becomes + * available or is updated. Note that in a case where a part of the information for a + * certain track is updated, it is not necessary to create a new {@link TvTrackInfo} object + * with a different track ID. * * @param tracks A list which includes track information. * @throws IllegalArgumentException if {@code tracks} contains redundant tracks. @@ -364,8 +369,12 @@ public abstract class TvInputService extends Service { } /** - * Sends the ID of the selected track for a given track type. This is expected to be called - * whenever there is a change on track selection. + * Sends the type and ID of a selected track. This is used to inform the application that a + * specific track is selected. The TV input service must call this method as soon as a track + * is selected either by default or in response to a call to {@link #onSelectTrack}. The + * selected track ID for a given type is maintained in the framework until the next call to + * this method even after the entire track list is updated (but is reset when the session is + * tuned to a new channel), so care must be taken not to result in an obsolete track ID. * * @param type The type of the selected track. The type can be * {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or @@ -1067,9 +1076,19 @@ public abstract class TvInputService extends Service { /** * Base class for a TV input session which represents an external device connected to a - * hardware TV input. Once TV input returns an implementation of this class on - * {@link #onCreateSession(String)}, the framework will create a hardware session and forward - * the application's surface to the hardware TV input. + * hardware TV input. + * <p> + * This class is for an input which provides channels for the external set-top box to the + * application. Once a TV input returns an implementation of this class on + * {@link #onCreateSession(String)}, the framework will create a separate session for + * a hardware TV Input (e.g. HDMI 1) and forward the application's surface to the session so + * that the user can see the screen of the hardware TV Input when she tunes to a channel from + * this TV input. The implementation of this class is expected to change the channel of the + * external set-top box via a proprietary protocol when {@link HardwareSession#onTune(Uri)} is + * requested by the application. + * </p><p> + * Note that this class is not for inputs for internal hardware like built-in tuner and HDMI 1. + * </p> * @see #onCreateSession(String) */ public abstract static class HardwareSession extends Session { diff --git a/media/java/android/media/tv/TvStreamConfig.java b/media/java/android/media/tv/TvStreamConfig.java index a7e7e44ac6e6..1bdc63eb0e97 100644 --- a/media/java/android/media/tv/TvStreamConfig.java +++ b/media/java/android/media/tv/TvStreamConfig.java @@ -33,7 +33,6 @@ public class TvStreamConfig implements Parcelable { private int mStreamId; private int mType; - // TODO: Revisit if max widht/height really make sense. private int mMaxWidth; private int mMaxHeight; /** @@ -166,4 +165,17 @@ public class TvStreamConfig implements Parcelable { return config; } } + + @Override + public boolean equals(Object obj) { + if (obj == null) return false; + if (!(obj instanceof TvStreamConfig)) return false; + + TvStreamConfig config = (TvStreamConfig) obj; + return config.mGeneration == mGeneration + && config.mStreamId == mStreamId + && config.mType == mType + && config.mMaxWidth == mMaxWidth + && config.mMaxHeight == mMaxHeight; + } } diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java index 0949b1af9dc8..f9d84c1b037f 100644 --- a/media/java/android/media/tv/TvView.java +++ b/media/java/android/media/tv/TvView.java @@ -59,8 +59,6 @@ public class TvView extends ViewGroup { private static final String TAG = "TvView"; private static final boolean DEBUG = false; - private static final int VIDEO_SIZE_VALUE_UNKNOWN = 0; - private static final int ZORDER_MEDIA = 0; private static final int ZORDER_MEDIA_OVERLAY = 1; private static final int ZORDER_ON_TOP = 2; @@ -69,7 +67,7 @@ public class TvView extends ViewGroup { private static final int CAPTION_ENABLED = 1; private static final int CAPTION_DISABLED = 2; - private static final WeakReference<TvView> NULL_TV_VIEW = new WeakReference(null); + private static final WeakReference<TvView> NULL_TV_VIEW = new WeakReference<>(null); private static final Object sMainTvViewLock = new Object(); private static WeakReference<TvView> sMainTvView = NULL_TV_VIEW; @@ -86,8 +84,10 @@ public class TvView extends ViewGroup { private OnUnhandledInputEventListener mOnUnhandledInputEventListener; private boolean mHasStreamVolume; private float mStreamVolume; - private int mVideoWidth = VIDEO_SIZE_VALUE_UNKNOWN; - private int mVideoHeight = VIDEO_SIZE_VALUE_UNKNOWN; + private int mCaptionEnabled; + private String mAppPrivateCommandAction; + private Bundle mAppPrivateCommandData; + private boolean mSurfaceChanged; private int mSurfaceFormat; private int mSurfaceWidth; @@ -100,7 +100,6 @@ public class TvView extends ViewGroup { private int mSurfaceViewRight; private int mSurfaceViewTop; private int mSurfaceViewBottom; - private int mCaptionEnabled; private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() { @Override @@ -197,7 +196,7 @@ public class TvView extends ViewGroup { @SystemApi public void setMain() { synchronized (sMainTvViewLock) { - sMainTvView = new WeakReference(this); + sMainTvView = new WeakReference<>(this); if (hasWindowFocus() && mSession != null) { mSession.setMain(); } @@ -291,7 +290,7 @@ public class TvView extends ViewGroup { } synchronized (sMainTvViewLock) { if (sMainTvView.get() == null) { - sMainTvView = new WeakReference(this); + sMainTvView = new WeakReference<>(this); } } if (mSessionCallback != null && mSessionCallback.mInputId.equals(inputId)) { @@ -421,10 +420,10 @@ public class TvView extends ViewGroup { * Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle) * TvInputService.Session.appPrivateCommand()} on the current TvView. * - * @param action Name of the command to be performed. This <em>must</em> be a scoped name, i.e. - * prefixed with a package name you own, so that different developers will not create - * conflicting commands. - * @param data Any data to include with the command. + * @param action The name of the private command to send. This <em>must</em> be a scoped name, + * i.e. prefixed with a package name you own, so that different developers will not + * create conflicting commands. + * @param data An optional bundle to send with the command. * @hide */ @SystemApi @@ -434,6 +433,13 @@ public class TvView extends ViewGroup { } if (mSession != null) { mSession.sendAppPrivateCommand(action, data); + } else { + Log.w(TAG, "sendAppPrivateCommand - session not created (action " + action + " cached)"); + if (mAppPrivateCommandAction != null) { + Log.w(TAG, "previous cached action " + action + " removed"); + } + mAppPrivateCommandAction = action; + mAppPrivateCommandData = data; } } @@ -619,6 +625,9 @@ public class TvView extends ViewGroup { } private void release() { + mAppPrivateCommandAction = null; + mAppPrivateCommandData = null; + setSessionSurface(null); removeSessionOverlayView(); mUseRequestedSurfaceLayout = false; @@ -703,19 +712,8 @@ public class TvView extends ViewGroup { } /** - * This is invoked when the view is tuned to a specific channel and starts decoding video - * stream from there. It is also called later when the video size is changed. - * - * @param inputId The ID of the TV input bound to this view. - * @param width The width of the video. - * @param height The height of the video. - */ - public void onVideoSizeChanged(String inputId, int width, int height) { - } - - /** * This is invoked when the channel of this TvView is changed by the underlying TV input - * with out any {@link TvView#tune(String, Uri)} request. + * without any {@link TvView#tune(String, Uri)} request. * * @param inputId The ID of the TV input bound to this view. * @param channelUri The URI of a channel. @@ -745,6 +743,18 @@ public class TvView extends ViewGroup { } /** + * This is invoked when the video size has been changed. It is also called when the first + * time video size information becomes available after this view is tuned to a specific + * channel. + * + * @param inputId The ID of the TV input bound to this view. + * @param width The width of the video. + * @param height The height of the video. + */ + public void onVideoSizeChanged(String inputId, int width, int height) { + } + + /** * This is called when the video is available, so the TV input starts the playback. * * @param inputId The ID of the TV input bound to this view. @@ -828,16 +838,17 @@ public class TvView extends ViewGroup { @Override public void onSessionCreated(Session session) { + if (DEBUG) { + Log.d(TAG, "onSessionCreated()"); + } if (this != mSessionCallback) { + Log.w(TAG, "onSessionCreated - session already created"); // This callback is obsolete. if (session != null) { session.release(); } return; } - if (DEBUG) { - Log.d(TAG, "onSessionCreated()"); - } mSession = session; if (session != null) { synchronized (sMainTvViewLock) { @@ -862,6 +873,12 @@ public class TvView extends ViewGroup { if (mHasStreamVolume) { mSession.setStreamVolume(mStreamVolume); } + if (mAppPrivateCommandAction != null) { + mSession.sendAppPrivateCommand( + mAppPrivateCommandAction, mAppPrivateCommandData); + mAppPrivateCommandAction = null; + mAppPrivateCommandData = null; + } } else { mSessionCallback = null; if (mCallback != null) { @@ -872,7 +889,11 @@ public class TvView extends ViewGroup { @Override public void onSessionReleased(Session session) { + if (DEBUG) { + Log.d(TAG, "onSessionReleased()"); + } if (this != mSessionCallback) { + Log.w(TAG, "onSessionReleased - session not created"); return; } mOverlayViewCreated = false; @@ -886,12 +907,13 @@ public class TvView extends ViewGroup { @Override public void onChannelRetuned(Session session, Uri channelUri) { - if (this != mSessionCallback) { - return; - } if (DEBUG) { Log.d(TAG, "onChannelChangedByTvInput(" + channelUri + ")"); } + if (this != mSessionCallback) { + Log.w(TAG, "onChannelRetuned - session not created"); + return; + } if (mCallback != null) { mCallback.onChannelRetuned(mInputId, channelUri); } @@ -899,12 +921,13 @@ public class TvView extends ViewGroup { @Override public void onTracksChanged(Session session, List<TvTrackInfo> tracks) { + if (DEBUG) { + Log.d(TAG, "onTracksChanged(" + tracks + ")"); + } if (this != mSessionCallback) { + Log.w(TAG, "onTracksChanged - session not created"); return; } - if (DEBUG) { - Log.d(TAG, "onTracksChanged()"); - } if (mCallback != null) { mCallback.onTracksChanged(mInputId, tracks); } @@ -912,26 +935,41 @@ public class TvView extends ViewGroup { @Override public void onTrackSelected(Session session, int type, String trackId) { + if (DEBUG) { + Log.d(TAG, "onTrackSelected(type=" + type + ", trackId=" + trackId + ")"); + } if (this != mSessionCallback) { + Log.w(TAG, "onTrackSelected - session not created"); return; } - if (DEBUG) { - Log.d(TAG, "onTrackSelected()"); - } - // TODO: Update the video size when the type is TYPE_VIDEO. if (mCallback != null) { mCallback.onTrackSelected(mInputId, type, trackId); } } @Override - public void onVideoAvailable(Session session) { + public void onVideoSizeChanged(Session session, int width, int height) { + if (DEBUG) { + Log.d(TAG, "onVideoSizeChanged()"); + } if (this != mSessionCallback) { + Log.w(TAG, "onVideoSizeChanged - session not created"); return; } + if (mCallback != null) { + mCallback.onVideoSizeChanged(mInputId, width, height); + } + } + + @Override + public void onVideoAvailable(Session session) { if (DEBUG) { Log.d(TAG, "onVideoAvailable()"); } + if (this != mSessionCallback) { + Log.w(TAG, "onVideoAvailable - session not created"); + return; + } if (mCallback != null) { mCallback.onVideoAvailable(mInputId); } @@ -939,12 +977,13 @@ public class TvView extends ViewGroup { @Override public void onVideoUnavailable(Session session, int reason) { + if (DEBUG) { + Log.d(TAG, "onVideoUnavailable(reason=" + reason + ")"); + } if (this != mSessionCallback) { + Log.w(TAG, "onVideoUnavailable - session not created"); return; } - if (DEBUG) { - Log.d(TAG, "onVideoUnavailable(" + reason + ")"); - } if (mCallback != null) { mCallback.onVideoUnavailable(mInputId, reason); } @@ -952,12 +991,13 @@ public class TvView extends ViewGroup { @Override public void onContentAllowed(Session session) { - if (this != mSessionCallback) { - return; - } if (DEBUG) { Log.d(TAG, "onContentAllowed()"); } + if (this != mSessionCallback) { + Log.w(TAG, "onContentAllowed - session not created"); + return; + } if (mCallback != null) { mCallback.onContentAllowed(mInputId); } @@ -965,12 +1005,13 @@ public class TvView extends ViewGroup { @Override public void onContentBlocked(Session session, TvContentRating rating) { + if (DEBUG) { + Log.d(TAG, "onContentBlocked(rating=" + rating + ")"); + } if (this != mSessionCallback) { + Log.w(TAG, "onContentBlocked - session not created"); return; } - if (DEBUG) { - Log.d(TAG, "onContentBlocked()"); - } if (mCallback != null) { mCallback.onContentBlocked(mInputId, rating); } @@ -978,13 +1019,14 @@ public class TvView extends ViewGroup { @Override public void onLayoutSurface(Session session, int left, int top, int right, int bottom) { - if (this != mSessionCallback) { - return; - } if (DEBUG) { Log.d(TAG, "onLayoutSurface (left=" + left + ", top=" + top + ", right=" + right + ", bottom=" + bottom + ",)"); } + if (this != mSessionCallback) { + Log.w(TAG, "onLayoutSurface - session not created"); + return; + } mSurfaceViewLeft = left; mSurfaceViewTop = top; mSurfaceViewRight = right; @@ -995,12 +1037,13 @@ public class TvView extends ViewGroup { @Override public void onSessionEvent(Session session, String eventType, Bundle eventArgs) { - if (this != mSessionCallback) { - return; - } if (DEBUG) { Log.d(TAG, "onSessionEvent(" + eventType + ")"); } + if (this != mSessionCallback) { + Log.w(TAG, "onSessionEvent - session not created"); + return; + } if (mCallback != null) { mCallback.onEvent(mInputId, eventType, eventArgs); } diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp index 56467403179d..3b1b1d7875a1 100644 --- a/media/jni/android_media_MediaRecorder.cpp +++ b/media/jni/android_media_MediaRecorder.cpp @@ -182,7 +182,8 @@ static void android_media_MediaRecorder_setAudioSource(JNIEnv *env, jobject thiz, jint as) { ALOGV("setAudioSource(%d)", as); - if (as < AUDIO_SOURCE_DEFAULT || as >= AUDIO_SOURCE_CNT) { + if (as < AUDIO_SOURCE_DEFAULT || + (as >= AUDIO_SOURCE_CNT && as != AUDIO_SOURCE_FM_TUNER)) { jniThrowException(env, "java/lang/IllegalArgumentException", "Invalid audio source"); return; } diff --git a/media/tests/omxjpegdecoder/Android.mk b/media/tests/omxjpegdecoder/Android.mk deleted file mode 100644 index b0bc5d4a2e36..000000000000 --- a/media/tests/omxjpegdecoder/Android.mk +++ /dev/null @@ -1,45 +0,0 @@ -# Copyright (C) 2009 The Android Open Source Project -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -LOCAL_SRC_FILES := \ - omx_jpeg_decoder.cpp \ - jpeg_decoder_bench.cpp \ - StreamSource.cpp - -LOCAL_SHARED_LIBRARIES := \ - libcutils \ - libskia \ - libstagefright \ - libstagefright_foundation \ - libbinder \ - libutils \ - liblog \ - libjpeg - -LOCAL_C_INCLUDES := \ - $(TOP)/external/jpeg \ - $(TOP)/frameworks/base/media/libstagefright \ - $(TOP)/frameworks/base/include/ \ - $(TOP)/frameworks/base/ \ - $(TOP)/frameworks/native/include/media/openmax - -LOCAL_MODULE := jpeg_bench - -LOCAL_MODULE_TAGS := optional - -include $(BUILD_EXECUTABLE) diff --git a/media/tests/omxjpegdecoder/StreamSource.cpp b/media/tests/omxjpegdecoder/StreamSource.cpp deleted file mode 100644 index f764121a0dff..000000000000 --- a/media/tests/omxjpegdecoder/StreamSource.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <media/stagefright/foundation/ADebug.h> - -#include "StreamSource.h" - -namespace android { - -StreamSource::StreamSource(SkStream *stream) - : mStream(stream) { - CHECK(stream != NULL); - mSize = stream->getLength(); -} - -StreamSource::~StreamSource() { - delete mStream; - mStream = NULL; -} - -status_t StreamSource::initCheck() const { - return mStream != NULL ? OK : NO_INIT; -} - -ssize_t StreamSource::readAt(off64_t offset, void *data, size_t size) { - Mutex::Autolock autoLock(mLock); - - mStream->rewind(); - mStream->skip(offset); - ssize_t result = mStream->read(data, size); - - return result; -} - -status_t StreamSource::getSize(off64_t *size) { - *size = mSize; - return OK; -} - -} // namespace android diff --git a/media/tests/omxjpegdecoder/StreamSource.h b/media/tests/omxjpegdecoder/StreamSource.h deleted file mode 100644 index 980738590587..000000000000 --- a/media/tests/omxjpegdecoder/StreamSource.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef STREAM_SOURCE_H_ - -#define STREAM_SOURCE_H_ - -#include <stdio.h> - -#include <SkStream.h> -#include <media/stagefright/DataSource.h> -#include <media/stagefright/MediaErrors.h> -#include <utils/threads.h> - -namespace android { - -class StreamSource : public DataSource { -public: - // Pass the ownership of SkStream to StreamSource. - StreamSource(SkStream *SkStream); - virtual status_t initCheck() const; - virtual ssize_t readAt(off64_t offset, void *data, size_t size); - virtual status_t getSize(off64_t *size); - -protected: - virtual ~StreamSource(); - -private: - SkStream *mStream; - size_t mSize; - Mutex mLock; - - StreamSource(const StreamSource &); - StreamSource &operator=(const StreamSource &); -}; - -} // namespace android - -#endif // STREAM_SOURCE_H_ diff --git a/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp b/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp deleted file mode 100644 index de6294dabaeb..000000000000 --- a/media/tests/omxjpegdecoder/jpeg_decoder_bench.cpp +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "OmxJpegDecoder" -#include <sys/time.h> -#include <utils/Log.h> - -#include <binder/ProcessState.h> - -#include "SkBitmap.h" -#include "SkImageDecoder.h" -#include "SkStream.h" -#include "omx_jpeg_decoder.h" - -class SkJPEGImageDecoder : public SkImageDecoder { -public: - virtual Format getFormat() const { - return kJPEG_Format; - } - -protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode); -}; - -int nullObjectReturn(const char msg[]) { - if (msg) { - SkDebugf("--- %s\n", msg); - } - return -1; -} - -static int64_t getNowUs() { - struct timeval tv; - gettimeofday(&tv, NULL); - - return tv.tv_usec + (int64_t) tv.tv_sec * 1000000; -} - -int testDecodeBounds(SkImageDecoder* decoder, SkStream* stream, - SkBitmap* bitmap) { - int64_t startTime = getNowUs(); - SkColorType prefColorType = kN32_SkColorType; - SkImageDecoder::Mode decodeMode = SkImageDecoder::kDecodeBounds_Mode; - - // Decode the input stream and then use the bitmap. - if (!decoder->decode(stream, bitmap, prefColorType, decodeMode)) { - return nullObjectReturn("decoder->decode returned false"); - } else { - int64_t delay = getNowUs() - startTime; - printf("WidthxHeight: %dx%d\n", bitmap->width(), bitmap->height()); - printf("Decoding Time in BoundsMode %.1f msec.\n", delay / 1000.0f); - return 0; - } -} - -int testDecodePixels(SkImageDecoder* decoder, SkStream* stream, - SkBitmap* bitmap) { - int64_t startTime = getNowUs(); - SkColorType prefColorType = kN32_SkColorType; - SkImageDecoder::Mode decodeMode = SkImageDecoder::kDecodePixels_Mode; - - // Decode the input stream and then use the bitmap. - if (!decoder->decode(stream, bitmap, prefColorType, decodeMode)) { - return nullObjectReturn("decoder->decode returned false"); - } else { - int64_t delay = getNowUs() - startTime; - printf("Decoding Time in PixelsMode %.1f msec.\n", delay / 1000.0f); - const char* filename = "/sdcard/omxJpegDecodedBitmap.rgba"; - return storeBitmapToFile(bitmap, filename); - } -} - -int testDecoder(SkImageDecoder* decoder, char* filename) { - // test DecodeMode == Pixels - SkStream* stream = new SkFILEStream(filename); - SkBitmap* bitmap = new SkBitmap; - testDecodePixels(decoder, stream, bitmap); - delete bitmap; - - // test DecodeMode == Bounds - stream = new SkFILEStream(filename); - bitmap = new SkBitmap; - testDecodeBounds(decoder, stream, bitmap); - delete bitmap; - - delete decoder; - return 0; -} - -int main(int argc, char** argv) { - android::ProcessState::self()->startThreadPool(); - - printf("Decoding jpeg with libjpeg...\n"); - SkJPEGImageDecoder* libjpeg = new SkJPEGImageDecoder; - testDecoder(libjpeg, argv[1]); - - printf("\nDecoding jpeg with OMX...\n"); - OmxJpegImageDecoder* omx = new OmxJpegImageDecoder; - testDecoder(omx, argv[1]); - return 0; -} diff --git a/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp b/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp deleted file mode 100644 index 229bfdb1a655..000000000000 --- a/media/tests/omxjpegdecoder/omx_jpeg_decoder.cpp +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "OmxJpegDecoder" -#include <sys/time.h> -#include <utils/Log.h> - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <binder/IServiceManager.h> -#include <binder/ProcessState.h> -#include <media/IMediaPlayerService.h> -#include <media/stagefright/foundation/ADebug.h> -#include <media/stagefright/MediaSource.h> -#include <media/stagefright/MetaData.h> -#include <media/stagefright/OMXClient.h> -#include <media/stagefright/OMXCodec.h> -#include <SkImage.h> -#include <SkMallocPixelRef.h> - -#include "omx_jpeg_decoder.h" -#include "StreamSource.h" - -using namespace android; - -static void getJpegOutput(MediaBuffer* buffer, const char* filename) { - int size = buffer->range_length(); - int offset = buffer->range_offset(); - FILE *pFile = fopen(filename, "w+"); - - if (pFile == NULL) { - printf("Error: cannot open %s.\n", filename); - } else { - char* data = (char*) buffer->data(); - data += offset; - while (size > 0) { - int numChars = fwrite(data, sizeof(char), 1024, pFile); - int numBytes = numChars * sizeof(char); - size -= numBytes; - data += numBytes; - } - fclose(pFile); - } - return; -} - -extern int storeBitmapToFile(SkBitmap* bitmap, const char* filename) { - bitmap->lockPixels(); - uint8_t* data = (uint8_t *)bitmap->getPixels(); - int size = bitmap->getSize(); - FILE* fp = fopen(filename, "w+"); - - if (NULL == fp) { - printf("Cannot open the output file! \n"); - return -1; - } else { - while (size > 0) { - int numChars = fwrite(data, sizeof(char), 1024, fp); - int numBytes = numChars * sizeof(char); - size -= numBytes; - data += numBytes; - } - fclose(fp); - } - return 0; -} - -static int64_t getNowUs() { - struct timeval tv; - gettimeofday(&tv, NULL); - - return (int64_t)tv.tv_usec + tv.tv_sec * 1000000; -} - -OmxJpegImageDecoder::OmxJpegImageDecoder() { - status_t err = mClient.connect(); - CHECK_EQ(err, (status_t)OK); -} - -OmxJpegImageDecoder::~OmxJpegImageDecoder() { - mClient.disconnect(); -} - -bool OmxJpegImageDecoder::onDecode(SkStream* stream, - SkBitmap* bm, Mode mode) { - sp<MediaSource> source = prepareMediaSource(stream); - sp<MetaData> meta = source->getFormat(); - int width; - int height; - meta->findInt32(kKeyWidth, &width); - meta->findInt32(kKeyHeight, &height); - configBitmapSize( - bm, getPrefColorType(k32Bit_SrcDepth, false), - width, height); - - // mode == DecodeBounds - if (mode == SkImageDecoder::kDecodeBounds_Mode) { - return true; - } - - // mode == DecodePixels - if (!this->allocPixelRef(bm, NULL)) { - ALOGI("Cannot allocPixelRef()!"); - return false; - } - - sp<MediaSource> decoder = getDecoder(&mClient, source); - return decodeSource(decoder, source, bm); -} - -JPEGSource* OmxJpegImageDecoder::prepareMediaSource(SkStream* stream) { - DataSource::RegisterDefaultSniffers(); - sp<DataSource> dataSource = new StreamSource(stream); - return new JPEGSource(dataSource); -} - -sp<MediaSource> OmxJpegImageDecoder::getDecoder( - OMXClient *client, const sp<MediaSource>& source) { - sp<MetaData> meta = source->getFormat(); - sp<MediaSource> decoder = OMXCodec::Create( - client->interface(), meta, false /* createEncoder */, source); - - CHECK(decoder != NULL); - return decoder; -} - -bool OmxJpegImageDecoder::decodeSource(sp<MediaSource> decoder, - const sp<MediaSource>& source, SkBitmap* bm) { - status_t rt = decoder->start(); - if (rt != OK) { - ALOGE("Cannot start OMX Decoder!"); - return false; - } - int64_t startTime = getNowUs(); - MediaBuffer *buffer; - - // decode source - status_t err = decoder->read(&buffer, NULL); - int64_t duration = getNowUs() - startTime; - - if (err != OK) { - CHECK(buffer == NULL); - } - printf("Duration in decoder->read(): %.1f (msecs). \n", - duration / 1E3 ); - - // Copy pixels from buffer to bm. - // May need to check buffer->rawBytes() == bm->rawBytes(). - CHECK_EQ(buffer->size(), bm->getSize()); - memcpy(bm->getPixels(), buffer->data(), buffer->size()); - buffer->release(); - decoder->stop(); - - return true; -} - -void OmxJpegImageDecoder::configBitmapSize(SkBitmap* bm, SkColorType pref, - int width, int height) { - // Set the color space to ARGB_8888 for now (ignoring pref) - // because of limitation in hardware support. - bm->setInfo(SkImageInfo::MakeN32(width, height, kOpaque_SkAlphaType)); -} diff --git a/media/tests/omxjpegdecoder/omx_jpeg_decoder.h b/media/tests/omxjpegdecoder/omx_jpeg_decoder.h deleted file mode 100644 index e487245fd551..000000000000 --- a/media/tests/omxjpegdecoder/omx_jpeg_decoder.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OMXJPEGIMAGEDECODER -#define OMXJPEGIMAGEDECODER - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include <media/stagefright/JPEGSource.h> -#include <media/stagefright/MediaSource.h> -#include <media/stagefright/OMXClient.h> -#include <media/stagefright/OMXCodec.h> -#include <SkImageDecoder.h> -#include <SkStream.h> - -using namespace android; - -extern int storeBitmapToFile(SkBitmap* bitmap, const char* filename); - -class OmxJpegImageDecoder : public SkImageDecoder { -public: - OmxJpegImageDecoder(); - ~OmxJpegImageDecoder(); - - virtual Format getFormat() const { - return kJPEG_Format; - } - -protected: - virtual bool onDecode(SkStream* stream, SkBitmap* bm, Mode mode); - -private: - JPEGSource* prepareMediaSource(SkStream* stream); - sp<MediaSource> getDecoder(OMXClient* client, const sp<MediaSource>& source); - bool decodeSource(sp<MediaSource> decoder, const sp<MediaSource>& source, - SkBitmap* bm); - void configBitmapSize(SkBitmap* bm, SkColorType, int width, int height); - - OMXClient mClient; -}; - -#endif diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java index fef1f4a2871b..219de383ee91 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -574,7 +574,8 @@ public class DocumentsActivity extends Activity { // Only sort by size when visible sortSize.setVisible(mState.showSize); - final boolean searchVisible; + boolean searchVisible; + boolean fileSizeVisible = mState.action != ACTION_MANAGE; if (mState.action == ACTION_CREATE || mState.action == ACTION_OPEN_TREE) { createDir.setVisible(cwd != null && cwd.isCreateSupported()); searchVisible = false; @@ -583,6 +584,7 @@ public class DocumentsActivity extends Activity { if (cwd == null) { grid.setVisible(false); list.setVisible(false); + fileSizeVisible = false; } if (mState.action == ACTION_CREATE) { @@ -604,7 +606,7 @@ public class DocumentsActivity extends Activity { ? R.string.menu_file_size_hide : R.string.menu_file_size_show); advanced.setVisible(mState.action != ACTION_MANAGE); - fileSize.setVisible(mState.action != ACTION_MANAGE); + fileSize.setVisible(fileSizeVisible); return true; } diff --git a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java index c323a3326d7f..066acac2c22d 100644 --- a/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java +++ b/packages/ExternalStorageProvider/src/com/android/externalstorage/ExternalStorageProvider.java @@ -154,7 +154,12 @@ public class ExternalStorageProvider extends DocumentsProvider { if (ROOT_ID_PRIMARY_EMULATED.equals(rootId)) { root.title = getContext().getString(R.string.root_internal_storage); } else { - root.title = volume.getUserLabel(); + final String userLabel = volume.getUserLabel(); + if (!TextUtils.isEmpty(userLabel)) { + root.title = userLabel; + } else { + root.title = volume.getDescription(getContext()); + } } root.docId = getDocIdForFile(path); mRoots.add(root); diff --git a/packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml b/packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml index 796cefbe68c3..63694a82fd72 100644 --- a/packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml +++ b/packages/Keyguard/test/SampleTrustAgent/res/layout/sample_trust_agent_settings.xml @@ -44,4 +44,18 @@ android:paddingTop="8dp" android:paddingBottom="8dp" android:text="Report unlock attempts" /> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content"> + <Button android:id="@+id/check_trusted" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Keyguard in trusted state?" /> + <TextView android:id="@+id/check_trusted_result" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_weight="1" /> + </LinearLayout> + </LinearLayout>
\ No newline at end of file diff --git a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java index bea74ab00655..39a599e726f0 100644 --- a/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java +++ b/packages/Keyguard/test/SampleTrustAgent/src/com/android/trustagent/test/SampleTrustAgentSettings.java @@ -18,10 +18,12 @@ package com.android.trustagent.test; import android.annotation.Nullable; import android.app.Activity; +import android.app.KeyguardManager; import android.os.Bundle; import android.view.View; import android.widget.CheckBox; import android.widget.CompoundButton; +import android.widget.TextView; public class SampleTrustAgentSettings extends Activity implements View.OnClickListener, CompoundButton.OnCheckedChangeListener { @@ -30,21 +32,31 @@ public class SampleTrustAgentSettings extends Activity implements View.OnClickLi private CheckBox mReportUnlockAttempts; private CheckBox mManagingTrust; + private TextView mCheckTrustedStateResult; + + private KeyguardManager mKeyguardManager; + @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + + mKeyguardManager = (KeyguardManager) getSystemService(KEYGUARD_SERVICE); + setContentView(R.layout.sample_trust_agent_settings); findViewById(R.id.enable_trust).setOnClickListener(this); findViewById(R.id.revoke_trust).setOnClickListener(this); findViewById(R.id.crash).setOnClickListener(this); + findViewById(R.id.check_trusted).setOnClickListener(this); mReportUnlockAttempts = (CheckBox) findViewById(R.id.report_unlock_attempts); mReportUnlockAttempts.setOnCheckedChangeListener(this); mManagingTrust = (CheckBox) findViewById(R.id.managing_trust); mManagingTrust.setOnCheckedChangeListener(this); + + mCheckTrustedStateResult = (TextView) findViewById(R.id.check_trusted_result); } @Override @@ -52,6 +64,7 @@ public class SampleTrustAgentSettings extends Activity implements View.OnClickLi super.onResume(); mReportUnlockAttempts.setChecked(SampleTrustAgent.getReportUnlockAttempts(this)); mManagingTrust.setChecked(SampleTrustAgent.getIsManagingTrust(this)); + updateTrustedState(); } @Override @@ -64,6 +77,8 @@ public class SampleTrustAgentSettings extends Activity implements View.OnClickLi SampleTrustAgent.sendRevokeTrust(this); } else if (id == R.id.crash) { throw new RuntimeException("crash"); + } else if (id == R.id.check_trusted) { + updateTrustedState(); } } @@ -75,4 +90,9 @@ public class SampleTrustAgentSettings extends Activity implements View.OnClickLi SampleTrustAgent.setIsManagingTrust(this, isChecked); } } + + private void updateTrustedState() { + mCheckTrustedStateResult.setText(Boolean.toString( + mKeyguardManager.isKeyguardInTrustedState())); + } } diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java index 85b2490c68fb..a54334aeba52 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java +++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java @@ -24,6 +24,7 @@ import android.content.ServiceConnection; import android.graphics.Bitmap; import android.graphics.Color; import android.graphics.drawable.BitmapDrawable; +import android.net.Uri; import android.os.AsyncTask; import android.os.IBinder; import android.os.ParcelFileDescriptor; @@ -110,13 +111,12 @@ public final class PageContentRepository { mRenderer.close(callback); } - public void destroy(Runnable callback) { - throwIfNotClosed(); + public void destroy() { mState = STATE_DESTROYED; if (DEBUG) { Log.i(LOG_TAG, "STATE_DESTROYED"); } - doDestroy(callback); + mRenderer.destroy(); } public void startPreload(int firstShownPage, int lastShownPage) { @@ -163,21 +163,13 @@ public final class PageContentRepository { try { if (mState != STATE_DESTROYED) { mCloseGuard.warnIfOpen(); - doDestroy(null); + destroy(); } } finally { super.finalize(); } } - private void doDestroy(Runnable callback) { - mState = STATE_DESTROYED; - if (DEBUG) { - Log.i(LOG_TAG, "STATE_DESTROYED"); - } - mRenderer.destroy(callback); - } - private void throwIfNotOpened() { if (mState != STATE_OPENED) { throw new IllegalStateException("Not opened"); @@ -428,6 +420,7 @@ public final class PageContentRepository { private IPdfRenderer mRenderer; private boolean mBoundToService; + private boolean mDestroyed; public AsyncRenderer(Context context, OnMalformedPdfFileListener malformedPdfFileListener) { mContext = context; @@ -441,7 +434,6 @@ public final class PageContentRepository { @Override public void onServiceConnected(ComponentName name, IBinder service) { - mBoundToService = true; synchronized (mLock) { mRenderer = IPdfRenderer.Stub.asInterface(service); mLock.notifyAll(); @@ -465,9 +457,15 @@ public final class PageContentRepository { new AsyncTask<Void, Void, Integer>() { @Override protected void onPreExecute() { + if (mDestroyed) { + cancel(true); + return; + } Intent intent = new Intent(PdfManipulationService.ACTION_GET_RENDERER); intent.setClass(mContext, PdfManipulationService.class); + intent.setData(Uri.fromParts("fake-scheme", String.valueOf(hashCode()), null)); mContext.bindService(intent, AsyncRenderer.this, Context.BIND_AUTO_CREATE); + mBoundToService = true; } @Override @@ -513,6 +511,14 @@ public final class PageContentRepository { new AsyncTask<Void, Void, Void>() { @Override + protected void onPreExecute() { + if (mDestroyed) { + cancel(true); + return; + } + } + + @Override protected Void doInBackground(Void... params) { synchronized (mLock) { try { @@ -534,27 +540,14 @@ public final class PageContentRepository { }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); } - public void destroy(final Runnable callback) { - new AsyncTask<Void, Void, Void>() { - @Override - protected Void doInBackground(Void... params) { - return null; - } - - @Override - public void onPostExecute(Void result) { - if (mBoundToService) { - mBoundToService = false; - mContext.unbindService(AsyncRenderer.this); - } - mPageContentCache.invalidate(); - mPageContentCache.clear(); - if (callback != null) { - callback.run(); - } - - } - }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR); + public void destroy() { + if (mBoundToService) { + mBoundToService = false; + mContext.unbindService(AsyncRenderer.this); + } + mPageContentCache.invalidate(); + mPageContentCache.clear(); + mDestroyed = true; } public void startPreload(int firstShownPage, int lastShownPage, RenderSpec renderSpec) { diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java index 045a2f9ea2f2..2cc5e049e3aa 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java +++ b/packages/PrintSpooler/src/com/android/printspooler/model/PrintSpoolerService.java @@ -78,7 +78,7 @@ public final class PrintSpoolerService extends Service { private static final boolean DEBUG_PERSISTENCE = false; - private static final boolean PERSISTNECE_MANAGER_ENABLED = true; + private static final boolean PERSISTENCE_MANAGER_ENABLED = true; private static final long CHECK_ALL_PRINTJOBS_HANDLED_DELAY = 5000; @@ -728,7 +728,7 @@ public final class PrintSpoolerService extends Service { } public void writeStateLocked() { - if (!PERSISTNECE_MANAGER_ENABLED) { + if (!PERSISTENCE_MANAGER_ENABLED) { return; } if (mWriteStateScheduled) { @@ -935,7 +935,7 @@ public final class PrintSpoolerService extends Service { } public void readStateLocked() { - if (!PERSISTNECE_MANAGER_ENABLED) { + if (!PERSISTENCE_MANAGER_ENABLED) { return; } FileInputStream in = null; diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java index c53fcadde4e7..f6ace41d6e9d 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java +++ b/packages/PrintSpooler/src/com/android/printspooler/model/RemotePrintDocument.java @@ -137,7 +137,7 @@ public final class RemotePrintDocument { private final DeathRecipient mDeathRecipient = new DeathRecipient() { @Override public void binderDied() { - notifyPrintingAppDied(); + onPrintingAppDied(); } }; @@ -268,7 +268,7 @@ public final class RemotePrintDocument { mPrintDocumentAdapter.finish(); mState = STATE_FINISHED; } catch (RemoteException re) { - Log.e(LOG_TAG, "Error calling finish()", re); + Log.e(LOG_TAG, "Error calling finish()"); mState = STATE_FAILED; } } @@ -1108,7 +1108,8 @@ public final class RemotePrintDocument { } } - private void notifyPrintingAppDied() { + private void onPrintingAppDied() { + mState = STATE_FAILED; new Handler(mLooper).post(new Runnable() { @Override public void run() { @@ -1129,7 +1130,7 @@ public final class RemotePrintDocument { public void onDestroy() { final RemotePrintDocument document = mWeakDocument.get(); if (document != null) { - document.notifyPrintingAppDied(); + document.onPrintingAppDied(); } } } diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java index 8a65a2ef1652..02d2715c035f 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/FusedPrintersProvider.java @@ -48,6 +48,7 @@ import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -91,14 +92,14 @@ public final class FusedPrintersProvider extends Loader<List<PrinterInfo>> { mPersistenceManager.addPrinterAndWritePrinterHistory(printer); } - private void computeAndDeliverResult(ArrayMap<PrinterId, PrinterInfo> discoveredPrinters, - ArrayMap<PrinterId, PrinterInfo> favoritePrinters) { + private void computeAndDeliverResult(Map<PrinterId, PrinterInfo> discoveredPrinters, + List<PrinterInfo> favoritePrinters) { List<PrinterInfo> printers = new ArrayList<>(); // Add the updated favorite printers. final int favoritePrinterCount = favoritePrinters.size(); for (int i = 0; i < favoritePrinterCount; i++) { - PrinterInfo favoritePrinter = favoritePrinters.valueAt(i); + PrinterInfo favoritePrinter = favoritePrinters.get(i); PrinterInfo updatedPrinter = discoveredPrinters.remove( favoritePrinter.getId()); if (updatedPrinter != null) { @@ -215,21 +216,14 @@ public final class FusedPrintersProvider extends Loader<List<PrinterInfo>> { // printer to use its current name instead of the historical one. mPersistenceManager.updatePrintersHistoricalNamesIfNeeded(printers); - ArrayMap<PrinterId, PrinterInfo> printersMap = new ArrayMap<>(); + Map<PrinterId, PrinterInfo> printersMap = new LinkedHashMap<>(); final int printerCount = printers.size(); for (int i = 0; i < printerCount; i++) { PrinterInfo printer = printers.get(i); printersMap.put(printer.getId(), printer); } - ArrayMap<PrinterId, PrinterInfo> favoritePrintersMap = new ArrayMap<>(); - final int favoritePrinterCount = favoritePrinters.size(); - for (int i = 0; i < favoritePrinterCount; i++) { - PrinterInfo favoritePrinter = favoritePrinters.get(i); - favoritePrintersMap.put(favoritePrinter.getId(), favoritePrinter); - } - - computeAndDeliverResult(printersMap, favoritePrintersMap); + computeAndDeliverResult(printersMap, favoritePrinters); } @Override @@ -544,7 +538,7 @@ public final class FusedPrintersProvider extends Loader<List<PrinterInfo>> { mReadHistoryCompleted = true; // Deliver the printers. - updatePrinters(mDiscoverySession.getPrinters(), mHistoricalPrinters); + updatePrinters(mDiscoverySession.getPrinters(), mFavoritePrinters); // Loading the available printers if needed. loadInternal(); diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java index fbf72048133a..aa7956859f75 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PageAdapter.java @@ -484,9 +484,13 @@ public final class PageAdapter extends Adapter implements return selectedPages; } - public void destroy(Runnable callback) { - throwIfNotClosed(); - doDestroy(callback); + public void destroy() { + mPageContentRepository.destroy(); + mCloseGuard.close(); + mState = STATE_DESTROYED; + if (DEBUG) { + Log.i(LOG_TAG, "STATE_DESTROYED"); + } } @Override @@ -494,7 +498,7 @@ public final class PageAdapter extends Adapter implements try { if (mState != STATE_DESTROYED) { mCloseGuard.warnIfOpen(); - doDestroy(null); + destroy(); } } finally { super.finalize(); @@ -741,15 +745,6 @@ public final class PageAdapter extends Adapter implements mPageContentRepository.stopPreload(); } - private void doDestroy(Runnable callback) { - mPageContentRepository.destroy(callback); - mCloseGuard.close(); - mState = STATE_DESTROYED; - if (DEBUG) { - Log.i(LOG_TAG, "STATE_DESTROYED"); - } - } - private void throwIfNotOpened() { if (mState != STATE_OPENED) { throw new IllegalStateException("Not opened"); diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java index 01ea3c85534b..15ea9a73c665 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java @@ -1412,12 +1412,16 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat mCopiesEditText.setEnabled(true); mCopiesEditText.setFocusableInTouchMode(true); } else { + CharSequence text = mCopiesEditText.getText(); + if (TextUtils.isEmpty(text) || !MIN_COPIES_STRING.equals(text.toString())) { + mCopiesEditText.setText(MIN_COPIES_STRING); + } mCopiesEditText.setEnabled(false); mCopiesEditText.setFocusable(false); } if (mCopiesEditText.getError() == null && TextUtils.isEmpty(mCopiesEditText.getText())) { - mCopiesEditText.setText(String.valueOf(MIN_COPIES)); + mCopiesEditText.setText(MIN_COPIES_STRING); mCopiesEditText.requestFocus(); } } @@ -1612,15 +1616,9 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat mSpoolerProvider.destroy(); mPrintedDocument.finish(); mPrintedDocument.destroy(); - mPrintPreviewController.destroy(new Runnable() { - @Override - public void run() { - finish(); - } - }); - } else { - finish(); + mPrintPreviewController.destroy(); } + finish(); } private final class SpinnerItem<T> { diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java index e4eab10e1b8c..15342ae3f595 100644 --- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java +++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java @@ -192,15 +192,10 @@ class PrintPreviewController implements MutexFileProvider.OnReleaseRequestCallba }); } - public void destroy(Runnable callback) { - if (mPageAdapter.isOpened()) { - Message operation = mHandler.obtainMessage(MyHandler.MSG_CLOSE); - mHandler.enqueueOperation(operation); - } - - Message operation = mHandler.obtainMessage(MyHandler.MSG_DESTROY); - operation.obj = callback; - mHandler.enqueueOperation(operation); + public void destroy() { + mHandler.cancelQueuedOperations(); + mRecyclerView.setAdapter(null); + mPageAdapter.destroy(); } @Override @@ -226,7 +221,6 @@ class PrintPreviewController implements MutexFileProvider.OnReleaseRequestCallba private final class MyHandler extends Handler { public static final int MSG_OPEN = 1; public static final int MSG_CLOSE = 2; - public static final int MSG_DESTROY = 3; public static final int MSG_UPDATE = 4; public static final int MSG_START_PRELOAD = 5; @@ -246,6 +240,10 @@ class PrintPreviewController implements MutexFileProvider.OnReleaseRequestCallba super(looper, null, false); } + public void cancelQueuedOperations() { + mPendingOperations.clear(); + } + public void enqueueOperation(Message message) { mPendingOperations.add(message); handleNextOperation(); @@ -294,13 +292,6 @@ class PrintPreviewController implements MutexFileProvider.OnReleaseRequestCallba }); } break; - case MSG_DESTROY: { - Runnable callback = (Runnable) message.obj; - mRecyclerView.setAdapter(null); - mPageAdapter.destroy(callback); - handleNextOperation(); - } break; - case MSG_UPDATE: { SomeArgs args = (SomeArgs) message.obj; PageRange[] writtenPages = (PageRange[]) args.arg1; diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml index efba03d7f108..16c6075f492a 100644 --- a/packages/SettingsProvider/res/values/defaults.xml +++ b/packages/SettingsProvider/res/values/defaults.xml @@ -21,6 +21,7 @@ <integer name="def_screen_off_timeout">60000</integer> <integer name="def_sleep_timeout">-1</integer> <bool name="def_airplane_mode_on">false</bool> + <bool name="def_theater_mode_on">false</bool> <!-- Comma-separated list of bluetooth, wifi, and cell. --> <string name="def_airplane_mode_radios" translatable="false">cell,bluetooth,wifi,nfc,wimax</string> <string name="airplane_mode_toggleable_radios" translatable="false">bluetooth,wifi,nfc</string> diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java index 8c51caf18307..eea97eac5c2f 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java @@ -71,7 +71,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { // database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion' // is properly propagated through your change. Not doing so will result in a loss of user // settings. - private static final int DATABASE_VERSION = 114; + private static final int DATABASE_VERSION = 116; private Context mContext; private int mUserHandle; @@ -568,7 +568,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)" + " VALUES(?,?);"); loadSetting(stmt, Settings.System.VOLUME_BLUETOOTH_SCO, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]); + AudioService.getDefaultStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO)); db.setTransactionSuccessful(); } finally { db.endTransaction(); @@ -1828,20 +1828,43 @@ public class DatabaseHelper extends SQLiteOpenHelper { upgradeVersion = 113; } - if (upgradeVersion < 114) { - db.beginTransaction(); - SQLiteStatement stmt = null; - try { - stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)" - + " VALUES(?,?);"); - loadSetting(stmt, Settings.Global.VOLTE_VT_ENABLED, ImsConfig.FeatureValueConstants.ON); - db.setTransactionSuccessful(); - } finally { - db.endTransaction(); - if (stmt != null) stmt.close(); + // We skipped 114 to handle a merge conflict with the introduction of theater mode. + + if (upgradeVersion < 115) { + if (mUserHandle == UserHandle.USER_OWNER) { + db.beginTransaction(); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)" + + " VALUES(?,?);"); + loadBooleanSetting(stmt, Global.THEATER_MODE_ON, + R.bool.def_theater_mode_on); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + if (stmt != null) stmt.close(); + } + } + upgradeVersion = 115; + } + + if (upgradeVersion < 116) { + if (mUserHandle == UserHandle.USER_OWNER) { + db.beginTransaction(); + SQLiteStatement stmt = null; + try { + stmt = db.compileStatement("INSERT OR IGNORE INTO global(name,value)" + + " VALUES(?,?);"); + loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED, ImsConfig.FeatureValueConstants.ON); + db.setTransactionSuccessful(); + } finally { + db.endTransaction(); + if (stmt != null) stmt.close(); + } } - upgradeVersion = 114; + upgradeVersion = 116; } + // *** Remember to update DATABASE_VERSION above! if (upgradeVersion != currentVersion) { @@ -2146,25 +2169,25 @@ public class DatabaseHelper extends SQLiteOpenHelper { + " VALUES(?,?);"); loadSetting(stmt, Settings.System.VOLUME_MUSIC, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_MUSIC]); + AudioService.getDefaultStreamVolume(AudioManager.STREAM_MUSIC)); loadSetting(stmt, Settings.System.VOLUME_RING, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_RING]); + AudioService.getDefaultStreamVolume(AudioManager.STREAM_RING)); loadSetting(stmt, Settings.System.VOLUME_SYSTEM, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_SYSTEM]); + AudioService.getDefaultStreamVolume(AudioManager.STREAM_SYSTEM)); loadSetting( stmt, Settings.System.VOLUME_VOICE, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_VOICE_CALL]); + AudioService.getDefaultStreamVolume(AudioManager.STREAM_VOICE_CALL)); loadSetting(stmt, Settings.System.VOLUME_ALARM, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_ALARM]); + AudioService.getDefaultStreamVolume(AudioManager.STREAM_ALARM)); loadSetting( stmt, Settings.System.VOLUME_NOTIFICATION, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_NOTIFICATION]); + AudioService.getDefaultStreamVolume(AudioManager.STREAM_NOTIFICATION)); loadSetting( stmt, Settings.System.VOLUME_BLUETOOTH_SCO, - AudioManager.DEFAULT_STREAM_VOLUME[AudioManager.STREAM_BLUETOOTH_SCO]); + AudioService.getDefaultStreamVolume(AudioManager.STREAM_BLUETOOTH_SCO)); // By default: // - ringtones, notification, system and music streams are affected by ringer mode @@ -2438,6 +2461,9 @@ public class DatabaseHelper extends SQLiteOpenHelper { loadBooleanSetting(stmt, Settings.Global.AIRPLANE_MODE_ON, R.bool.def_airplane_mode_on); + loadBooleanSetting(stmt, Settings.Global.THEATER_MODE_ON, + R.bool.def_theater_mode_on); + loadStringSetting(stmt, Settings.Global.AIRPLANE_MODE_RADIOS, R.string.def_airplane_mode_radios); @@ -2584,7 +2610,7 @@ public class DatabaseHelper extends SQLiteOpenHelper { loadBooleanSetting(stmt, Settings.Global.GUEST_USER_ENABLED, R.bool.def_guest_user_enabled); - loadSetting(stmt, Settings.Global.VOLTE_VT_ENABLED, ImsConfig.FeatureValueConstants.ON); + loadSetting(stmt, Settings.Global.ENHANCED_4G_MODE_ENABLED, ImsConfig.FeatureValueConstants.ON); // --- New global settings start here } finally { if (stmt != null) stmt.close(); diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index 7e6afa67d962..3c4424505f04 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -92,6 +92,7 @@ <uses-permission android:name="android.permission.FRAME_STATS" /> <uses-permission android:name="android.permission.BIND_APPWIDGET" /> <uses-permission android:name="android.permission.UPDATE_APP_OPS_STATS" /> + <uses-permission android:name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"/> <application android:label="@string/app_label"> <provider diff --git a/packages/SystemUI/res/drawable/stat_sys_alarm.xml b/packages/SystemUI/res/drawable/stat_sys_alarm.xml index 57545691b4f6..48c2222f50ca 100644 --- a/packages/SystemUI/res/drawable/stat_sys_alarm.xml +++ b/packages/SystemUI/res/drawable/stat_sys_alarm.xml @@ -17,7 +17,7 @@ android:insetLeft="2.5dp" android:insetRight="2.5dp"> <vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="22dp" + android:width="17dp" android:height="17dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_cast.xml b/packages/SystemUI/res/drawable/stat_sys_cast.xml index df28638c64c8..4a7cbb3a4edf 100644 --- a/packages/SystemUI/res/drawable/stat_sys_cast.xml +++ b/packages/SystemUI/res/drawable/stat_sys_cast.xml @@ -16,7 +16,7 @@ Copyright (C) 2014 The Android Open Source Project <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="2.5dp" android:insetRight="2.5dp"> - <vector android:width="22dp" + <vector android:width="17dp" android:height="17dp" android:viewportWidth="48.0" android:viewportHeight="48.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_location.xml b/packages/SystemUI/res/drawable/stat_sys_location.xml index 433f73be3306..33ac5cd9e34e 100644 --- a/packages/SystemUI/res/drawable/stat_sys_location.xml +++ b/packages/SystemUI/res/drawable/stat_sys_location.xml @@ -17,7 +17,7 @@ android:insetLeft="1.5dp" android:insetRight="1.5dp"> <vector - android:width="20dp" + android:width="17dp" android:height="17dp" android:viewportWidth="48.0" android:viewportHeight="48.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml index f017d5808768..eb7b4fca6a89 100644 --- a/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml +++ b/packages/SystemUI/res/drawable/stat_sys_ringer_vibrate.xml @@ -16,7 +16,7 @@ Copyright (C) 2014 The Android Open Source Project <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="3dp" android:insetRight="3dp"> - <vector android:width="24dp" + <vector android:width="18dp" android:height="18dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_zen_important.xml b/packages/SystemUI/res/drawable/stat_sys_zen_important.xml index 9dabb03e5fc3..1262617589d5 100644 --- a/packages/SystemUI/res/drawable/stat_sys_zen_important.xml +++ b/packages/SystemUI/res/drawable/stat_sys_zen_important.xml @@ -16,7 +16,7 @@ Copyright (C) 2014 The Android Open Source Project <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="2.5dp" android:insetRight="2.5dp"> - <vector android:width="23dp" + <vector android:width="18dp" android:height="18dp" android:viewportWidth="24.0" android:viewportHeight="24.0"> diff --git a/packages/SystemUI/res/drawable/stat_sys_zen_none.xml b/packages/SystemUI/res/drawable/stat_sys_zen_none.xml index 7573de0d6e65..92914a8dd988 100644 --- a/packages/SystemUI/res/drawable/stat_sys_zen_none.xml +++ b/packages/SystemUI/res/drawable/stat_sys_zen_none.xml @@ -16,7 +16,7 @@ Copyright (C) 2014 The Android Open Source Project <inset xmlns:android="http://schemas.android.com/apk/res/android" android:insetLeft="2.5dp" android:insetRight="2.5dp"> - <vector android:width="22dp" + <vector android:width="17dp" android:height="17dp" android:viewportWidth="48.0" android:viewportHeight="48.0"> diff --git a/packages/SystemUI/res/layout/signal_cluster_view.xml b/packages/SystemUI/res/layout/signal_cluster_view.xml index 5889c55a8f42..f45aa858d9bd 100644 --- a/packages/SystemUI/res/layout/signal_cluster_view.xml +++ b/packages/SystemUI/res/layout/signal_cluster_view.xml @@ -24,6 +24,7 @@ android:layout_width="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" + android:paddingEnd="@dimen/signal_cluster_battery_padding" > <ImageView android:id="@+id/vpn" diff --git a/packages/SystemUI/res/layout/system_icons.xml b/packages/SystemUI/res/layout/system_icons.xml index 21386ef98054..943e84622fe7 100644 --- a/packages/SystemUI/res/layout/system_icons.xml +++ b/packages/SystemUI/res/layout/system_icons.xml @@ -36,6 +36,5 @@ <com.android.systemui.BatteryMeterView android:id="@+id/battery" android:layout_height="14.5dp" android:layout_width="9.5dp" - android:layout_marginBottom="@dimen/battery_margin_bottom" - android:layout_marginStart="7dp"/> + android:layout_marginBottom="@dimen/battery_margin_bottom"/> </LinearLayout>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index df8f72869111..25bd9939840b 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> waarskuwing"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Jou onlangse skerms verskyn hier"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Programinligting"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"sluit na program"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"skermvaspen"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"soek"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Kon nie <xliff:g id="APP">%s</xliff:g> begin nie."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Gelaai"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index c8038a852fae..f08d99ee1c7e 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"የ<xliff:g id="DATA_LIMIT">%s</xliff:g> ማስጠንቀቂያ"</string> <string name="recents_empty_message" msgid="8682129509540827999">"የቅርብ ጊዜ ማያ ገጾችዎ እዚህ ይታያሉ"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"የመተግበሪያ መረጃ"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"መተግበሪያ-ጋር-ቆልፍ"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"ፈልግ"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ን መጀመር አልተቻለም።"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"ባትሪ ሞልቷል"</string> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index fa46a41769f3..f59d011bbbe4 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"تظهر شاشاتك المعروضة مؤخرًا هنا"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"إزالة التطبيقات الحديثة"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"شاشة واحدة في العرض العام"</item> - <item quantity="other" msgid="5523506463832158203">"%d من الشاشات في العرض العام"</item> + <item quantity="one" msgid="3969335317929254918">"شاشة واحدة في النظرة عامة"</item> + <item quantity="other" msgid="5523506463832158203">"%d من الشاشات في النظرة عامة"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"ليس هناك أي اشعارات"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"مستمر"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"رجوع"</string> <string name="accessibility_home" msgid="8217216074895377641">"الرئيسية"</string> <string name="accessibility_menu" msgid="316839303324695949">"القائمة"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"العرض العام"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"النظرة عامة"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"بحث"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"الكاميرا"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"الهاتف"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"الإعدادات السريعة."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"شاشة التأمين."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"الإعدادات"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"العرض العام."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"النظرة عامة."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"المستخدم <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"تم إيقاف Wifi."</string> @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"تحذير <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"تظهر شاشاتك المعروضة مؤخرًا هنا"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"معلومات التطبيق"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"تقييد بالتطبيق"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"تثبيت الشاشة"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"بحث"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"تعذر بدء <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"تم الشحن"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 59e5ecefec0c..20111351a9e8 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Предупреждение: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Скорошните ви екрани се показват тук"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Информация за приложението"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"заключване в приложението"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"търсене"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> не можа да стартира."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Заредена"</string> diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml index 93ff2eca1a42..60872f58125c 100644 --- a/packages/SystemUI/res/values-bn-rBD/strings.xml +++ b/packages/SystemUI/res/values-bn-rBD/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"আপনার সাম্প্রতিক স্ক্রীনগুলো এখানে দেখা যাবে"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"সাম্প্রতিক অ্যাপ্লিকেশানগুলি খারিজ করুন"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"ওভারভিউ-এ ১টি স্ক্রীন"</item> - <item quantity="other" msgid="5523506463832158203">"ওভারভিউ-এ %dটি স্ক্রীন"</item> + <item quantity="one" msgid="3969335317929254918">"এক নজরে-এ ১টি স্ক্রীন"</item> + <item quantity="other" msgid="5523506463832158203">"এক নজরে-এ %dটি স্ক্রীন"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"কোনো বিজ্ঞপ্তি নেই"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"চলতে-থাকা"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"ফিরুন"</string> <string name="accessibility_home" msgid="8217216074895377641">"হোম"</string> <string name="accessibility_menu" msgid="316839303324695949">"মেনু"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"ওভারভিউ"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"এক নজরে"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"অনুসন্ধান করুন"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"ক্যামেরা"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"ফোন"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"দ্রুত সেটিংস৷"</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"লক স্ক্রীন।"</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"সেটিংস"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"ওভারভিউ৷"</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"এক নজরে৷"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ব্যবহারকারী <xliff:g id="USER">%s</xliff:g>৷"</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>।"</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"WiFi বন্ধ হয়েছে।"</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> সতর্কতা"</string> <string name="recents_empty_message" msgid="8682129509540827999">"আপনার সাম্প্রতিক স্ক্রীনগুলো এখানে দেখা যাবে"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"অ্যাপ্লিকেশানের তথ্য"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"অ্যাপ্লিকেশানে লক করুন"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"অনুসন্ধান"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> শুরু করা যায়নি৷"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"চার্জ হয়েছে"</string> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index 7ebce43fd8f1..9f7457143689 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Aquí es mostren les teves pantalles recents."</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Omet les aplicacions recents"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"1 pantalla en la visió general"</item> - <item quantity="other" msgid="5523506463832158203">"%d pantalles en la visió general"</item> + <item quantity="one" msgid="3969335317929254918">"1 pantalla a Visió general"</item> + <item quantity="other" msgid="5523506463832158203">"%d pantalles a Visió general"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Cap notificació"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Continu"</string> @@ -277,7 +277,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advertiment: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Aquí es mostren les teves pantalles recents."</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informació de l\'aplicació"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"bloqueig d\'aplicació"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"No s\'ha pogut iniciar <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Carregada"</string> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index da61fcbd7ccf..2e0e0d70672f 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -277,7 +277,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Upozornění při <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Zde budou zobrazeny vaše poslední obrazovky"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informace o aplikaci"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"uzamknout v aplikaci"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"připnutí obrazovky"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"vyhledat"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikaci <xliff:g id="APP">%s</xliff:g> nelze spustit."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Nabito"</string> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index d18c2faafb0c..c102f13fa4e7 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advarsel ved <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Dine seneste skærme vises her"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Oplysninger om applikationen"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"Bliv i app"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"søg"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> kunne ikke startes."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Opladet"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index ec34296c0e78..55422295566a 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -277,7 +277,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Warnung für <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Hier sehen Sie Ihre zuletzt geöffneten Apps."</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"App-Info"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"App-Verriegelung"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"Bildschirmfixierung"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"Suche"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> konnte nicht gestartet werden."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Aufgeladen"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index 1e2d72c1807c..d924ceaf76d2 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -277,7 +277,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Προειδοποίηση για <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Οι πρόσφατες οθόνες σας εμφανίζονται εδώ"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Πληροφορίες εφαρμογής"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"lock to app"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"αναζήτηση"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Δεν ήταν δυνατή η εκκίνηση της εφαρμογής <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Φορτίστηκε"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index c587701cba3f..f2018fa10c35 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> warning"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Your recent screens appear here"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"lock to app"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Charged"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index c587701cba3f..f2018fa10c35 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> warning"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Your recent screens appear here"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"lock to app"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Charged"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 3fcc1fdd0014..0e723ea77d84 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Las pantallas recientes aparecen aquí."</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Rechazar aplicaciones recientes"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"1 pantalla en Descripción general"</item> - <item quantity="other" msgid="5523506463832158203">"%d pantallas en Descripción general"</item> + <item quantity="one" msgid="3969335317929254918">"1 pantalla en Recientes"</item> + <item quantity="other" msgid="5523506463832158203">"%d pantallas en Recientes"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No hay notificaciones"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Continuo"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"Atrás"</string> <string name="accessibility_home" msgid="8217216074895377641">"Página principal"</string> <string name="accessibility_menu" msgid="316839303324695949">"Menú"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"Descripción general"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"Recientes"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"Buscar"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"Cámara"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string> @@ -167,7 +167,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuración rápida"</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Pantalla bloqueada"</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Configuración"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Descripción general"</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Recientes"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuario <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-Fi desactivado"</string> @@ -277,7 +277,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advertencia de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Las pantallas recientes aparecen aquí."</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Información de la aplicación"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"fijar aplicación"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"No se pudo iniciar <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Cargada"</string> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 8ad8be3af06a..b8e4e4e39f43 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Aquí aparecerán tus pantallas recientes"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Ignorar aplicaciones recientes"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"1 pantalla en Información general"</item> - <item quantity="other" msgid="5523506463832158203">"%d pantallas en Información general"</item> + <item quantity="one" msgid="3969335317929254918">"1 pantalla en Visión general"</item> + <item quantity="other" msgid="5523506463832158203">"%d pantallas en Visión general"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"No tienes notificaciones"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Entrante"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"Atrás"</string> <string name="accessibility_home" msgid="8217216074895377641">"Inicio"</string> <string name="accessibility_menu" msgid="316839303324695949">"Menú"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"Información general"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"Visión general"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"Buscar"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"Cámara"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Ajustes rápidos"</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Pantalla de bloqueo."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Ajustes"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Información general."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Visión general."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuario <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-Fi desactivado."</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advertencia de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Aquí aparecerán tus pantallas recientes"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Información de la aplicación"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"bloqueo de aplicación"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"No se ha podido iniciar <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Cargada"</string> @@ -296,7 +297,7 @@ <string name="speed_bump_explanation" msgid="1288875699658819755">"Notificaciones menos urgente abajo"</string> <string name="notification_tap_again" msgid="8524949573675922138">"Vuelve a tocar para abrir"</string> <string name="keyguard_unlock" msgid="8043466894212841998">"Desliza el dedo hacia arriba para desbloquear"</string> - <string name="phone_hint" msgid="3101468054914424646">"Desliza el dedo hacia la izquierda para acceder al teléfono"</string> + <string name="phone_hint" msgid="3101468054914424646">"Desliza el dedo hacia la derecha para acceder al teléfono"</string> <string name="camera_hint" msgid="5241441720959174226">"Desliza el dedo hacia la izquierda para acceder a la cámara"</string> <string name="interruption_level_none" msgid="3831278883136066646">"Nada"</string> <string name="interruption_level_priority" msgid="6517366750688942030">"Prioridad"</string> diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml index 0a8cc0c0d4b3..be851664be30 100644 --- a/packages/SystemUI/res/values-et-rEE/strings.xml +++ b/packages/SystemUI/res/values-et-rEE/strings.xml @@ -27,7 +27,7 @@ <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Loobu hiljutistest rakendustest"</string> <plurals name="status_bar_accessibility_recent_apps"> <item quantity="one" msgid="3969335317929254918">"1 ekraan jaotises Ülevaade"</item> - <item quantity="other" msgid="5523506463832158203">"%d ekraani jaotises Ülevaade"</item> + <item quantity="other" msgid="5523506463832158203">"%d ekraanikuva jaotises Ülevaade"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Teatisi pole"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Jätkuv"</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> hoiatus"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Teie viimane ekraanikuva ilmub siia"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Rakenduste teave"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"lukusta rakendusele"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"otsing"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Rakendust <xliff:g id="APP">%s</xliff:g> ei saanud käivitada."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Laetud"</string> diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml index 138c7b168709..84874d318580 100644 --- a/packages/SystemUI/res/values-eu-rES/strings.xml +++ b/packages/SystemUI/res/values-eu-rES/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Abisua: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Ikusitako azken pantailak erakusten dira hemen"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Aplikazioaren informazioa"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"aplikazio bakarreko modua"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"bilatu"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Ezin izan da hasi <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Kargatuta"</string> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index c3efc17ea82d..245ac4a596b9 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"هشدار <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"صفحههای اخیر شما اینجا نمایان میشوند"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"اطلاعات برنامه"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"قفل به برنامه"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"پین کردن صفحه"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"جستجو"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> شروع نشد."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"شارژ کامل شد"</string> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index de44080c3629..be27fb131250 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Äskettäin käytetyt ruudut näkyvät tässä"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Hylkää viimeaikaiset sovellukset"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"1 näyttö Yleistä-kohdassa"</item> - <item quantity="other" msgid="5523506463832158203">"%d näyttöä Yleistä-kohdassa"</item> + <item quantity="one" msgid="3969335317929254918">"1 näyttö Viimeisimmät-kohdassa"</item> + <item quantity="other" msgid="5523506463832158203">"%d näyttöä Viimeisimmät-kohdassa"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ei ilmoituksia"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Käynnissä olevat"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"Takaisin"</string> <string name="accessibility_home" msgid="8217216074895377641">"Aloituspainike"</string> <string name="accessibility_menu" msgid="316839303324695949">"Valikko"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"Yleistä"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"Viimeisimmät"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"Haku"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"Puhelin"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Pika-asetukset."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Lukitse näyttö."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Asetukset"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Yleistä."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Viimeisimmät."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Käyttäjä: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-Fi poistettiin käytöstä."</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> – varoitus"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Äskettäin käytetyt ruudut näkyvät tässä"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Sovellustiedot"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"lukitse sovellukseen"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"haku"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Sovelluksen <xliff:g id="APP">%s</xliff:g> käynnistäminen epäonnistui."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Ladattu"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index a67a9dd0ee5e..a52655edf44c 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Vos écrans récents s\'affichent ici"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Masquer les applications récentes"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"Aperçu d\'1 écran"</item> - <item quantity="other" msgid="5523506463832158203">"Aperçu de %d écrans"</item> + <item quantity="one" msgid="3969335317929254918">"1 écran dans Aperçu"</item> + <item quantity="other" msgid="5523506463832158203">"%d écrans dans Aperçu"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Aucune notification"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"En cours"</string> @@ -167,7 +167,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Paramètres rapides"</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Écran de verrouillage"</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Paramètres"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Aperçu."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Aperçu"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Utilisateur : <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-Fi désactivé"</string> @@ -277,7 +277,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Avertissement : <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Vos écrans récents s\'affichent ici"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Détails de l\'application"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"verrouiller sur l\'application"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Chargée"</string> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index 13f3f55749b8..26fa5a2fb72c 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Vos écrans récents s\'affichent ici"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Masquer les applications récentes"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"1 écran dans la vue d\'ensemble"</item> - <item quantity="other" msgid="5523506463832158203">"%d écrans dans la vue d\'ensemble"</item> + <item quantity="one" msgid="3969335317929254918">"1 écran dans Aperçu"</item> + <item quantity="other" msgid="5523506463832158203">"%d écrans dans Aperçu"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Aucune notification"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"En cours"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"Retour"</string> <string name="accessibility_home" msgid="8217216074895377641">"Accueil"</string> <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"Vue d\'ensemble"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"Aperçu"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"Rechercher"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"Appareil photo"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"Téléphoner"</string> @@ -167,7 +167,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Paramètres rapides"</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Écran de verrouillage"</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Paramètres"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Vue d\'ensemble"</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Aperçu"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Utilisateur <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-Fi désactivé."</string> @@ -277,7 +277,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Avertissement : <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Vos écrans récents s\'affichent ici"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informations sur l\'application"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"verrouiller sur l\'application"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"rechercher"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossible de lancer <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Chargé"</string> diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml index c631c3c2a71d..1d9b63a5d35c 100644 --- a/packages/SystemUI/res/values-gl-rES/strings.xml +++ b/packages/SystemUI/res/values-gl-rES/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"As túas pantallas recentes aparecen aquí"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Rexeitar aplicacións recentes"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"1 pantalla en Vista xeral"</item> - <item quantity="other" msgid="5523506463832158203">"%d pantallas en Vista xeral"</item> + <item quantity="one" msgid="3969335317929254918">"1 pantalla en Visión xeral"</item> + <item quantity="other" msgid="5523506463832158203">"%d pantallas en Visión xeral"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Non hai notificacións"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"En curso"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"Volver"</string> <string name="accessibility_home" msgid="8217216074895377641">"Inicio"</string> <string name="accessibility_menu" msgid="316839303324695949">"Menú"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"Vista xeral"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"Visión xeral"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"Buscar"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"Cámara"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"Teléfono"</string> @@ -167,7 +167,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuración rápida"</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Pantalla de bloqueo."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Configuración"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Vista xeral."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Visión xeral."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Usuario <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wifi desactivada."</string> @@ -277,7 +277,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advertencia <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"As túas pantallas recentes aparecen aquí"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Información da aplicación"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"bloqueo de aplicación"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"buscar"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Non foi posible iniciar <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Cargada"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 3e209454a150..47da5bfa9523 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"आपकी हाल की स्क्रीन यहां दिखाई देती हैं"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"हाल ही के ऐप्स खारिज करें"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"ओवरव्यू मेें 1 स्क्रीन"</item> - <item quantity="other" msgid="5523506463832158203">"ओवरव्यू में %d स्क्रीन"</item> + <item quantity="one" msgid="3969335317929254918">"अवलोकन मेें 1 स्क्रीन"</item> + <item quantity="other" msgid="5523506463832158203">"अवलोकन में %d स्क्रीन"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"कोई नोटिफिकेशन नहीं"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"ऑनगोइंग"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"वापस जाएं"</string> <string name="accessibility_home" msgid="8217216074895377641">"होम"</string> <string name="accessibility_menu" msgid="316839303324695949">"मेनू"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"ओवरव्यू"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"अवलोकन"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"खोजें"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"कैमरा"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"फ़ोन"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"त्वरित सेटिंग."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"लॉक स्क्रीन."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"सेटिंग"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"ओवरव्यू."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"अवलोकन."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"उपयोगकर्ता <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"वाई-फ़ाई को बंद किया गया."</string> @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> चेतावनी"</string> <string name="recents_empty_message" msgid="8682129509540827999">"आपकी हाल की स्क्रीन यहां दिखाई देती हैं"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"एप्लिकेशन जानकारी"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"ऐप्स पर लॉक करें"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्क्रीन पिन करना"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"खोज"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ नहीं किया जा सका."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"चार्ज हो गई है"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 1d97c9fae1fe..0ad9f3edce26 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Upozorenje <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Ovdje se pojavljuju vaši nedavni zasloni"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informacije o aplikaciji"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"zaključaj na aplikaciju"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Napunjeno"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 451684eb2930..591e6fa5af8c 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Figyelem! <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"A legutóbbi képernyők itt jelennek meg"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Az alkalmazás adatai"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"alkalmazászárolás"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"keresés"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Nem lehet elindítani a következőt: <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Feltöltve"</string> diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml index 5d442a08e53e..5db23b810ba7 100644 --- a/packages/SystemUI/res/values-hy-rAM/strings.xml +++ b/packages/SystemUI/res/values-hy-rAM/strings.xml @@ -214,7 +214,7 @@ <string name="accessibility_clear_all" msgid="5235938559247164925">"Մաքրել բոլոր ծանուցումները:"</string> <string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ծանուցման կարգավորումներ"</string> <string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>-ի կարգավորումներ"</string> - <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Էկրանը ինքնուրույն կպտտվի:"</string> + <string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Էկրանը ինքնաշխատ կպտտվի:"</string> <string name="accessibility_rotation_lock_on_landscape" msgid="6731197337665366273">"Էկրանը կողպված է հորիզոնական դիրքավորման մեջ:"</string> <string name="accessibility_rotation_lock_on_portrait" msgid="5809367521644012115">"Էկրանը կողպված է ուղղաձիգ դիրքավորմամբ:"</string> <string name="accessibility_rotation_lock_off_changed" msgid="8134601071026305153">"Էկրանն այժմ ավտոմատ կպտտվի:"</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> զգուշացում"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Ձեր վերջին էկրանները տեսանելի են այստեղ"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Հավելվածի մասին"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"Lock-to-app"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"որոնել"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Հնարավոր չէ գործարկել <xliff:g id="APP">%s</xliff:g>-ը:"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Լիցքավորված է"</string> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 5228a06df02a..2ad0285968c5 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Layar terkini Anda muncul di sini"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Tutup aplikasi terbaru"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"1 layar dalam Ikhtisar"</item> - <item quantity="other" msgid="5523506463832158203">"%d layar dalam Ikhtisar"</item> + <item quantity="one" msgid="3969335317929254918">"1 layar dalam Ringkasan"</item> + <item quantity="other" msgid="5523506463832158203">"%d layar dalam Ringkasan"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Tidak ada pemberitahuan"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Berkelanjutan"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"Kembali"</string> <string name="accessibility_home" msgid="8217216074895377641">"Utama"</string> <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"Ikhtisar"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"Ringkasan"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"Telusuri"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"Telepon"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Setelan cepat."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Layar kunci."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Setelan"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Ikhtisar."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Ringkasan."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Pengguna <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-Fi dinonaktifkan."</string> @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Peringatan <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Layar terkini Anda muncul di sini"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Info Aplikasi"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"kunci ke aplikasi"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pin ke layar"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"telusuri"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Tidak dapat memulai <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Terisi"</string> diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml index d5e64765c983..0a058647868e 100644 --- a/packages/SystemUI/res/values-is-rIS/strings.xml +++ b/packages/SystemUI/res/values-is-rIS/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> viðvörun"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Nýlegar skjámyndir birtast hér"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Forritsupplýsingar"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"forritslæsing"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"leita"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Ekki var hægt að ræsa <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Fullhlaðin"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 98a22ec6a893..82711f1a547e 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -277,7 +277,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Avviso <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Le tue schermate recenti vengono visualizzate in questa sezione"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informazioni sull\'applicazione"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"blocca su app"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"cerca"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Impossibile avviare <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Carica"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 55f2daf9b234..a07370696c3f 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"אזהרה - <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"המסכים האחרונים מופיעים כאן"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"מידע על האפליקציה"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"נעל לאפליקציה"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"הצמדת מסך"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"חפש"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"לא ניתן היה להפעיל את <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"טעון"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index afea5755a744..81e38ea4ef5d 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"ここに最近の画面が表示されます"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"最近使ったアプリをクリア"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"[概要]に1個の画面があります"</item> - <item quantity="other" msgid="5523506463832158203">"[概要]に%d個の画面があります"</item> + <item quantity="one" msgid="3969335317929254918">"[最近]に1個の画面があります"</item> + <item quantity="other" msgid="5523506463832158203">"[最近]に%d個の画面があります"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"通知なし"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"実行中"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"戻る"</string> <string name="accessibility_home" msgid="8217216074895377641">"ホーム"</string> <string name="accessibility_menu" msgid="316839303324695949">"メニュー"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"概要"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"最近"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"検索"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"カメラ"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"電話"</string> @@ -167,7 +167,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"クイック設定"</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"ロック画面"</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"設定"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"概要です。"</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"最近"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ユーザー: <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-FiをOFFにしました。"</string> @@ -277,7 +277,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"警告: 上限は<xliff:g id="DATA_LIMIT">%s</xliff:g>です"</string> <string name="recents_empty_message" msgid="8682129509540827999">"ここに最近の画面が表示されます"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"アプリ情報"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"アプリロック"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"検索"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>を開始できません。"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"充電が完了しました"</string> diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml index 9461ad2aee84..9f4163f4d918 100644 --- a/packages/SystemUI/res/values-ka-rGE/strings.xml +++ b/packages/SystemUI/res/values-ka-rGE/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> გაფრთხილება"</string> <string name="recents_empty_message" msgid="8682129509540827999">"თქვენი ბოლო ეკრანები აქ გამოჩნდება"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"აპლიკაციის შესახებ"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"აპზე ფიქსაცია"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"ძიება"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-ის გამოძახება ვერ მოხერხდა."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"დატენილია"</string> diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml index bb84471b687c..fd9300948321 100644 --- a/packages/SystemUI/res/values-kk-rKZ/strings.xml +++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> туралы ескерту"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Мұнда жақындағы экрандар көрсетіледі"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Қолданба туралы ақпарат"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"қолданбаға бекіту"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"іздеу"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> іске қосу мүмкін болмады."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Зарядталды"</string> diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml index 335681a0584b..efa9eb72484c 100644 --- a/packages/SystemUI/res/values-km-rKH/strings.xml +++ b/packages/SystemUI/res/values-km-rKH/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ការព្រមាន"</string> <string name="recents_empty_message" msgid="8682129509540827999">"អេក្រង់បច្ចុប្បន្នរបស់អ្នកបង្ហាញនៅទីនេះ"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"ព័ត៌មានកម្មវិធី"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"ចាក់សោទៅកម្មវិធី"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ការភ្ជាប់អេក្រង់"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"ស្វែងរក"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"មិនអាចចាប់ផ្ដើម <xliff:g id="APP">%s</xliff:g> ទេ។"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"បានបញ្ចូលថ្ម"</string> diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml index e61f89a6c0e0..174c0a955361 100644 --- a/packages/SystemUI/res/values-kn-rIN/strings.xml +++ b/packages/SystemUI/res/values-kn-rIN/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"ನಿಮ್ಮ ಇತ್ತೀಚಿನ ಪರದೆಗಳು ಇಲ್ಲಿ ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತವೆ"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"ಇತ್ತೀಚಿನ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ವಜಾಗೊಳಿಸು"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"ಅವಲೋಕನದಲ್ಲಿರುವ 1 ಪರದೆ"</item> - <item quantity="other" msgid="5523506463832158203">"ಅವಲೋಕನದಲ್ಲಿರುವ %d ಪರದೆಗಳು"</item> + <item quantity="one" msgid="3969335317929254918">"ಸಮಗ್ರ ನೋಟದಲ್ಲಿರುವ 1 ಪರದೆ"</item> + <item quantity="other" msgid="5523506463832158203">"ಸಮಗ್ರ ನೋಟದಲ್ಲಿರುವ %d ಪರದೆಗಳು"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"ಯಾವುದೇ ಅಧಿಸೂಚನೆಗಳಿಲ್ಲ"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"ಚಾಲ್ತಿಯಲ್ಲಿರುವ"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"ಹಿಂದೆ"</string> <string name="accessibility_home" msgid="8217216074895377641">"ಮುಖಪುಟ"</string> <string name="accessibility_menu" msgid="316839303324695949">"ಮೆನು"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"ಅವಲೋಕನ"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"ಸಮಗ್ರ ನೋಟ"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"ಹುಡುಕು"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"ಕ್ಯಾಮರಾ"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"ಫೋನ್"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್ಗಳು."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"ಲಾಕ್ ಪರದೆ."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"ಅವಲೋಕನ."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"ಸಮಗ್ರ ನೋಟ."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ಬಳಕೆದಾರ <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"ವೈಫೈ ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> ಎಚ್ಚರಿಕೆ"</string> <string name="recents_empty_message" msgid="8682129509540827999">"ನಿಮ್ಮ ಇತ್ತೀಚಿನ ಪರದೆಗಳು ಇಲ್ಲಿ ಕಾಣಿಸಿಕೊಳ್ಳುತ್ತವೆ"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"ಅಪ್ಲಿಕೇಶನ್ಗೆ ಲಾಕ್"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"ಹುಡುಕಾಟ"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ಪ್ರಾರಂಭಿಸಲು ಸಾದ್ಯವಿಲ್ಲ."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"ಚಾರ್ಜ್ ಆಗಿದೆ"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index af7288a15796..191411626f94 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"여기에 최근 화면이 표시됩니다."</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"최근에 사용한 앱 숨기기"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"개요에 화면 1개"</item> - <item quantity="other" msgid="5523506463832158203">"개요에 화면 %d개"</item> + <item quantity="one" msgid="3969335317929254918">"최근 사용에 화면 1개"</item> + <item quantity="other" msgid="5523506463832158203">"최근 사용에 화면 %d개"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"알림 없음"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"진행 중"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"뒤로"</string> <string name="accessibility_home" msgid="8217216074895377641">"홈"</string> <string name="accessibility_menu" msgid="316839303324695949">"메뉴"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"개요"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"최근 사용"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"검색"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"카메라"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"전화"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"빠른 설정"</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"화면을 잠급니다."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"설정"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"개요"</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"최근 사용"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"사용자 <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-Fi가 사용 중지되었습니다."</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> 경고"</string> <string name="recents_empty_message" msgid="8682129509540827999">"여기에 최근 화면이 표시됩니다."</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"애플리케이션 정보"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"앱에 잠금"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"검색"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>을(를) 시작할 수 없습니다."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"충전됨"</string> diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml index 45ed9bf006bd..44babae35e97 100644 --- a/packages/SystemUI/res/values-ky-rKG/strings.xml +++ b/packages/SystemUI/res/values-ky-rKG/strings.xml @@ -300,7 +300,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> эскертүү"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Акыркы экрандарыңыз бул жерден көрүнөт"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Колдонмо жөнүндө маалымат"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"колдонмого кулпулоо"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"издөө"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> баштай алган жок."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Кубатталды"</string> diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml index 4218fd1a6a9e..5cba7f3af3af 100644 --- a/packages/SystemUI/res/values-lo-rLA/strings.xml +++ b/packages/SystemUI/res/values-lo-rLA/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"ຄຳເຕືອນ <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Your recent screens appear here"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"ຂໍ້ມູນແອັບພລິເຄຊັນ"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"lock to app"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"ຊອກຫາ"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"ບໍ່ສາມາດເລີ່ມ <xliff:g id="APP">%s</xliff:g> ໄດ້."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"ສາກເຕັມແລ້ວ."</string> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index 24945ca6dd07..342b98542319 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -199,7 +199,7 @@ <string name="accessibility_quick_settings_hotspot_changed_off" msgid="5004708003447561394">"Mobiliojo ryšio viešosios interneto prieigos taškas išjungtas."</string> <string name="accessibility_quick_settings_hotspot_changed_on" msgid="2890951609226476206">"Mobiliojo ryšio viešosios interneto prieigos taškas įjungtas."</string> <string name="accessibility_casting_turned_off" msgid="1430668982271976172">"Ekrano perdavimas sustabdytas."</string> - <string name="accessibility_brightness" msgid="8003681285547803095">"Ekrano ryškumas"</string> + <string name="accessibility_brightness" msgid="8003681285547803095">"Ekrano šviesumas"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="2626865386971800302">"2G–3G duomenys išjungti"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="4629078114195977196">"4G duomenys išjungti"</string> <string name="data_usage_disabled_dialog_mobile_title" msgid="5793456071535876132">"Mobiliojo ryšio duomenys išjungti"</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> įspėjimas"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Čia rodomi naujausi ekranai"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Programos informacija"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"Programos užrakinimo funkcija"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"paieška"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Nepavyko paleisti <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Įkrautas"</string> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index b97a17660de3..960f52c2698e 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Jūsu pēdējie ekrāni tiek rādīti šeit."</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Nerādīt nesen izmantotās lietotnes"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"1 ekrāns sadaļā “Kopsavilkums”"</item> - <item quantity="other" msgid="5523506463832158203">"%d ekrāni sadaļā “Kopsavilkums”"</item> + <item quantity="one" msgid="3969335317929254918">"1 ekrāns sadaļā “Pārskats”"</item> + <item quantity="other" msgid="5523506463832158203">"%d ekrāni sadaļā “Pārskats”"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Nav paziņojumu"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Notiekošs"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"Atpakaļ"</string> <string name="accessibility_home" msgid="8217216074895377641">"Sākums"</string> <string name="accessibility_menu" msgid="316839303324695949">"Izvēlne"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"Kopsavilkums"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"Pārskats"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"Meklēt"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"Tālruņa numurs"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Ātrie iestatījumi"</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Bloķēšanas ekrāns."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Iestatījumi"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Kopsavilkums."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Pārskats."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Lietotājs: <xliff:g id="USER">%s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-Fi ir izslēgts."</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> brīdinājums"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Jūsu pēdējie ekrāni tiek rādīti šeit."</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informācija par lietojumprogrammu"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"fiksēt lietotni"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"Meklēt"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Nevarēja palaist lietotni <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Akumulators uzlādēts"</string> diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml index 14d4c1143587..46cb4a6dc4c8 100644 --- a/packages/SystemUI/res/values-mk-rMK/strings.xml +++ b/packages/SystemUI/res/values-mk-rMK/strings.xml @@ -277,7 +277,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Предупредување за <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Вашите неодамнешни екрани се појавуваат тука"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Информации за апликацијата"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"заклучи на апликација"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"пребарај"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> не може да се вклучи."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Наполнета"</string> diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml index 5e24986d0bfc..30423ff48f89 100644 --- a/packages/SystemUI/res/values-ml-rIN/strings.xml +++ b/packages/SystemUI/res/values-ml-rIN/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"നിങ്ങളുടെ പുതിയ സ്ക്രീനുകൾ ഇവിടെ ദൃശ്യമാകുന്നു"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"സമീപകാല അപ്ലിക്കേഷനുകൾ നിരസിക്കുക"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"ചുരുക്കവിവരണത്തിലെ ഒരു സ്ക്രീൻ"</item> - <item quantity="other" msgid="5523506463832158203">"ചുരുക്കവിവരണത്തിലെ %d സ്ക്രീനുകൾ"</item> + <item quantity="one" msgid="3969335317929254918">"കാഴ്ചയിലെ ഒരു സ്ക്രീൻ"</item> + <item quantity="other" msgid="5523506463832158203">"കാഴ്ചയിലെ %d സ്ക്രീനുകൾ"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"അറിയിപ്പുകൾ ഒന്നുമില്ല"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"നടന്നുകൊണ്ടിരിക്കുന്നവ"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"മടങ്ങുക"</string> <string name="accessibility_home" msgid="8217216074895377641">"ഹോം"</string> <string name="accessibility_menu" msgid="316839303324695949">"മെനു"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"ചുരുക്കവിവരണം"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"കാഴ്ച"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"തിരയൽ"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"ക്യാമറ"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"ഫോണ്"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ദ്രുത ക്രമീകരണങ്ങൾ."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"ലോക്ക് സ്ക്രീൻ."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"ക്രമീകരണങ്ങൾ"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"ചുരുക്കവിവരണം."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"കാഴ്ച."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"ഉപയോക്താവ് <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"വൈഫൈ ഓഫാക്കി."</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> മുന്നറിയിപ്പ്"</string> <string name="recents_empty_message" msgid="8682129509540827999">"നിങ്ങളുടെ പുതിയ സ്ക്രീനുകൾ ഇവിടെ ദൃശ്യമാകുന്നു"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"അപ്ലിക്കേഷൻ വിവരം"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"അപ്ലിക്കേഷനിലേക്ക് ലോക്കുചെയ്യൽ"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"തിരയുക"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ആരംഭിക്കാനായില്ല."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"ചാർജ്ജുചെയ്തു"</string> diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml index c294f6a81988..7c475a98261d 100644 --- a/packages/SystemUI/res/values-mn-rMN/strings.xml +++ b/packages/SystemUI/res/values-mn-rMN/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> анхааруулга"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Таны саяхны дэлгэц энд харагдах болно"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Аппликешны мэдээлэл"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"Апп-дотор-түгжих"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"дэлгэц тогтоох"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"хайх"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>-г эхлүүлж чадсангүй."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Цэнэглэгдсэн"</string> diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml index 63b2c89ff683..7b3934ca5728 100644 --- a/packages/SystemUI/res/values-mr-rIN/strings.xml +++ b/packages/SystemUI/res/values-mr-rIN/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> चेतावणी"</string> <string name="recents_empty_message" msgid="8682129509540827999">"आपल्या अलीकडील स्क्रीन येथे दिसतात"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"अनुप्रयोग माहिती"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"अॅप-लॉक-करणे"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्क्रीन पिन करणे"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"शोधा"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> प्रारंभ करणे शक्य झाले नाही."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"चार्ज झाली"</string> diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml index 93fea9f7876c..9da46d815b46 100644 --- a/packages/SystemUI/res/values-ms-rMY/strings.xml +++ b/packages/SystemUI/res/values-ms-rMY/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Skrin terbaru anda terpapar di sini"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Buang aplikasi terbaharu"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"1 skrin dalam Gambaran Keseluruhan"</item> - <item quantity="other" msgid="5523506463832158203">"%d skrin dalam Gambaran Keseluruhan"</item> + <item quantity="one" msgid="3969335317929254918">"1 skrin dalam Ikhtisar"</item> + <item quantity="other" msgid="5523506463832158203">"%d skrin dalam Ikhtisar"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Tiada pemberitahuan"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Sedang berlangsung"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"Kembali"</string> <string name="accessibility_home" msgid="8217216074895377641">"Rumah"</string> <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"Gambaran keseluruhan"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"Ikhtisar"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"Cari"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"Kamera"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"Telefon"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Tetapan pantas."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Kunci skrin."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Tetapan"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Gambaran keseluruhan."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Ikhtisar."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Pengguna <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wifi dimatikan."</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Amaran <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Skrin terbaru anda terpapar di sini"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Maklumat Aplikasi"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"kunci ke apl"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"cari"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Tidak dapat memulakan <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Sudah dicas"</string> diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml index 6c573d6df7e1..6d7941f99502 100644 --- a/packages/SystemUI/res/values-my-rMM/strings.xml +++ b/packages/SystemUI/res/values-my-rMM/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> သတိပေးချက်"</string> <string name="recents_empty_message" msgid="8682129509540827999">"သင်၏ မကြာမီက မျက်နှာပြင်များ ဒီမှာ ပေါ်လာကြမည်"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"အပလီကေးရှင်း အင်ဖို"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"appသို့ သော့ခတ်ထားရန်"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"မျက်နှာပြင် ပင်ထိုးမှု"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"ရှာဖွေရန်"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ကို မစနိုင်ပါ။"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"အားသွင်းပြီး"</string> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index b25e8a7726b6..22b59437c1c3 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Advarsel for <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"De sist brukte skjermene dine vises her"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Appinformasjon"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"lås til app"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"Søk"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Kunne ikke starte <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Oppladet"</string> diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml index 153d48dd9981..6caf070d9640 100644 --- a/packages/SystemUI/res/values-ne-rNP/strings.xml +++ b/packages/SystemUI/res/values-ne-rNP/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> चेतावनी दिँदै"</string> <string name="recents_empty_message" msgid="8682129509540827999">"तपाईँको हालको स्क्रिन यहाँ प्रकट हुन्छ"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"अनुप्रयोग जानकारी"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"अनुप्रयोग बन्द गर्न"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"स्क्रिन पिन गर्दै"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"खोजी गर्नुहोस्"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"सुरु गर्न सकिएन <xliff:g id="APP">%s</xliff:g>।"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"चार्ज भयो"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index a722d3a4d5d7..4987619e4a6f 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Waarschuwing voor <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Uw recente schermen worden hier weergegeven"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"App-informatie"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"app-slot"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"zoeken"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Kan <xliff:g id="APP">%s</xliff:g> niet starten."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Opgeladen"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 8704b3328ee6..9b58984e32ca 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Ostrzeżenie: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Tutaj pojawią się ostatnie ekrany"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informacje o aplikacji"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"zablokuj na aplikacji"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"szukaj"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Nie udało się uruchomić aplikacji <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Naładowana"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 2a1de0804ed7..b7c37b82757c 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Aviso de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Os ecrãs recentes aparecem aqui"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informações da aplicação"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"bloquear numa aplicação"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar o <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Carregada"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 703eb33b49c8..4d8b1d07a9ca 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -277,7 +277,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Aviso de <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Suas telas recentes aparecem aqui"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informações do app"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"bloquear no app"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Carregada"</string> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index 127658854cd7..ffa73b2009e2 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Avertizare: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Ecranele dvs. recente apar aici"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informații despre aplicație"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"blocare la aplicație"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"căutare"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> nu a putut porni."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"S-a încărcat"</string> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 9aa65310d98b..9f82006cec79 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Здесь будут показаны недавние приложения."</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Закрыть недавние приложения"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"Показан 1 экран."</item> - <item quantity="other" msgid="5523506463832158203">"Показано экранов: %d."</item> + <item quantity="one" msgid="3969335317929254918">"В обзоре 1 экран."</item> + <item quantity="other" msgid="5523506463832158203">"Экранов в обзоре: %d."</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Нет уведомлений"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Текущие"</string> @@ -277,7 +277,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Предупреждение: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Здесь будут показаны недавние приложения"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Сведения о приложении"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"Блокировать в приложении"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"поиск"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Не удалось запустить приложение \"<xliff:g id="APP">%s</xliff:g>\""</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Батарея заряжена"</string> diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml index f76e719584d7..315286875306 100644 --- a/packages/SystemUI/res/values-si-rLK/strings.xml +++ b/packages/SystemUI/res/values-si-rLK/strings.xml @@ -25,8 +25,10 @@ <string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"යෙදුම් තොරතුරු"</string> <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"මෙහි ඔබගේ මෑතක තිර පෙන්නුම් කරයි"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"මෑත යෙදුම් ඉවතලන්න"</string> - <!-- no translation found for status_bar_accessibility_recent_apps:one (3969335317929254918) --> - <!-- no translation found for status_bar_accessibility_recent_apps:other (5523506463832158203) --> + <plurals name="status_bar_accessibility_recent_apps"> + <item quantity="one" msgid="3969335317929254918">"දළ විශ්ලේෂණය තුළ 1 තීරයයි"</item> + <item quantity="other" msgid="5523506463832158203">"දළ විශ්ලේෂණය තුළ තීරයෙන් %d"</item> + </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"දැනුම්දීම් නැත"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"දැනට පවතින"</string> <string name="status_bar_latest_events_title" msgid="6594767438577593172">"දැනුම්දීම්"</string> @@ -78,8 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"ආපසු"</string> <string name="accessibility_home" msgid="8217216074895377641">"මුල් පිටුව"</string> <string name="accessibility_menu" msgid="316839303324695949">"මෙනුව"</string> - <!-- no translation found for accessibility_recent (5208608566793607626) --> - <skip /> + <string name="accessibility_recent" msgid="5208608566793607626">"දළ විශ්ලේෂණය"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"සොයන්න"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"කැමරාව"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"දුරකථනය"</string> @@ -164,8 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"ක්ෂණික සැකසීම්."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"අගුළු තිරය."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"සැකසීම්"</string> - <!-- no translation found for accessibility_desc_recent_apps (4876900986661819788) --> - <skip /> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"දළ විශ්ලේෂණය."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"පරිශීලකයා <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wifi අක්රියයි."</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> අවවාද කිරීම"</string> <string name="recents_empty_message" msgid="8682129509540827999">"මෙහි ඔබගේ මෑතක තිර පෙන්නුම් කරයි"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"යෙදුම් තොරතුරු"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"යෙදුමට අඟුළු දැමීම"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"සෙවීම"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ආරම්භ කළ නොහැක."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"අරෝපිතයි"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 6ca0d9f9f4f2..330331289d58 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Vaše nedávne obrazovky sa zobrazia tu."</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Zatvoriť nedávne aplikácie"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"V Prehľade je 1 obrazovka"</item> - <item quantity="other" msgid="5523506463832158203">"V Prehľade je niekoľko obrazoviek (počet: %d)"</item> + <item quantity="one" msgid="3969335317929254918">"Počet obrazoviek v Prehľade: 1"</item> + <item quantity="other" msgid="5523506463832158203">"Počet obrazoviek v Prehľade: %d"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Žiadne upozornenia"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Prebiehajúce"</string> @@ -167,7 +167,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Rýchle nastavenia."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Uzamknutá obrazovka"</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Nastavenia"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Prehľad."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Prehľad"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Používateľ: <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>"</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Pripojenie Wi-Fi je vypnuté."</string> @@ -277,7 +277,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Upozornenie pri <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Vaše nedávne obrazovky sa zobrazia tu."</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Informácie o aplikácii"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"Uzamknutie v aplikácii"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pripnutie k obrazovke"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"hľadať"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikáciu <xliff:g id="APP">%s</xliff:g> sa nepodarilo spustiť"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Nabitá"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 594b760c5839..74faa1dc8c60 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Vaši nedavni zasloni so prikazani tu"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Zapre nedavne aplikacije"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"En zaslon v pregledu"</item> - <item quantity="other" msgid="5523506463832158203">"Št. zaslonov v pregledu: %d"</item> + <item quantity="one" msgid="3969335317929254918">"En zaslon v Pregledu"</item> + <item quantity="other" msgid="5523506463832158203">"Št. zaslonov v Pregledu: %d"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Ni obvestil"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Trenutno"</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Opozorilo – <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Vaši nedavni zasloni so prikazani tu"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Podatki o aplikaciji"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"zakleni v aplikacijo"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"iskanje"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacije <xliff:g id="APP">%s</xliff:g> ni bilo mogoče zagnati."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Akumulator napolnjen"</string> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index f7025fef2087..630f9ce774f6 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Упозорење за <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Недавни екрани се појављују овде"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Информације о апликацији"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"закључај апликацију"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"претражи"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Покретање апликације <xliff:g id="APP">%s</xliff:g> није успело."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Напуњена је"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index d9a7de4d18cf..a58dc68d31d6 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Dina senaste skärmar visas här"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Avvisa nya appar"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"En skärm i översikten"</item> - <item quantity="other" msgid="5523506463832158203">"%d skärmar i översikten"</item> + <item quantity="one" msgid="3969335317929254918">"En skärm i Översikten"</item> + <item quantity="other" msgid="5523506463832158203">"%d skärmar i Översikten"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Inga aviseringar"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Pågående"</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Varning <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Dina senaste skärmar visas här"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Appinformation"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"lås till app"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"sök"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Det gick inte att starta appen <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Laddat"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 399204cf7ca5..d46d5b656dae 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Onyo <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Skrini zako za hivi majuzi huonekana hapa"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Maelezo ya Programu"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"lazimisha kutumia programu"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"tafuta"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Haikuweza kuanzisha <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Betri imejaa"</string> diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml index 7b629d714cb0..850a964e823a 100644 --- a/packages/SystemUI/res/values-ta-rIN/strings.xml +++ b/packages/SystemUI/res/values-ta-rIN/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> எச்சரிக்கை"</string> <string name="recents_empty_message" msgid="8682129509540827999">"சமீபத்திய திரைகள் இங்கு தோன்றும்"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"பயன்பாட்டு தகவல்"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"லாக்-டு-ஆப்"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"தேடு"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ஐத் தொடங்க முடியவில்லை."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"சார்ஜ் செய்யப்பட்டது"</string> diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml index c59e1daa3b2f..393569afb38c 100644 --- a/packages/SystemUI/res/values-te-rIN/strings.xml +++ b/packages/SystemUI/res/values-te-rIN/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"మీ ఇటీవలి స్క్రీన్లు ఇక్కడ కనిపిస్తాయి"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"ఇటీవలి అనువర్తనాలను తీసివేయండి"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"స్థూలదృష్టిలో 1 స్క్రీన్ ఉంది"</item> - <item quantity="other" msgid="5523506463832158203">"స్థూలదృష్టిలో %d స్క్రీన్లు ఉన్నాయి"</item> + <item quantity="one" msgid="3969335317929254918">"అవలోకనంలో 1 స్క్రీన్ ఉంది"</item> + <item quantity="other" msgid="5523506463832158203">"అవలోకనంలో %d స్క్రీన్లు ఉన్నాయి"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"నోటిఫికేషన్లు లేవు"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"కొనసాగుతున్నవి"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"వెనుకకు"</string> <string name="accessibility_home" msgid="8217216074895377641">"హోమ్"</string> <string name="accessibility_menu" msgid="316839303324695949">"మెను"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"స్థూలదృష్టి"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"అవలోకనం"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"శోధించు"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"కెమెరా"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"ఫోన్"</string> @@ -143,7 +143,7 @@ <string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"రోమింగ్"</string> <string name="accessibility_data_connection_edge" msgid="4477457051631979278">"ఎడ్జ్"</string> <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string> - <string name="accessibility_no_sim" msgid="8274017118472455155">"SIM లేదు."</string> + <string name="accessibility_no_sim" msgid="8274017118472455155">"సిమ్ లేదు."</string> <string name="accessibility_bluetooth_tether" msgid="4102784498140271969">"బ్లూటూత్ టెథెరింగ్."</string> <string name="accessibility_airplane_mode" msgid="834748999790763092">"ఎయిర్ప్లేన్ మోడ్."</string> <string name="accessibility_battery_level" msgid="7451474187113371965">"బ్యాటరీ <xliff:g id="NUMBER">%d</xliff:g> శాతం."</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"శీఘ్ర సెట్టింగ్లు."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"లాక్ స్క్రీన్."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"సెట్టింగ్లు"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"స్థూలదృష్టి."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"అవలోకనం."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"వినియోగదారు <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"వైఫై ఆఫ్ చేయబడింది."</string> @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> హెచ్చరిక"</string> <string name="recents_empty_message" msgid="8682129509540827999">"మీ ఇటీవలి స్క్రీన్లు ఇక్కడ కనిపిస్తాయి"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"అనువర్తన సమాచారం"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"లాక్ టు యాప్"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"స్క్రీన్ పిన్నింగ్"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"శోధించు"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g>ని ప్రారంభించడం సాధ్యపడలేదు."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"ఛార్జ్ చేయబడింది"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 45c570f143d7..673e0e485b73 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"คำเตือน <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"หน้าจอล่าสุดของคุณแสดงที่นี่"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"ข้อมูลแอปพลิเคชัน"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"การล็อกแอป"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"การตรึงหน้าจอ"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"ค้นหา"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"ไม่สามารถเริ่มใช้ <xliff:g id="APP">%s</xliff:g>"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"ชาร์จแล้ว"</string> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index a6b7c60ed109..e7db5f84c6da 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Lumalabas dito ang iyong kamakailang screen"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Huwag pansinin ang kamakailang apps"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"1 screen sa Pangkalahatang-ideya"</item> - <item quantity="other" msgid="5523506463832158203">"%d (na) screen sa Pangkalahatang-ideya"</item> + <item quantity="one" msgid="3969335317929254918">"1 screen sa Overview"</item> + <item quantity="other" msgid="5523506463832158203">"%d (na) screen sa Overview"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Walang mga notification"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Nagpapatuloy"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"Bumalik"</string> <string name="accessibility_home" msgid="8217216074895377641">"Home"</string> <string name="accessibility_menu" msgid="316839303324695949">"Menu"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"Pangkalahatang-ideya"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"Overview"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"Hanapin"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"Camera"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"Telepono"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Mga mabilisang setting."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Lock screen."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Mga Setting"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Pangkalahatang-ideya."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Overview"</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"User na si <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Na-off ang wifi."</string> @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Babala sa <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Lumalabas dito ang iyong mga kamakailang screen"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Impormasyon ng Application"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"lock to app"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"pagpi-pin sa screen"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"maghanap"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Hindi masimulan <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Nasingil na"</string> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index e1216133e74f..269743bb3af4 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> uyarısı"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Son ekranlarınız burada görünür"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Uygulama Bilgileri"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"uygulamaya kilitle"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"ara"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> başlatılamadı."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Ödeme alındı"</string> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 0bdb5c517f76..6e31484a0e66 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Ваші останні екрани відображаються тут"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Відхилити останні програми"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"На панелі огляду 1 екран"</item> - <item quantity="other" msgid="5523506463832158203">"Екранів на панелі огляду: %d"</item> + <item quantity="one" msgid="3969335317929254918">"Показано 1 екран"</item> + <item quantity="other" msgid="5523506463832158203">"Показано екранів: %d"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Немає сповіщень"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Поточні"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Швидке налаштування."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Заблокований екран."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Налаштування"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Панель огляду."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Огляд."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Користувач <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-Fi вимкнено."</string> @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Застереження: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Ваші останні екрани відображаються тут"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Інформація про додаток"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"блокування в додатку"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"пошук"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Не вдалося запустити <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Заряджено"</string> diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml index 425133435a11..e3c174e209a1 100644 --- a/packages/SystemUI/res/values-ur-rPK/strings.xml +++ b/packages/SystemUI/res/values-ur-rPK/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> وارننگ"</string> <string name="recents_empty_message" msgid="8682129509540827999">"آپ کی حالیہ اسکرینز یہاں ظاہر ہوتی ہیں"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"ایپلیکیشن کی معلومات"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"لاک ٹو ایپ"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"تلاش کریں"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> کو شروع نہیں کیا جا سکا۔"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"چارج ہوگئی"</string> diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml index 422a82f778a6..3430cf917ab7 100644 --- a/packages/SystemUI/res/values-uz-rUZ/strings.xml +++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml @@ -275,7 +275,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Ogohlantirish: <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Siz yaqinda ishlatgan ilova ekranlari bu yerda ko‘rinadi"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Ilova haqida ma’lumot"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"ilovaga qulflash"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"qidirish"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"“<xliff:g id="APP">%s</xliff:g>” ilovasini ishga tushirib bo‘lmadi."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Batareya quvvati to‘ldi"</string> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index d070968f9dd3..0572930991e8 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"Cảnh báo <xliff:g id="DATA_LIMIT">%s</xliff:g>"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Màn hình gần đây của bạn sẽ xuất hiện tại đây"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Thông tin ứng dụng"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"khóa trong ứng dụng"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"khóa màn hình"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"tìm kiếm"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Không thể khởi động <xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Đã sạc"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index db7e5e56f1ff..b511baff19c0 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -277,7 +277,8 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g>警告"</string> <string name="recents_empty_message" msgid="8682129509540827999">"您最近浏览过的屏幕会显示在此处"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"应用信息"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"固定屏幕"</string> + <!-- no translation found for recents_lock_to_app_button_label (6942899049072506044) --> + <skip /> <string name="recents_search_bar_label" msgid="8074997400187836677">"搜索"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"无法启动<xliff:g id="APP">%s</xliff:g>。"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"充电完成"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 5c5f07e0b2fe..fe8fe85cebc8 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -277,7 +277,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> 警告"</string> <string name="recents_empty_message" msgid="8682129509540827999">"您最近的螢幕顯示在這裡"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"應用程式資料"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"應用程式鎖定"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"螢幕固定"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"無法啟動「<xliff:g id="APP">%s</xliff:g>」。"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"已完成充電"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index cbf73aafb303..773ce0f4caa7 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -277,7 +277,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> 警告"</string> <string name="recents_empty_message" msgid="8682129509540827999">"您最近的螢幕會顯示在這裡"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"應用程式資訊"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"應用程式鎖定"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"螢幕固定"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"搜尋"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"無法啟動「<xliff:g id="APP">%s</xliff:g>」。"</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"已充飽"</string> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 28e0f94fcf13..282acaa6abb2 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -26,8 +26,8 @@ <string name="status_bar_no_recent_apps" msgid="7374907845131203189">"Izikrini zakho zakamuva zivela lapha"</string> <string name="status_bar_accessibility_dismiss_recents" msgid="4576076075226540105">"Susa izinhlelo zokusebenza zakamumva"</string> <plurals name="status_bar_accessibility_recent_apps"> - <item quantity="one" msgid="3969335317929254918">"1 isikrini esiku-Ukubuka konke"</item> - <item quantity="other" msgid="5523506463832158203">"%d wezikrini eziku-Ukubuka konke"</item> + <item quantity="one" msgid="3969335317929254918">"1 isikrini esiku-Buka konke"</item> + <item quantity="other" msgid="5523506463832158203">"%d wezikrini eziku-Buka konke"</item> </plurals> <string name="status_bar_no_notifications_title" msgid="4755261167193833213">"Azikho izaziso"</string> <string name="status_bar_ongoing_events_title" msgid="1682504513316879202">"Okuqhubekayo"</string> @@ -80,7 +80,7 @@ <string name="accessibility_back" msgid="567011538994429120">"Emuva"</string> <string name="accessibility_home" msgid="8217216074895377641">"Ekhaya"</string> <string name="accessibility_menu" msgid="316839303324695949">"Imenyu"</string> - <string name="accessibility_recent" msgid="5208608566793607626">"Ukubuka konke"</string> + <string name="accessibility_recent" msgid="5208608566793607626">"Buka konke"</string> <string name="accessibility_search_light" msgid="1103867596330271848">"Sesha"</string> <string name="accessibility_camera_button" msgid="8064671582820358152">"Ikhamela"</string> <string name="accessibility_phone_button" msgid="6738112589538563574">"Ifoni"</string> @@ -165,7 +165,7 @@ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Izilingiselelo ezisheshayo."</string> <string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Khiya isikrini."</string> <string name="accessibility_desc_settings" msgid="3417884241751434521">"Izilungiselelo"</string> - <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Ukubuka konke."</string> + <string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Buka konke."</string> <string name="accessibility_quick_settings_user" msgid="1104846699869476855">"Umsebenzisi <xliff:g id="USER">%s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string> <string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"I-Wifi ivaliwe."</string> @@ -275,7 +275,7 @@ <string name="quick_settings_cellular_detail_data_warning" msgid="2440098045692399009">"<xliff:g id="DATA_LIMIT">%s</xliff:g> isexwayiso"</string> <string name="recents_empty_message" msgid="8682129509540827999">"Izikrini zakho zakamuva zivela lapha"</string> <string name="recents_app_info_button_label" msgid="2890317189376000030">"Ulwazi lohlelo lokusebenza"</string> - <string name="recents_lock_to_app_button_label" msgid="4793991421811647489">"ukukhiya kuhlelo lokusebenza"</string> + <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"ukuphina isikrini"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"sesha"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Ayikwazanga ukuqala i-<xliff:g id="APP">%s</xliff:g>."</string> <string name="expanded_header_battery_charged" msgid="5945855970267657951">"Kushajiwe"</string> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index aaa350c603ea..4f867a0e422a 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -252,5 +252,8 @@ <!-- Zen toast visibility duration --> <integer name="zen_toast_visible_duration">500</integer> + + <!-- Enable the default volume dialog --> + <bool name="enable_volume_ui">true</bool> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index c4780716e110..07573e075436 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -239,7 +239,7 @@ <dimen name="recents_search_bar_space_height">64dp</dimen> <!-- The side padding for the task stack as a percentage of the width. --> - <item name="recents_stack_width_padding_percentage" format="float" type="dimen">0.04444</item> + <item name="recents_stack_width_padding_percentage" format="float" type="dimen">0.03333</item> <!-- The overscroll percentage allowed on the stack. --> <item name="recents_stack_overscroll_percentage" format="float" type="dimen">0.0875</item> @@ -508,4 +508,10 @@ <dimen name="fake_shadow_inset">1dp</dimen> <dimen name="fake_shadow_size">8dp</dimen> + + <!-- Padding between signal cluster and battery icon --> + <dimen name="signal_cluster_battery_padding">7dp</dimen> + + <!-- Padding for signal cluster and battery icon when there are not icons in signal cluster --> + <dimen name="no_signal_cluster_battery_padding">3dp</dimen> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 89bbacf48470..7a0d655514e4 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -657,8 +657,8 @@ <string name="recents_empty_message">Your recent screens appear here</string> <!-- Recents: The info panel app info button string. [CHAR LIMIT=NONE] --> <string name="recents_app_info_button_label">Application Info</string> - <!-- Recents: The lock-to-app button. [CHAR LIMIT=NONE] --> - <string name="recents_lock_to_app_button_label">lock to app</string> + <!-- Recents: The screen pinning button. [CHAR LIMIT=NONE] --> + <string name="recents_lock_to_app_button_label">screen pinning</string> <!-- Recents: Temporary string for the button in the recents search bar. [CHAR LIMIT=NONE] --> <string name="recents_search_bar_label">search</string> <!-- Recents: Launch error string. [CHAR LIMIT=NONE] --> diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java index 8ef37911694a..f5df1a9ed2bd 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java @@ -144,7 +144,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { showSaverNotification(); mShowing = SHOWING_SAVER; } else { - mNoMan.cancel(TAG_NOTIFICATION, ID_NOTIFICATION); + mNoMan.cancelAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, UserHandle.ALL); mShowing = SHOWING_NOTHING; } } @@ -165,7 +165,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { if (n.headsUpContentView != null) { n.headsUpContentView.setViewVisibility(com.android.internal.R.id.right_icon, View.GONE); } - mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, n, UserHandle.CURRENT); + mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, n, UserHandle.ALL); } private void showWarningNotification() { @@ -202,7 +202,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { if (n.headsUpContentView != null) { n.headsUpContentView.setViewVisibility(com.android.internal.R.id.right_icon, View.GONE); } - mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, n, UserHandle.CURRENT); + mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, n, UserHandle.ALL); } private void showSaverNotification() { @@ -219,7 +219,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { if (hasSaverSettings()) { nb.setContentIntent(pendingActivity(mOpenSaverSettings)); } - mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, nb.build(), UserHandle.CURRENT); + mNoMan.notifyAsUser(TAG_NOTIFICATION, ID_NOTIFICATION, nb.build(), UserHandle.ALL); } private void addStopSaverAction(Notification.Builder nb) { @@ -340,6 +340,11 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { updateNotification(); } + @Override + public void userSwitched() { + updateNotification(); + } + private void showStartSaverConfirmation() { if (mSaverConfirmation != null) return; final SystemUIDialog d = new SystemUIDialog(mContext); @@ -369,7 +374,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI { filter.addAction(ACTION_SHOW_BATTERY_SETTINGS); filter.addAction(ACTION_START_SAVER); filter.addAction(ACTION_STOP_SAVER); - mContext.registerReceiver(this, filter, null, mHandler); + mContext.registerReceiverAsUser(this, UserHandle.ALL, filter, null, mHandler); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java index d3c7dee9e5bb..945974042edf 100644 --- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java +++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java @@ -137,6 +137,7 @@ public class PowerUI extends SystemUI { filter.addAction(Intent.ACTION_BATTERY_CHANGED); filter.addAction(Intent.ACTION_SCREEN_OFF); filter.addAction(Intent.ACTION_SCREEN_ON); + filter.addAction(Intent.ACTION_USER_SWITCHED); filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGING); filter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED); mContext.registerReceiver(this, filter, null, mHandler); @@ -207,6 +208,8 @@ public class PowerUI extends SystemUI { mScreenOffTime = SystemClock.elapsedRealtime(); } else if (Intent.ACTION_SCREEN_ON.equals(action)) { mScreenOffTime = -1; + } else if (Intent.ACTION_USER_SWITCHED.equals(action)) { + mWarnings.userSwitched(); } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)) { updateSaverMode(); } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGING.equals(action)) { @@ -256,6 +259,7 @@ public class PowerUI extends SystemUI { void updateLowBatteryWarning(); boolean isInvalidChargerWarningShowing(); void dump(PrintWriter pw); + void userSwitched(); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java index 1ca67bc07cab..76e818140740 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java +++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java @@ -54,7 +54,7 @@ import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; /** A proxy implementation for the recents component */ -public class AlternateRecentsComponent implements ActivityOptions.OnAnimationStartedListener { +public class AlternateRecentsComponent { final public static String EXTRA_FROM_HOME = "recents.triggeredOverHome"; final public static String EXTRA_FROM_SEARCH_HOME = "recents.triggeredOverSearchHome"; @@ -63,7 +63,6 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta final public static String EXTRA_TRIGGERED_FROM_ALT_TAB = "recents.triggeredFromAltTab"; final public static String EXTRA_TRIGGERED_FROM_HOME_KEY = "recents.triggeredFromHomeKey"; - final public static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation"; final public static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity"; final public static String ACTION_HIDE_RECENTS_ACTIVITY = "action_hide_recents_activity"; @@ -78,9 +77,7 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta Context mContext; LayoutInflater mInflater; SystemServicesProxy mSystemServicesProxy; - Handler mHandler; boolean mBootCompleted; - boolean mStartAnimationTriggered; // Task launching RecentsConfiguration mConfig; @@ -106,7 +103,6 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta mInflater = LayoutInflater.from(context); mContext = context; mSystemServicesProxy = new SystemServicesProxy(context); - mHandler = new Handler(); mTaskStackBounds = new Rect(); } @@ -130,6 +126,9 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta } } } + + // When we start, preload the metadata associated with the previous tasks + RecentsTaskLoader.getInstance().preload(mContext); } public void onBootCompleted() { @@ -327,7 +326,8 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta // If the user has toggled it too quickly, then just eat up the event here (it's better than // showing a janky screenshot). // NOTE: Ideally, the screenshot mechanism would take the window transform into account - if (System.currentTimeMillis() - mLastToggleTime < sMinToggleDelay) { + long currentTime = System.currentTimeMillis(); + if ((currentTime > mLastToggleTime) && (currentTime - mLastToggleTime) < sMinToggleDelay) { return; } @@ -364,30 +364,27 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta * Creates the activity options for a unknown state->recents transition. */ ActivityOptions getUnknownTransitionActivityOptions() { - mStartAnimationTriggered = false; return ActivityOptions.makeCustomAnimation(mContext, R.anim.recents_from_unknown_enter, - R.anim.recents_from_unknown_exit, mHandler, this); + R.anim.recents_from_unknown_exit); } /** * Creates the activity options for a home->recents transition. */ ActivityOptions getHomeTransitionActivityOptions(boolean fromSearchHome) { - mStartAnimationTriggered = false; if (fromSearchHome) { return ActivityOptions.makeCustomAnimation(mContext, R.anim.recents_from_search_launcher_enter, - R.anim.recents_from_search_launcher_exit, mHandler, this); + R.anim.recents_from_search_launcher_exit); } return ActivityOptions.makeCustomAnimation(mContext, R.anim.recents_from_launcher_enter, - R.anim.recents_from_launcher_exit, mHandler, this); + R.anim.recents_from_launcher_exit); } /** - * Creates the activity options for an app->recents transition. If this method sets the static - * screenshot, then we will use that for the transition. + * Creates the activity options for an app->recents transition. */ ActivityOptions getThumbnailTransitionActivityOptions(ActivityManager.RunningTaskInfo topTask, boolean isTopTaskHome) { @@ -411,10 +408,9 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta c.setBitmap(null); } - mStartAnimationTriggered = false; return ActivityOptions.makeThumbnailAspectScaleDownAnimation(mStatusBarView, thumbnail, toTaskRect.left, toTaskRect.top, toTaskRect.width(), - toTaskRect.height(), this); + toTaskRect.height(), null); } // If both the screenshot and thumbnail fails, then just fall back to the default transition @@ -551,42 +547,4 @@ public class AlternateRecentsComponent implements ActivityOptions.OnAnimationSta sRecentsComponentCallbacks.onVisibilityChanged(visible); } } - - /**** OnAnimationStartedListener Implementation ****/ - - @Override - public void onAnimationStarted() { - // Notify recents to start the enter animation - if (!mStartAnimationTriggered) { - // There can be a race condition between the start animation callback and - // the start of the new activity (where we register the receiver that listens - // to this broadcast, so we add our own receiver and if that gets called, then - // we know the activity has not yet started and we can retry sending the broadcast. - BroadcastReceiver fallbackReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (getResultCode() == Activity.RESULT_OK) { - mStartAnimationTriggered = true; - return; - } - - // Schedule for the broadcast to be sent again after some time - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - onAnimationStarted(); - } - }, 75); - } - }; - - // Send the broadcast to notify Recents that the animation has started - Intent intent = new Intent(ACTION_START_ENTER_ANIMATION); - intent.setPackage(mContext.getPackageName()); - intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | - Intent.FLAG_RECEIVER_FOREGROUND); - mContext.sendOrderedBroadcastAsUser(intent, UserHandle.CURRENT, null, - fallbackReceiver, null, Activity.RESULT_CANCELED, null, null); - } - } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index 1c8f55bc029a..d2c55f71ca46 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -28,6 +28,8 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.os.UserHandle; import android.util.Pair; import android.view.KeyEvent; @@ -102,8 +104,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView @Override public void run() { // Mark Recents as no longer visible - AlternateRecentsComponent.notifyVisibilityChanged(false); - mVisible = false; + onRecentsActivityVisibilityChanged(false); // Finish Recents if (mLaunchIntent != null) { if (mLaunchOpts != null) { @@ -141,14 +142,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView } else if (action.equals(AlternateRecentsComponent.ACTION_TOGGLE_RECENTS_ACTIVITY)) { // If we are toggling Recents, then first unfilter any filtered stacks first dismissRecentsToFocusedTaskOrHome(true); - } else if (action.equals(AlternateRecentsComponent.ACTION_START_ENTER_ANIMATION)) { - // Try and start the enter animation (or restart it on configuration changed) - ReferenceCountedTrigger t = new ReferenceCountedTrigger(context, null, null, null); - mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t)); - onEnterAnimationTriggered(); - // Notify the fallback receiver that we have successfully got the broadcast - // See AlternateRecentsComponent.onAnimationStarted() - setResultCode(Activity.RESULT_OK); } } }; @@ -163,6 +156,8 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView if (action.equals(Intent.ACTION_SCREEN_OFF)) { // When the screen turns off, dismiss Recents to Home dismissRecentsToHome(false); + // Start preloading some tasks in the background + RecentsTaskLoader.getInstance().preload(RecentsActivity.this); } else if (action.equals(SearchManager.INTENT_GLOBAL_SEARCH_ACTIVITY_CHANGED)) { // When the search activity changes, update the Search widget refreshSearchWidget(); @@ -433,6 +428,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView } } + /** Called when the configuration changes. */ void onConfigurationChange() { // Update RecentsConfiguration mConfig = RecentsConfiguration.reinitialize(this, @@ -441,7 +437,16 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView // Try and start the enter animation (or restart it on configuration changed) ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null); mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t)); - onEnterAnimationTriggered(); + // Animate the SystemUI scrim views + mScrimViews.startEnterRecentsAnimation(); + } + + /** Handles changes to the activity visibility. */ + void onRecentsActivityVisibilityChanged(boolean visible) { + if (!visible) { + AlternateRecentsComponent.notifyVisibilityChanged(visible); + } + mVisible = visible; } @Override @@ -469,7 +474,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView IntentFilter filter = new IntentFilter(); filter.addAction(AlternateRecentsComponent.ACTION_HIDE_RECENTS_ACTIVITY); filter.addAction(AlternateRecentsComponent.ACTION_TOGGLE_RECENTS_ACTIVITY); - filter.addAction(AlternateRecentsComponent.ACTION_START_ENTER_ANIMATION); registerReceiver(mServiceBroadcastReceiver, filter); // Register any broadcast receivers for the task loader @@ -481,7 +485,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView super.onResume(); // Mark Recents as visible - mVisible = true; + onRecentsActivityVisibilityChanged(true); } @Override @@ -512,6 +516,16 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView } @Override + public void onEnterAnimationComplete() { + // Try and start the enter animation (or restart it on configuration changed) + ReferenceCountedTrigger t = new ReferenceCountedTrigger(this, null, null, null); + mRecentsView.startEnterRecentsAnimation(new ViewAnimation.TaskViewEnterContext(t)); + + // Animate the SystemUI scrim views + mScrimViews.startEnterRecentsAnimation(); + } + + @Override public void onTrimMemory(int level) { RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); if (loader != null) { @@ -592,12 +606,6 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView } } - /** Called when the enter recents animation is triggered. */ - public void onEnterAnimationTriggered() { - // Animate the SystemUI scrim views - mScrimViews.startEnterRecentsAnimation(); - } - /**** RecentsView.RecentsViewCallbacks Implementation ****/ @Override @@ -609,8 +617,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView @Override public void onTaskViewClicked() { // Mark recents as no longer visible - AlternateRecentsComponent.notifyVisibilityChanged(false); - mVisible = false; + onRecentsActivityVisibilityChanged(false); } @Override 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 f01d17c611c9..a0dee07e374a 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/Utilities.java @@ -16,6 +16,7 @@ package com.android.systemui.recents.misc; +import android.animation.Animator; import android.content.Intent; import android.graphics.Color; import android.graphics.Matrix; @@ -188,4 +189,15 @@ public class Utilities { int flags = intent.getFlags(); return (flags & Intent.FLAG_ACTIVITY_NEW_DOCUMENT) == Intent.FLAG_ACTIVITY_NEW_DOCUMENT; } + + /** + * Cancels an animation ensuring that if it has listeners, onCancel and onEnd + * are not called. + */ + public static void cancelAnimationWithoutCallbacks(Animator animator) { + if (animator != null) { + animator.removeAllListeners(); + animator.cancel(); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java b/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java index 7ccefc6ed5f7..97e091613530 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/KeyStoreLruCache.java @@ -21,15 +21,16 @@ import android.util.LruCache; import java.util.HashMap; /** - * An LRU cache that support querying the keys as well as values. By using the Task's key, we can - * prevent holding onto a reference to the Task resource data, while keeping the cache data in - * memory where necessary. + * An LRU cache that internally support querying the keys as well as values. We use this to keep + * track of the task metadata to determine when to invalidate the cache when tasks have been + * updated. Generally, this cache will return the last known cache value for the requested task + * key. */ public class KeyStoreLruCache<V> { // We keep a set of keys that are associated with the LRU cache, so that we can find out // information about the Task that was previously in the cache. HashMap<Integer, Task.TaskKey> mTaskKeys = new HashMap<Integer, Task.TaskKey>(); - // The cache implementation + // The cache implementation, mapping task id -> value LruCache<Integer, V> mCache; public KeyStoreLruCache(int cacheSize) { diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java index 60e89bf880a6..e48e5f053f5f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsPackageMonitor.java @@ -19,6 +19,7 @@ package com.android.systemui.recents.model; import android.content.ComponentName; import android.content.Context; import android.os.Looper; +import android.os.UserHandle; import com.android.internal.content.PackageMonitor; import com.android.systemui.recents.misc.SystemServicesProxy; @@ -26,16 +27,16 @@ import java.util.HashSet; import java.util.List; /** - * The package monitor listens for changes from PackageManager to update the contents of the Recents - * list. + * The package monitor listens for changes from PackageManager to update the contents of the + * Recents list. */ public class RecentsPackageMonitor extends PackageMonitor { public interface PackageCallbacks { - public void onComponentRemoved(HashSet<ComponentName> cns); + public void onPackagesChanged(RecentsPackageMonitor monitor, String packageName, + int userId); } PackageCallbacks mCb; - List<Task.TaskKey> mTasks; SystemServicesProxy mSystemServicesProxy; /** Registers the broadcast receivers with the specified callbacks. */ @@ -43,7 +44,9 @@ public class RecentsPackageMonitor extends PackageMonitor { mSystemServicesProxy = new SystemServicesProxy(context); mCb = cb; try { - register(context, Looper.getMainLooper(), true); + // We register for events from all users, but will cross-reference them with + // packages for the current user and any profiles they have + register(context, Looper.getMainLooper(), UserHandle.ALL, true); } catch (IllegalStateException e) { e.printStackTrace(); } @@ -59,29 +62,15 @@ public class RecentsPackageMonitor extends PackageMonitor { } mSystemServicesProxy = null; mCb = null; - mTasks.clear(); - } - - /** Sets the list of tasks to match against package broadcast changes. */ - void setTasks(List<Task.TaskKey> tasks) { - mTasks = tasks; } @Override public void onPackageRemoved(String packageName, int uid) { if (mCb == null) return; - // Identify all the tasks that should be removed as a result of the package being removed. - // Using a set to ensure that we callback once per unique component. - HashSet<ComponentName> componentsToRemove = new HashSet<ComponentName>(); - for (Task.TaskKey t : mTasks) { - ComponentName cn = t.baseIntent.getComponent(); - if (cn.getPackageName().equals(packageName)) { - componentsToRemove.add(cn); - } - } - // Notify our callbacks that the components no longer exist - mCb.onComponentRemoved(componentsToRemove); + // Notify callbacks that a package has changed + final int eventUserId = getChangingUserId(); + mCb.onPackagesChanged(this, packageName, eventUserId); } @Override @@ -94,25 +83,38 @@ public class RecentsPackageMonitor extends PackageMonitor { public void onPackageModified(String packageName) { if (mCb == null) return; + // Notify callbacks that a package has changed + final int eventUserId = getChangingUserId(); + mCb.onPackagesChanged(this, packageName, eventUserId); + } + + /** + * Computes the components that have been removed as a result of a change in the specified + * package. + */ + public HashSet<ComponentName> computeComponentsRemoved(List<Task.TaskKey> taskKeys, + String packageName, int userId) { // Identify all the tasks that should be removed as a result of the package being removed. // Using a set to ensure that we callback once per unique component. - HashSet<ComponentName> componentsKnownToExist = new HashSet<ComponentName>(); - HashSet<ComponentName> componentsToRemove = new HashSet<ComponentName>(); - for (Task.TaskKey t : mTasks) { + HashSet<ComponentName> existingComponents = new HashSet<ComponentName>(); + HashSet<ComponentName> removedComponents = new HashSet<ComponentName>(); + for (Task.TaskKey t : taskKeys) { + // Skip if this doesn't apply to the current user + if (t.userId != userId) continue; + ComponentName cn = t.baseIntent.getComponent(); if (cn.getPackageName().equals(packageName)) { - if (componentsKnownToExist.contains(cn)) { + if (existingComponents.contains(cn)) { // If we know that the component still exists in the package, then skip continue; } - if (mSystemServicesProxy.getActivityInfo(cn) != null) { - componentsKnownToExist.add(cn); + if (mSystemServicesProxy.getActivityInfo(cn, userId) != null) { + existingComponents.add(cn); } else { - componentsToRemove.add(cn); + removedComponents.add(cn); } } } - // Notify our callbacks that the components no longer exist - mCb.onComponentRemoved(componentsToRemove); + return removedComponents; } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java index d40e8474e573..594eb0e43c12 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoader.java @@ -418,17 +418,25 @@ public class RecentsTaskLoader { root.setStack(stack); // Start the task loader and add all the tasks we need to load - mLoader.start(context); mLoadQueue.addTasks(tasksToLoad); - - // Update the package monitor with the list of packages to listen for - mPackageMonitor.setTasks(taskKeys); + mLoader.start(context); return root; } + /** Preloads the set of recent tasks (not including thumbnails). */ + public void preload(Context context) { + ArrayList<Task> tasksToLoad = new ArrayList<Task>(); + getTaskStack(mSystemServicesProxy, context.getResources(), + -1, -1, true, true, null, tasksToLoad); + + // Start the task loader and add all the tasks we need to load + mLoadQueue.addTasks(tasksToLoad); + mLoader.start(context); + } + /** Creates a lightweight stack of the current recent tasks, without thumbnails and icons. */ - public TaskStack getTaskStack(SystemServicesProxy ssp, Resources res, + public synchronized TaskStack getTaskStack(SystemServicesProxy ssp, Resources res, int preloadTaskId, int preloadTaskCount, boolean loadTaskThumbnails, boolean isTopTaskHome, List<Task.TaskKey> taskKeysOut, List<Task> tasksToLoadOut) { 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 a7e2b0b4f3a3..55dfe4561de8 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/Task.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/Task.java @@ -129,7 +129,7 @@ public class Task { TaskCallbacks mCb; public Task() { - // Only used by RecentsService for task rect calculations. + // Do nothing } public Task(TaskKey key, boolean isActive, int taskAffiliation, int taskAffiliationColor, 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 1e47b504baf4..a37b9e63f30f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/TaskStack.java @@ -255,6 +255,17 @@ public class TaskStack { return mTaskList.getTasks().get(mTaskList.size() - 1); } + /** Gets the task keys */ + public ArrayList<Task.TaskKey> getTaskKeys() { + ArrayList<Task.TaskKey> taskKeys = new ArrayList<Task.TaskKey>(); + ArrayList<Task> tasks = mTaskList.getTasks(); + int taskCount = tasks.size(); + for (int i = 0; i < taskCount; i++) { + taskKeys.add(tasks.get(i).key); + } + return taskKeys; + } + /** Gets the tasks */ public ArrayList<Task> getTasks() { return mTaskList.getTasks(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java index 421b905530c8..5f8f3f26b594 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/AnimateableViewBounds.java @@ -68,7 +68,7 @@ public class AnimateableViewBounds extends ViewOutlineProvider { mSourceView.invalidateOutline(); updateClipBounds(); if (!mConfig.useHardwareLayers) { - mSourceView.mThumbnailView.updateVisibility( + mSourceView.mThumbnailView.updateThumbnailVisibility( bottom - mSourceView.getPaddingBottom()); } } 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 9dfebfee627b..6b0d3066720e 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -18,7 +18,6 @@ package com.android.systemui.recents.views; import android.app.ActivityOptions; import android.app.TaskStackBuilder; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; @@ -42,7 +41,6 @@ import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.TaskStack; import java.util.ArrayList; -import java.util.HashSet; /** * This view is the the top level layout that contains TaskStacks (which are laid out according @@ -564,14 +562,14 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV /**** RecentsPackageMonitor.PackageCallbacks Implementation ****/ @Override - public void onComponentRemoved(HashSet<ComponentName> cns) { + public void onPackagesChanged(RecentsPackageMonitor monitor, String packageName, int userId) { // Propagate this event down to each task stack view int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); if (child != mSearchBar) { TaskStackView stackView = (TaskStackView) child; - stackView.onComponentRemoved(cns); + stackView.onPackagesChanged(monitor, packageName, userId); } } } 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 e479952b4381..dee26e6e45ca 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -1081,12 +1081,16 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal /**** RecentsPackageMonitor.PackageCallbacks Implementation ****/ @Override - public void onComponentRemoved(HashSet<ComponentName> cns) { + public void onPackagesChanged(RecentsPackageMonitor monitor, String packageName, int userId) { + // Compute which components need to be removed + HashSet<ComponentName> removedComponents = monitor.computeComponentsRemoved( + mStack.getTaskKeys(), packageName, userId); + // For other tasks, just remove them directly if they no longer exist ArrayList<Task> tasks = mStack.getTasks(); for (int i = tasks.size() - 1; i >= 0; i--) { final Task t = tasks.get(i); - if (cns.contains(t.key.baseIntent.getComponent())) { + if (removedComponents.contains(t.key.baseIntent.getComponent())) { TaskView tv = getChildViewForTask(t); if (tv != null) { // For visible children, defer removing the task until after the animation 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 c9113fe6cc5b..04f7c6fca64b 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackViewScroller.java @@ -23,6 +23,7 @@ import android.animation.ValueAnimator; import android.content.Context; import android.widget.OverScroller; import com.android.systemui.recents.RecentsConfiguration; +import com.android.systemui.recents.misc.Utilities; /* The scrolling logic for a TaskStackView */ public class TaskStackViewScroller { @@ -161,10 +162,7 @@ public class TaskStackViewScroller { /** Aborts any current stack scrolls */ void stopBoundScrollAnimation() { - if (mScrollAnimator != null) { - mScrollAnimator.removeAllListeners(); - mScrollAnimator.cancel(); - } + Utilities.cancelAnimationWithoutCallbacks(mScrollAnimator); } /**** OverScroller ****/ diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index dfb30f30b378..7b4e10a74b3d 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -28,10 +28,9 @@ import android.view.ViewPropertyAnimator; import android.view.animation.AccelerateInterpolator; import android.widget.FrameLayout; import com.android.systemui.R; -import com.android.systemui.recents.AlternateRecentsComponent; import com.android.systemui.recents.Constants; import com.android.systemui.recents.RecentsConfiguration; -import com.android.systemui.recents.model.RecentsTaskLoader; +import com.android.systemui.recents.misc.Utilities; import com.android.systemui.recents.model.Task; import com.android.systemui.statusbar.phone.PhoneStatusBar; @@ -53,11 +52,11 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, float mTaskProgress; ObjectAnimator mTaskProgressAnimator; - ObjectAnimator mDimAnimator; float mMaxDimScale; - int mDim; + int mDimAlpha; AccelerateInterpolator mDimInterpolator = new AccelerateInterpolator(1f); - PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.MULTIPLY); + PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP); + Paint mDimLayerPaint = new Paint(); Task mTask; boolean mTaskDataLoaded; @@ -65,7 +64,6 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, boolean mFocusAnimationsEnabled; boolean mClipViewInStack; AnimateableViewBounds mViewBounds; - Paint mLayerPaint = new Paint(); View mContent; TaskViewThumbnail mThumbnailView; @@ -130,7 +128,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, mContent = findViewById(R.id.task_view_content); mHeaderView = (TaskViewHeader) findViewById(R.id.task_view_bar); mThumbnailView = (TaskViewThumbnail) findViewById(R.id.task_view_thumbnail); - mThumbnailView.enableTaskBarClip(mHeaderView); + mThumbnailView.updateClipToTaskBar(mHeaderView); mActionButtonView = findViewById(R.id.lock_to_app_fab); mActionButtonView.setOutlineProvider(new ViewOutlineProvider() { @Override @@ -179,10 +177,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, !mConfig.fakeShadows, updateCallback); // Update the task progress - if (mTaskProgressAnimator != null) { - mTaskProgressAnimator.removeAllListeners(); - mTaskProgressAnimator.cancel(); - } + Utilities.cancelAnimationWithoutCallbacks(mTaskProgressAnimator); if (duration <= 0) { setTaskProgress(toTransform.p); } else { @@ -377,7 +372,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, mThumbnailView.startLaunchTaskAnimation(postAnimRunnable); // Animate the dim - if (mDim > 0) { + if (mDimAlpha > 0) { ObjectAnimator anim = ObjectAnimator.ofInt(this, "dim", 0); anim.setDuration(mConfig.taskBarExitAnimDuration); anim.setInterpolator(mConfig.fastOutLinearInInterpolator); @@ -495,26 +490,16 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, /** Returns the current dim. */ public void setDim(int dim) { - mDim = dim; - if (mDimAnimator != null) { - mDimAnimator.removeAllListeners(); - mDimAnimator.cancel(); - } + mDimAlpha = dim; if (mConfig.useHardwareLayers) { // Defer setting hardware layers if we have not yet measured, or there is no dim to draw if (getMeasuredWidth() > 0 && getMeasuredHeight() > 0) { - if (mDimAnimator != null) { - mDimAnimator.removeAllListeners(); - mDimAnimator.cancel(); - } - - int inverse = 255 - mDim; - mDimColorFilter.setColor(Color.argb(0xFF, inverse, inverse, inverse)); - mLayerPaint.setColorFilter(mDimColorFilter); - mContent.setLayerType(LAYER_TYPE_HARDWARE, mLayerPaint); + mDimColorFilter.setColor(Color.argb(mDimAlpha, 0, 0, 0)); + mDimLayerPaint.setColorFilter(mDimColorFilter); + mContent.setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint); } } else { - float dimAlpha = mDim / 255.0f; + float dimAlpha = mDimAlpha / 255.0f; if (mThumbnailView != null) { mThumbnailView.setDimAlpha(dimAlpha); } @@ -526,7 +511,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, /** Returns the current dim. */ public int getDim() { - return mDim; + return mDimAlpha; } /** Animates the dim to the task progress. */ 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 6554f820b5a6..ba868f5bc90d 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewHeader.java @@ -36,7 +36,6 @@ import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.RippleDrawable; -import android.graphics.drawable.ShapeDrawable; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; @@ -56,23 +55,27 @@ public class TaskViewHeader extends FrameLayout { RecentsConfiguration mConfig; + // Header views ImageView mDismissButton; ImageView mApplicationIcon; TextView mActivityDescription; - RippleDrawable mBackground; - GradientDrawable mBackgroundColorDrawable; + // Header drawables + boolean mCurrentPrimaryColorIsDark; + int mCurrentPrimaryColor; int mBackgroundColor; Drawable mLightDismissDrawable; Drawable mDarkDismissDrawable; + RippleDrawable mBackground; + GradientDrawable mBackgroundColorDrawable; AnimatorSet mFocusAnimator; - PorterDuffColorFilter mDimFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP); - - boolean mCurrentPrimaryColorIsDark; - int mCurrentPrimaryColor; + // Static highlight that we draw at the top of each view static Paint sHighlightPaint; - private Paint mDimPaint = new Paint(); + + // Header dim, which is only used when task view hardware layers are not used + Paint mDimLayerPaint = new Paint(); + PorterDuffColorFilter mDimColorFilter = new PorterDuffColorFilter(0, PorterDuff.Mode.SRC_ATOP); public TaskViewHeader(Context context) { this(context, null); @@ -172,6 +175,16 @@ public class TaskViewHeader extends FrameLayout { return false; } + /** + * Sets the dim alpha, only used when we are not using hardware layers. + * (see RecentsConfiguration.useHardwareLayers) + */ + void setDimAlpha(int alpha) { + mDimColorFilter.setColor(Color.argb(alpha, 0, 0, 0)); + mDimLayerPaint.setColorFilter(mDimColorFilter); + setLayerType(LAYER_TYPE_HARDWARE, mDimLayerPaint); + } + /** Returns the secondary color for a primary color. */ int getSecondaryColor(int primaryColor, boolean useLightOverlayColor) { int overlayColor = useLightOverlayColor ? Color.WHITE : Color.BLACK; @@ -266,8 +279,7 @@ public class TaskViewHeader extends FrameLayout { boolean isRunning = false; if (mFocusAnimator != null) { isRunning = mFocusAnimator.isRunning(); - mFocusAnimator.removeAllListeners(); - mFocusAnimator.cancel(); + Utilities.cancelAnimationWithoutCallbacks(mFocusAnimator); } if (focused) { @@ -344,11 +356,4 @@ public class TaskViewHeader extends FrameLayout { } } } - - public void setDimAlpha(int alpha) { - int color = Color.argb(alpha, 0, 0, 0); - mDimFilter.setColor(color); - mDimPaint.setColorFilter(mDimFilter); - setLayerType(LAYER_TYPE_HARDWARE, mDimPaint); - } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java index a946a849310b..c83248ef37d9 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewThumbnail.java @@ -33,37 +33,48 @@ import android.graphics.Shader; import android.util.AttributeSet; import android.view.View; import com.android.systemui.recents.RecentsConfiguration; +import com.android.systemui.recents.misc.Utilities; import com.android.systemui.recents.model.Task; -/** The task thumbnail view */ +/** + * The task thumbnail view. It implements an image view that allows for animating the dim and + * alpha of the thumbnail image. + */ public class TaskViewThumbnail extends View { - private final int mCornerRadius; - private final Matrix mScaleMatrix = new Matrix(); RecentsConfiguration mConfig; - // Task bar clipping - Rect mClipRect = new Rect(); + // Drawing + float mDimAlpha; + Matrix mScaleMatrix = new Matrix(); Paint mDrawPaint = new Paint(); + RectF mBitmapRect = new RectF(); + RectF mLayoutRect = new RectF(); + BitmapShader mBitmapShader; LightingColorFilter mLightingColorFilter = new LightingColorFilter(0xffffffff, 0); - private final RectF mBitmapRect = new RectF(); - private final RectF mLayoutRect = new RectF(); - private BitmapShader mBitmapShader; - private float mBitmapAlpha; - private float mDimAlpha; - private View mTaskBar; - private boolean mInvisible; - private ValueAnimator mAlphaAnimator; - private ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener + + // Thumbnail alpha + float mThumbnailAlpha; + ValueAnimator mThumbnailAlphaAnimator; + ValueAnimator.AnimatorUpdateListener mThumbnailAlphaUpdateListener = new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { - mBitmapAlpha = (float) animation.getAnimatedValue(); - updateFilter(); + mThumbnailAlpha = (float) animation.getAnimatedValue(); + updateThumbnailPaintFilter(); } }; + // Task bar clipping, the top of this thumbnail can be clipped against the opaque header + // bar that overlaps this thumbnail + View mTaskBar; + Rect mClipRect = new Rect(); + + // Visibility optimization, if the thumbnail height is less than the height of the header + // bar for the task view, then just mark this thumbnail view as invisible + boolean mInvisible; + public TaskViewThumbnail(Context context) { this(context, null); } @@ -79,53 +90,82 @@ public class TaskViewThumbnail extends View { public TaskViewThumbnail(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mConfig = RecentsConfiguration.getInstance(); - mCornerRadius = mConfig.taskViewRoundedCornerRadiusPx; mDrawPaint.setColorFilter(mLightingColorFilter); mDrawPaint.setFilterBitmap(true); mDrawPaint.setAntiAlias(true); } @Override + protected void onFinishInflate() { + mThumbnailAlpha = mConfig.taskViewThumbnailAlpha; + updateThumbnailPaintFilter(); + } + + @Override + protected void onLayout(boolean changed, int left, int top, int right, int bottom) { + super.onLayout(changed, left, top, right, bottom); + if (changed) { + mLayoutRect.set(0, 0, getWidth(), getHeight()); + updateThumbnailScale(); + } + } + + @Override protected void onDraw(Canvas canvas) { if (mInvisible) { return; } - canvas.drawRoundRect(0, - 0, - getWidth(), - getHeight(), - mCornerRadius, - mCornerRadius, - mDrawPaint); + // Draw the thumbnail with the rounded corners + canvas.drawRoundRect(0, 0, getWidth(), getHeight(), + mConfig.taskViewRoundedCornerRadiusPx, + mConfig.taskViewRoundedCornerRadiusPx, mDrawPaint); } - @Override - protected void onFinishInflate() { - mBitmapAlpha = 0.9f; - updateFilter(); + /** Sets the thumbnail to a given bitmap. */ + void setThumbnail(Bitmap bm) { + if (bm != null) { + mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, + Shader.TileMode.CLAMP); + mDrawPaint.setShader(mBitmapShader); + mBitmapRect.set(0, 0, bm.getWidth(), bm.getHeight()); + updateThumbnailScale(); + } else { + mBitmapShader = null; + mDrawPaint.setShader(null); + } + updateThumbnailPaintFilter(); } - private void updateFilter() { + /** Updates the paint to draw the thumbnail. */ + void updateThumbnailPaintFilter() { if (mInvisible) { return; } - int mul = (int) ((1.0f - mDimAlpha) * mBitmapAlpha * 255); - int add = (int) ((1.0f - mDimAlpha) * (1 - mBitmapAlpha) * 255); + int mul = (int) ((1.0f - mDimAlpha) * mThumbnailAlpha * 255); + int add = (int) ((1.0f - mDimAlpha) * (1 - mThumbnailAlpha) * 255); if (mBitmapShader != null) { mLightingColorFilter.setColorMultiply(Color.argb(255, mul, mul, mul)); mLightingColorFilter.setColorAdd(Color.argb(0, add, add, add)); mDrawPaint.setColorFilter(mLightingColorFilter); mDrawPaint.setColor(0xffffffff); } else { - mDrawPaint.setColorFilter(null); int grey = mul + add; + mDrawPaint.setColorFilter(null); mDrawPaint.setColor(Color.argb(255, grey, grey, grey)); } invalidate(); } + /** Updates the thumbnail shader's scale transform. */ + void updateThumbnailScale() { + if (mBitmapShader != null) { + mScaleMatrix.setRectToRect(mBitmapRect, mLayoutRect, Matrix.ScaleToFit.FILL); + mBitmapShader.setLocalMatrix(mScaleMatrix); + } + } + /** Updates the clip rect based on the given task bar. */ - void enableTaskBarClip(View taskBar) { + void updateClipToTaskBar(View taskBar) { mTaskBar = taskBar; int top = (int) Math.max(0, taskBar.getTranslationY() + taskBar.getMeasuredHeight() - 1); @@ -133,75 +173,39 @@ public class TaskViewThumbnail extends View { setClipBounds(mClipRect); } - void updateVisibility(int clipBottom) { - boolean invisible = mTaskBar != null && getHeight() - clipBottom < mTaskBar.getHeight(); + /** Updates the visibility of the the thumbnail. */ + void updateThumbnailVisibility(int clipBottom) { + boolean invisible = mTaskBar != null && (getHeight() - clipBottom) <= mTaskBar.getHeight(); if (invisible != mInvisible) { mInvisible = invisible; if (!mInvisible) { - updateFilter(); + updateThumbnailPaintFilter(); } invalidate(); } } - /** Binds the thumbnail view to the screenshot. */ - boolean bindToScreenshot(Bitmap ss) { - setImageBitmap(ss); - return ss != null; - } - - /** Unbinds the thumbnail view from the screenshot. */ - void unbindFromScreenshot() { - setImageBitmap(null); + /** + * Sets the dim alpha, only used when we are not using hardware layers. + * (see RecentsConfiguration.useHardwareLayers) + */ + public void setDimAlpha(float dimAlpha) { + mDimAlpha = dimAlpha; + updateThumbnailPaintFilter(); } /** Binds the thumbnail view to the task */ void rebindToTask(Task t) { if (t.thumbnail != null) { - setImageBitmap(t.thumbnail); + setThumbnail(t.thumbnail); } else { - setImageBitmap(null); + setThumbnail(null); } } - public void setImageBitmap(Bitmap bm) { - if (bm != null) { - mBitmapShader = new BitmapShader(bm, Shader.TileMode.CLAMP, - Shader.TileMode.CLAMP); - mDrawPaint.setShader(mBitmapShader); - mBitmapRect.set(0, 0, bm.getWidth(), bm.getHeight()); - updateBitmapScale(); - } else { - mBitmapShader = null; - mDrawPaint.setShader(null); - } - updateFilter(); - } - - @Override - protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - super.onLayout(changed, left, top, right, bottom); - if (changed) { - mLayoutRect.set(0, 0, getWidth(), getHeight()); - updateBitmapScale(); - } - } - - private void updateBitmapScale() { - if (mBitmapShader != null) { - mScaleMatrix.setRectToRect(mBitmapRect, mLayoutRect, Matrix.ScaleToFit.FILL); - mBitmapShader.setLocalMatrix(mScaleMatrix); - } - } - - public void setDimAlpha(float dimAlpha) { - mDimAlpha = dimAlpha; - updateFilter(); - } - /** Unbinds the thumbnail view from the task */ void unbindFromTask() { - setImageBitmap(null); + setThumbnail(null); } /** Handles focus changes. */ @@ -217,54 +221,46 @@ public class TaskViewThumbnail extends View { } } - /** Prepares for the enter recents animation. */ + /** + * Prepares for the enter recents animation, this gets called before the the view + * is first visible and will be followed by a startEnterRecentsAnimation() call. + */ void prepareEnterRecentsAnimation(boolean isTaskViewLaunchTargetTask) { if (isTaskViewLaunchTargetTask) { - mBitmapAlpha = 1f; + mThumbnailAlpha = 1f; } else { - mBitmapAlpha = mConfig.taskViewThumbnailAlpha; + mThumbnailAlpha = mConfig.taskViewThumbnailAlpha; } - updateFilter(); + updateThumbnailPaintFilter(); } - /** Animates this task thumbnail as it enters recents */ + /** Animates this task thumbnail as it enters Recents. */ void startEnterRecentsAnimation(int delay, Runnable postAnimRunnable) { startFadeAnimation(mConfig.taskViewThumbnailAlpha, delay, mConfig.taskBarEnterAnimDuration, postAnimRunnable); } - /** Animates this task thumbnail as it exits recents */ + /** Animates this task thumbnail as it exits Recents. */ void startLaunchTaskAnimation(Runnable postAnimRunnable) { startFadeAnimation(1f, 0, mConfig.taskBarExitAnimDuration, postAnimRunnable); } - /** Animates the thumbnail alpha. */ + /** Starts a new thumbnail alpha animation. */ void startFadeAnimation(float finalAlpha, int delay, int duration, final Runnable postAnimRunnable) { - if (mAlphaAnimator != null) { - mAlphaAnimator.cancel(); - } - mAlphaAnimator = ValueAnimator.ofFloat(mBitmapAlpha, finalAlpha); - mAlphaAnimator.addUpdateListener(mAlphaUpdateListener); - mAlphaAnimator.setStartDelay(delay); - mAlphaAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator); - mAlphaAnimator.setDuration(duration); - mAlphaAnimator.start(); + Utilities.cancelAnimationWithoutCallbacks(mThumbnailAlphaAnimator); + mThumbnailAlphaAnimator = ValueAnimator.ofFloat(mThumbnailAlpha, finalAlpha); + mThumbnailAlphaAnimator.setStartDelay(delay); + mThumbnailAlphaAnimator.setDuration(duration); + mThumbnailAlphaAnimator.setInterpolator(mConfig.fastOutSlowInInterpolator); + mThumbnailAlphaAnimator.addUpdateListener(mThumbnailAlphaUpdateListener); if (postAnimRunnable != null) { - mAlphaAnimator.addListener(new AnimatorListenerAdapter() { - public boolean mCancelled; - - @Override - public void onAnimationCancel(Animator animation) { - mCancelled = true; - } - + mThumbnailAlphaAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - if (!mCancelled) { - postAnimRunnable.run(); - } + postAnimRunnable.run(); } }); } + mThumbnailAlphaAnimator.start(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java index f5e5517b731c..7c74246ba4d2 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java @@ -69,6 +69,7 @@ import android.view.View; import android.view.ViewAnimationUtils; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; +import android.view.ViewParent; import android.view.ViewStub; import android.view.WindowManager; import android.view.WindowManagerGlobal; @@ -266,6 +267,7 @@ public abstract class BaseStatusBar extends SystemUI implements if (DEBUG) { Log.v(TAG, "Notification click handler invoked for intent: " + pendingIntent); } + logActionClick(view); // The intent we are sending is for the application, which // won't have permission to immediately start an activity after // the user switches to home. We know it is safe to do at this @@ -308,6 +310,37 @@ public abstract class BaseStatusBar extends SystemUI implements } } + private void logActionClick(View view) { + ViewParent parent = view.getParent(); + String key = getNotificationKeyForParent(parent); + if (key == null) { + Log.w(TAG, "Couldn't determine notification for click."); + return; + } + int index = -1; + // If this is a default template, determine the index of the button. + if (view.getId() == com.android.internal.R.id.action0 && + parent != null && parent instanceof ViewGroup) { + ViewGroup actionGroup = (ViewGroup) parent; + index = actionGroup.indexOfChild(view); + } + try { + mBarService.onNotificationActionClick(key, index); + } catch (RemoteException e) { + // Ignore + } + } + + private String getNotificationKeyForParent(ViewParent parent) { + while (parent != null) { + if (parent instanceof ExpandableNotificationRow) { + return ((ExpandableNotificationRow) parent).getStatusBarNotification().getKey(); + } + parent = parent.getParent(); + } + return null; + } + private boolean superOnClickHandler(View view, PendingIntent pendingIntent, Intent fillInIntent) { return super.onClickHandler(view, pendingIntent, fillInIntent); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 9196dc89c6c3..556c423080b9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -158,6 +158,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { public void resetHeight() { mMaxExpandHeight = 0; mWasReset = true; + mActualHeight = 0; onHeightReset(); requestLayout(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java index b71c9bfc8f60..9154a487e8ac 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/SignalClusterView.java @@ -49,7 +49,6 @@ public class SignalClusterView private boolean mIsAirplaneMode = false; private int mAirplaneIconId = 0; private String mWifiDescription, mMobileDescription, mMobileTypeDescription; - private boolean mRoaming; private boolean mIsMobileTypeIconWide; ViewGroup mWifiGroup, mMobileGroup; @@ -58,6 +57,8 @@ public class SignalClusterView View mWifiSignalSpacer; private int mWideTypeIconStartPadding; + private int mEndPadding; + private int mEndPaddingNothingVisible; public SignalClusterView(Context context) { this(context, null); @@ -88,6 +89,10 @@ public class SignalClusterView super.onFinishInflate(); mWideTypeIconStartPadding = getContext().getResources().getDimensionPixelSize( R.dimen.wide_type_icon_start_padding); + mEndPadding = getContext().getResources().getDimensionPixelSize( + R.dimen.signal_cluster_battery_padding); + mEndPaddingNothingVisible = getContext().getResources().getDimensionPixelSize( + R.dimen.no_signal_cluster_battery_padding); } @Override @@ -143,14 +148,12 @@ public class SignalClusterView @Override public void setMobileDataIndicators(boolean visible, int strengthIcon, int typeIcon, - String contentDescription, String typeContentDescription, boolean roaming, - boolean isTypeIconWide) { + String contentDescription, String typeContentDescription, boolean isTypeIconWide) { mMobileVisible = visible; mMobileStrengthId = strengthIcon; mMobileTypeId = typeIcon; mMobileDescription = contentDescription; mMobileTypeDescription = typeContentDescription; - mRoaming = roaming; mIsMobileTypeIconWide = isTypeIconWide; apply(); @@ -244,7 +247,7 @@ public class SignalClusterView mWifiAirplaneSpacer.setVisibility(View.GONE); } - if (mRoaming && mMobileVisible && mWifiVisible) { + if (mMobileVisible && mMobileTypeId != 0 && mWifiVisible) { mWifiSignalSpacer.setVisibility(View.VISIBLE); } else { mWifiSignalSpacer.setVisibility(View.GONE); @@ -257,7 +260,10 @@ public class SignalClusterView (mMobileVisible ? "VISIBLE" : "GONE"), mMobileStrengthId, mMobileTypeId)); - mMobileType.setVisibility((mRoaming || mMobileTypeId != 0) ? View.VISIBLE : View.GONE); + mMobileType.setVisibility(mMobileTypeId != 0 ? View.VISIBLE : View.GONE); + + boolean anythingVisible = mWifiVisible || mIsAirplaneMode || mMobileVisible || mVpnVisible; + setPaddingRelative(0, 0, anythingVisible ? mEndPadding : mEndPaddingNothingVisible, 0); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index a6fccb624ab2..c19bdffaf466 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -802,6 +802,7 @@ public class NotificationPanelView extends PanelView implements requestPanelHeightUpdate(); mNotificationStackScroller.setInterceptDelegateEnabled(expanded); mStatusBar.setQsExpanded(expanded); + mQsPanel.setExpanded(expanded); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java index f74d2f4baf70..3efaaff21a4d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java @@ -236,4 +236,8 @@ public class PanelBar extends FrameLayout { public void onExpandingFinished() { } + + public void onClosingFinished() { + + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java index a7ff0bde678b..0ddda8a3ab12 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -68,7 +68,6 @@ public abstract class PanelView extends FrameLayout { protected int mTouchSlop; protected boolean mHintAnimationRunning; private boolean mOverExpandedBeforeFling; - private float mOriginalIndicationY; private boolean mTouchAboveFalsingThreshold; private int mUnlockFalsingThreshold; @@ -107,7 +106,7 @@ public abstract class PanelView extends FrameLayout { }; protected void onExpandingFinished() { - mClosing = false; + endClosing(); mBar.onExpandingFinished(); } @@ -250,9 +249,7 @@ public abstract class PanelView extends FrameLayout { trackMovement(event); if (!waitForTouchSlop || (mHeightAnimator != null && !mHintAnimationRunning) || mPeekPending || mPeekAnimator != null) { - if (mHeightAnimator != null) { - mHeightAnimator.cancel(); // end any outstanding animations - } + cancelHeightAnimator(); cancelPeek(); mTouchSlopExceeded = (mHeightAnimator != null && !mHintAnimationRunning) || mPeekPending || mPeekAnimator != null; @@ -293,9 +290,7 @@ public abstract class PanelView extends FrameLayout { mInitialTouchY = y; h = 0; } - if (mHeightAnimator != null) { - mHeightAnimator.cancel(); // end any outstanding animations - } + cancelHeightAnimator(); removeCallbacks(mPeekRunnable); mPeekPending = false; onTrackingStarted(); @@ -372,7 +367,7 @@ public abstract class PanelView extends FrameLayout { } protected void onTrackingStarted() { - mClosing = false; + endClosing(); mTracking = true; mCollapseAfterPeek = false; mBar.onTrackingStarted(PanelView.this); @@ -407,9 +402,7 @@ public abstract class PanelView extends FrameLayout { mStatusBar.userActivity(); if (mHeightAnimator != null && !mHintAnimationRunning || mPeekPending || mPeekAnimator != null) { - if (mHeightAnimator != null) { - mHeightAnimator.cancel(); // end any outstanding animations - } + cancelHeightAnimator(); cancelPeek(); mTouchSlopExceeded = true; return true; @@ -441,9 +434,7 @@ public abstract class PanelView extends FrameLayout { trackMovement(event); if (scrolledToBottom) { if (h < -mTouchSlop && h < -Math.abs(x - mInitialTouchX)) { - if (mHeightAnimator != null) { - mHeightAnimator.cancel(); - } + cancelHeightAnimator(); mInitialOffsetOnTouch = mExpandedHeight; mInitialTouchY = y; mInitialTouchX = x; @@ -461,6 +452,20 @@ public abstract class PanelView extends FrameLayout { return false; } + private void cancelHeightAnimator() { + if (mHeightAnimator != null) { + mHeightAnimator.cancel(); + } + endClosing(); + } + + private void endClosing() { + if (mClosing) { + mClosing = false; + onClosingFinished(); + } + } + private void initVelocityTracker() { if (mVelocityTracker != null) { mVelocityTracker.recycle(); @@ -700,9 +705,7 @@ public abstract class PanelView extends FrameLayout { mPeekRunnable.run(); } } else if (!isFullyCollapsed() && !mTracking && !mClosing) { - if (mHeightAnimator != null) { - mHeightAnimator.cancel(); - } + cancelHeightAnimator(); mClosing = true; notifyExpandingStarted(); if (delayed) { @@ -785,13 +788,16 @@ public abstract class PanelView extends FrameLayout { private void abortAnimations() { cancelPeek(); - if (mHeightAnimator != null) { - mHeightAnimator.cancel(); - } + cancelHeightAnimator(); removeCallbacks(mPostCollapseRunnable); removeCallbacks(mFlingCollapseRunnable); } + protected void onClosingFinished() { + mBar.onClosingFinished(); + } + + protected void startUnlockHintAnimation() { // We don't need to hint the user if an animation is already running or the user is changing @@ -841,16 +847,15 @@ public abstract class PanelView extends FrameLayout { }); animator.start(); mHeightAnimator = animator; - mOriginalIndicationY = mKeyguardBottomArea.getIndicationView().getY(); mKeyguardBottomArea.getIndicationView().animate() - .y(mOriginalIndicationY - mHintDistance) + .translationY(-mHintDistance) .setDuration(250) .setInterpolator(mFastOutSlowInInterpolator) .withEndAction(new Runnable() { @Override public void run() { mKeyguardBottomArea.getIndicationView().animate() - .y(mOriginalIndicationY) + .translationY(0) .setDuration(450) .setInterpolator(mBounceInterpolator) .start(); 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 4980c1cd72e8..be27ddcee42b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -175,6 +175,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; +import java.util.Map; public class PhoneStatusBar extends BaseStatusBar implements DemoMode, DragDownHelper.DragDownCallback, ActivityStarter { @@ -800,7 +801,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } mUserInfoController = new UserInfoController(mContext); mVolumeComponent = getComponent(VolumeComponent.class); - mZenModeController = mVolumeComponent.getZenController(); + if (mVolumeComponent != null) { + mZenModeController = mVolumeComponent.getZenController(); + } mCastController = new CastControllerImpl(mContext); final SignalClusterView signalCluster = (SignalClusterView) mStatusBarView.findViewById(R.id.signal_cluster); @@ -2963,6 +2966,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, if (mSecurityController != null) { mSecurityController.dump(fd, pw, args); } + pw.println("SharedPreferences:"); + for (Map.Entry<String, ?> entry : mContext.getSharedPreferences(mContext.getPackageName(), + Context.MODE_PRIVATE).getAll().entrySet()) { + pw.print(" "); pw.print(entry.getKey()); pw.print("="); pw.println(entry.getValue()); + } } private String hunStateToString(Entry entry) { @@ -3787,6 +3795,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, runPostCollapseRunnables(); } + public void onClosingFinished() { + runPostCollapseRunnables(); + } + public void onUnlockHintStarted() { mKeyguardIndicationController.showTransientIndication(R.string.keyguard_unlock); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java index 6411fb84ccd2..e4eae38fcdcd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.res.Resources; import android.util.AttributeSet; import android.util.EventLog; -import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.accessibility.AccessibilityEvent; @@ -152,6 +151,12 @@ public class PhoneStatusBarView extends PanelBar { } @Override + public void onClosingFinished() { + super.onClosingFinished(); + mBar.onClosingFinished(); + } + + @Override public void onTrackingStopped(PanelView panel, boolean expand) { super.onTrackingStopped(panel, expand); mBar.onTrackingStopped(expand); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java index ca853a964d29..247252cfcc48 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java @@ -302,9 +302,6 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL updateSystemIconsLayoutParams(); updateClickTargets(); updateMultiUserSwitch(); - if (mQSPanel != null) { - mQSPanel.setExpanded(mExpanded); - } updateClockScale(); updateAvatarScale(); updateClockLp(); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java index 36259979b13e..b2198f64c823 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java @@ -164,8 +164,7 @@ public class NetworkControllerImpl extends BroadcastReceiver public interface SignalCluster { void setWifiIndicators(boolean visible, int strengthIcon, String contentDescription); void setMobileDataIndicators(boolean visible, int strengthIcon, int typeIcon, - String contentDescription, String typeContentDescription, boolean roaming, - boolean isTypeIconWide); + String contentDescription, String typeContentDescription, boolean isTypeIconWide); void setIsAirplaneMode(boolean is, int airplaneIcon); } @@ -386,7 +385,6 @@ public class NetworkControllerImpl extends BroadcastReceiver mDataTypeIconId, mContentDescriptionWimax, mContentDescriptionDataType, - mDataTypeIconId == TelephonyIcons.ROAMING_ICON, false /* isTypeIconWide */ ); } else { // normal mobile data @@ -396,7 +394,6 @@ public class NetworkControllerImpl extends BroadcastReceiver mDataTypeIconId, mContentDescriptionPhoneSignal, mContentDescriptionDataType, - mDataTypeIconId == TelephonyIcons.ROAMING_ICON, isTypeIconWide(mDataTypeIconId)); } cluster.setIsAirplaneMode(mAirplaneMode, mAirplaneIconId); @@ -1606,7 +1603,6 @@ public class NetworkControllerImpl extends BroadcastReceiver mDemoDataTypeIconId, "Demo", "Demo", - mDemoDataTypeIconId == TelephonyIcons.ROAMING_ICON, isTypeIconWide(mDemoDataTypeIconId)); } refreshViews(); 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 eb808c2c3cb7..5c7909a25147 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -571,6 +571,9 @@ public class UserSwitcherController { cancel(); } else { dismiss(); + if (ActivityManager.isUserAMonkey()) { + return; + } UserInfo user = mUserManager.createSecondaryUser( mContext.getString(R.string.user_new_user_name), 0 /* flags */); if (user == null) { diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java index 0586a83d12ab..0fe6d892a0f3 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java +++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java @@ -1,7 +1,6 @@ package com.android.systemui.volume; import android.content.Context; -import android.content.Intent; import android.content.res.Configuration; import android.database.ContentObserver; import android.media.AudioManager; @@ -11,13 +10,10 @@ import android.media.session.ISessionController; import android.media.session.MediaController; import android.media.session.MediaSessionManager; import android.net.Uri; -import android.os.AsyncTask; import android.os.Handler; import android.os.RemoteException; -import android.os.UserHandle; import android.provider.Settings; import android.util.Log; -import android.view.WindowManagerGlobal; import com.android.systemui.R; import com.android.systemui.SystemUI; @@ -53,6 +49,7 @@ public class VolumeUI extends SystemUI { private final Handler mHandler = new Handler(); + private boolean mEnabled; private AudioManager mAudioManager; private MediaSessionManager mMediaSessionManager; private VolumeController mVolumeController; @@ -63,6 +60,8 @@ public class VolumeUI extends SystemUI { @Override public void start() { + mEnabled = mContext.getResources().getBoolean(R.bool.enable_volume_ui); + if (!mEnabled) return; mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); mMediaSessionManager = (MediaSessionManager) mContext .getSystemService(Context.MEDIA_SESSION_SERVICE); @@ -84,6 +83,7 @@ public class VolumeUI extends SystemUI { @Override public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + pw.print("mEnabled="); pw.println(mEnabled); if (mPanel != null) { mPanel.dump(fd, pw, args); } diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java index ea431aeb2678..69be37789cc4 100644 --- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java +++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java @@ -430,7 +430,8 @@ public class ZenModePanel extends LinearLayout { } tag.condition = condition; tag.rb.setEnabled(enabled); - if (sameConditionId(mSessionExitCondition, tag.condition)) { + if (mSessionExitCondition != null + && sameConditionId(mSessionExitCondition, tag.condition)) { tag.rb.setChecked(true); } tag.rb.setOnCheckedChangeListener(new OnCheckedChangeListener() { @@ -690,7 +691,7 @@ public class ZenModePanel extends LinearLayout { } private SharedPreferences prefs() { - return mContext.getSharedPreferences(ZenModePanel.class.getSimpleName(), 0); + return mContext.getSharedPreferences(mContext.getPackageName(), 0); } private void updateMinuteIndex() { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index 9c81f0a94856..1ed61fd22e97 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -3342,9 +3342,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { final boolean noActionBar = !hasFeature(FEATURE_ACTION_BAR) || hasFeature(FEATURE_NO_TITLE); if (targetPreHoneycomb || (targetPreIcs && targetHcNeedsOptions && noActionBar)) { - addFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY); + setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE); } else { - clearFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY); + setNeedsMenuKey(WindowManager.LayoutParams.NEEDS_MENU_SET_FALSE); } // Non-floating windows on high end devices must put up decor beneath the system bars and diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 6b9d95d7ee17..558cf56f14d6 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -503,6 +503,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { // What we do when the user double-taps on home private int mDoubleTapOnHomeBehavior; + // Allowed theater mode wake actions + private boolean mAllowTheaterModeWakeFromKey; + private boolean mAllowTheaterModeWakeFromPowerKey; + private boolean mAllowTheaterModeWakeFromMotion; + private boolean mAllowTheaterModeWakeFromCameraLens; + private boolean mAllowTheaterModeWakeFromLidSwitch; + private boolean mAllowTheaterModeWakeFromWakeGesture; + // Screenshot trigger states // Time to volume and power must be pressed within this interval of each other. private static final long SCREENSHOT_CHORD_DEBOUNCE_DELAY_MILLIS = 150; @@ -656,7 +664,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { synchronized (mLock) { if (shouldEnableWakeGestureLp()) { performHapticFeedbackLw(null, HapticFeedbackConstants.VIRTUAL_KEY, false); - mPowerManager.wakeUp(SystemClock.uptimeMillis()); + wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromWakeGesture); } } } @@ -1022,6 +1030,21 @@ public class PhoneWindowManager implements WindowManagerPolicy { com.android.internal.R.bool.config_lidControlsSleep); mTranslucentDecorEnabled = mContext.getResources().getBoolean( com.android.internal.R.bool.config_enableTranslucentDecor); + + mAllowTheaterModeWakeFromKey = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_allowTheaterModeWakeFromKey); + mAllowTheaterModeWakeFromPowerKey = mAllowTheaterModeWakeFromKey + || mContext.getResources().getBoolean( + com.android.internal.R.bool.config_allowTheaterModeWakeFromPowerKey); + mAllowTheaterModeWakeFromMotion = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_allowTheaterModeWakeFromMotion); + mAllowTheaterModeWakeFromCameraLens = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_allowTheaterModeWakeFromCameraLens); + mAllowTheaterModeWakeFromLidSwitch = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_allowTheaterModeWakeFromLidSwitch); + mAllowTheaterModeWakeFromWakeGesture = mContext.getResources().getBoolean( + com.android.internal.R.bool.config_allowTheaterModeWakeFromGesture); + readConfigurationDependentBehaviors(); mAccessibilityManager = (AccessibilityManager) context.getSystemService( @@ -1408,6 +1431,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { case TYPE_WALLPAPER: case TYPE_PRIVATE_PRESENTATION: case TYPE_VOICE_INTERACTION: + case TYPE_ACCESSIBILITY_OVERLAY: // The window manager will check these. break; case TYPE_PHONE: @@ -1637,15 +1661,18 @@ public class PhoneWindowManager implements WindowManagerPolicy { // the drag layer: input for drag-and-drop is associated with this window, // which sits above all other focusable windows return 25; - case TYPE_SECURE_SYSTEM_OVERLAY: + case TYPE_ACCESSIBILITY_OVERLAY: + // overlay put by accessibility services to intercept user interaction return 26; - case TYPE_BOOT_PROGRESS: + case TYPE_SECURE_SYSTEM_OVERLAY: return 27; + case TYPE_BOOT_PROGRESS: + return 28; case TYPE_POINTER: // the (mouse) pointer layer - return 28; - case TYPE_HIDDEN_NAV_CONSUMER: return 29; + case TYPE_HIDDEN_NAV_CONSUMER: + return 30; } Log.e(TAG, "Unknown window type: " + type); return 2; @@ -1949,7 +1976,6 @@ public class PhoneWindowManager implements WindowManagerPolicy { } mKeyguardScrim = win; break; - } return WindowManagerGlobal.ADD_OKAY; } @@ -3181,10 +3207,15 @@ public class PhoneWindowManager implements WindowManagerPolicy { // whether it is taking care of insetting its content. If not, // we need to use the parent's content frame so that the entire // window is positioned within that content. Otherwise we can use - // the display frame and let the attached window take care of + // the overscan frame and let the attached window take care of // positioning its content appropriately. if (adjust != SOFT_INPUT_ADJUST_RESIZE) { - cf.set(attached.getOverscanFrameLw()); + // Set the content frame of the attached window to the parent's decor frame + // (same as content frame when IME isn't present) if specifically requested by + // setting {@link WindowManager.LayoutParams#FLAG_LAYOUT_ATTACHED_IN_DECOR} flag. + // Otherwise, use the overscan frame. + cf.set((fl & FLAG_LAYOUT_ATTACHED_IN_DECOR) != 0 + ? attached.getContentFrameLw() : attached.getOverscanFrameLw()); } else { // If the window is resizing, then we want to base the content // frame on our attached content frame to resize... however, @@ -4060,7 +4091,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { updateRotation(true); if (lidOpen) { - mPowerManager.wakeUp(SystemClock.uptimeMillis()); + wakeUp(SystemClock.uptimeMillis(), mAllowTheaterModeWakeFromLidSwitch); } else if (!mLidControlsSleep) { mPowerManager.userActivity(SystemClock.uptimeMillis(), false); } @@ -4082,7 +4113,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { } else { intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA); } - mPowerManager.wakeUp(whenNanos / 1000000); + wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromCameraLens); mContext.startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF); } mCameraLensCoverState = lensCoverState; @@ -4260,7 +4291,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { // key processing. if (mGlobalKeyManager.shouldHandleGlobalKey(keyCode, event)) { if (isWakeKey) { - mPowerManager.wakeUp(event.getEventTime()); + wakeUp(event.getEventTime(), keyCode == KeyEvent.KEYCODE_POWER + ? mAllowTheaterModeWakeFromPowerKey : mAllowTheaterModeWakeFromKey); } return result; } @@ -4509,8 +4541,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { } if (isWakeKey) { - mPowerManager.wakeUp(event.getEventTime()); + wakeUp(event.getEventTime(), keyCode == KeyEvent.KEYCODE_POWER + ? mAllowTheaterModeWakeFromPowerKey : mAllowTheaterModeWakeFromKey); } + return result; } @@ -4553,7 +4587,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { @Override public int interceptMotionBeforeQueueingNonInteractive(long whenNanos, int policyFlags) { if ((policyFlags & FLAG_WAKE) != 0) { - mPowerManager.wakeUp(whenNanos / 1000000); + wakeUp(whenNanos / 1000000, mAllowTheaterModeWakeFromMotion); return 0; } if (shouldDispatchInputWhenNonInteractive()) { @@ -4731,6 +4765,14 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + private void wakeUp(long wakeTime, boolean wakeInTheaterMode) { + if (!wakeInTheaterMode && isTheaterModeEnabled()) { + return; + } + + mPowerManager.wakeUp(wakeTime); + } + // Called on the PowerManager's Notifier thread. @Override public void wakingUp() { @@ -5609,6 +5651,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { ringTone.play(); } + private boolean isTheaterModeEnabled() { + return Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.THEATER_MODE_ON, 0) == 1; + } + private boolean isGlobalAccessibilityGestureEnabled() { return Settings.Global.getInt(mContext.getContentResolver(), Settings.Global.ENABLE_ACCESSIBILITY_GLOBAL_GESTURE_ENABLED, 0) == 1; diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index e1a74d1432d4..278189008362 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -1040,7 +1040,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private void addServiceLocked(Service service, UserState userState) { try { - service.linkToOwnDeathLocked(); + service.onAdded(); userState.mBoundServices.add(service); userState.mComponentNameToServiceMap.put(service.mComponentName, service); } catch (RemoteException re) { @@ -1056,7 +1056,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private void removeServiceLocked(Service service, UserState userState) { userState.mBoundServices.remove(service); userState.mComponentNameToServiceMap.remove(service.mComponentName); - service.unlinkToOwnDeathLocked(); + service.onRemoved(); } /** @@ -1931,6 +1931,8 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { final ResolveInfo mResolveInfo; + final IBinder mOverlayWindowToken = new Binder(); + // the events pending events to be dispatched to this service final SparseArray<AccessibilityEvent> mPendingEvents = new SparseArray<>(); @@ -2112,7 +2114,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { userState.mBindingServices.remove(mComponentName); mWasConnectedAndDied = false; try { - mServiceInterface.setConnection(this, mId); + mServiceInterface.init(this, mId, mOverlayWindowToken); onUserStateChangedLocked(userState); } catch (RemoteException re) { Slog.w(LOG_TAG, "Error while setting connection for service: " @@ -2602,6 +2604,27 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { /* do nothing - #binderDied takes care */ } + public void onAdded() throws RemoteException { + linkToOwnDeathLocked(); + final long identity = Binder.clearCallingIdentity(); + try { + mWindowManagerService.addWindowToken(mOverlayWindowToken, + WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + public void onRemoved() { + final long identity = Binder.clearCallingIdentity(); + try { + mWindowManagerService.removeWindowToken(mOverlayWindowToken, true); + } finally { + Binder.restoreCallingIdentity(identity); + } + unlinkToOwnDeathLocked(); + } + public void linkToOwnDeathLocked() throws RemoteException { mService.linkToDeath(this, 0); } @@ -2614,7 +2637,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { try { // Clear the proxy in the other process so this // IAccessibilityServiceConnection can be garbage collected. - mServiceInterface.setConnection(null, mId); + mServiceInterface.init(null, mId, null); } catch (RemoteException re) { /* ignore */ } @@ -3164,6 +3187,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { return AccessibilityWindowInfo.TYPE_SYSTEM; } + case WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY: { + return AccessibilityWindowInfo.TYPE_ACCESSIBILITY_OVERLAY; + } + default: { return -1; } diff --git a/services/core/java/com/android/server/DockObserver.java b/services/core/java/com/android/server/DockObserver.java index d05c280093fb..41ce25d38078 100644 --- a/services/core/java/com/android/server/DockObserver.java +++ b/services/core/java/com/android/server/DockObserver.java @@ -65,11 +65,15 @@ final class DockObserver extends SystemService { private boolean mUpdatesStopped; + private final boolean mAllowTheaterModeWakeFromDock; + public DockObserver(Context context) { super(context); mPowerManager = (PowerManager)context.getSystemService(Context.POWER_SERVICE); mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); + mAllowTheaterModeWakeFromDock = context.getResources().getBoolean( + com.android.internal.R.bool.config_allowTheaterModeWakeFromDock); init(); // set initial status @@ -126,8 +130,12 @@ final class DockObserver extends SystemService { if (newState != mReportedDockState) { mReportedDockState = newState; if (mSystemReady) { - // Wake up immediately when docked or undocked. - mPowerManager.wakeUp(SystemClock.uptimeMillis()); + // Wake up immediately when docked or undocked except in theater mode. + if (mAllowTheaterModeWakeFromDock + || Settings.Global.getInt(getContext().getContentResolver(), + Settings.Global.THEATER_MODE_ON, 0) == 0) { + mPowerManager.wakeUp(SystemClock.uptimeMillis()); + } updateLocked(); } } diff --git a/services/core/java/com/android/server/EventLogTags.logtags b/services/core/java/com/android/server/EventLogTags.logtags index 64d8f6fd09f5..eec97f3f7686 100644 --- a/services/core/java/com/android/server/EventLogTags.logtags +++ b/services/core/java/com/android/server/EventLogTags.logtags @@ -69,6 +69,10 @@ option java_package com.android.server 27511 notification_expansion (key|3),(user_action|1),(expanded|1) # when a notification has been clicked 27520 notification_clicked (key|3) +# when a notification action button has been clicked +27521 notification_action_clicked (key|3),(action_index|1) +# when a notification has been canceled +27530 notification_canceled (key|3),(reason|1) # --------------------------- # Watchdog.java diff --git a/services/core/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java index 07cc8647b62b..387eabc85d6b 100644 --- a/services/core/java/com/android/server/IntentResolver.java +++ b/services/core/java/com/android/server/IntentResolver.java @@ -21,7 +21,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -30,6 +29,7 @@ import java.util.Set; import android.net.Uri; import android.util.FastImmutableArraySet; import android.util.ArrayMap; +import android.util.ArraySet; import android.util.Log; import android.util.PrintWriterPrinter; import android.util.Slog; @@ -736,7 +736,7 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> { /** * All filters that have been registered. */ - private final HashSet<F> mFilters = new HashSet<F>(); + private final ArraySet<F> mFilters = new ArraySet<F>(); /** * All of the MIME types that have been registered, such as "image/jpeg", diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index 28a6917cb0c7..d9c96e4a2537 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -1796,9 +1796,6 @@ public class LocationManagerService extends ILocationManager.Stub { @Override public boolean addGpsStatusListener(IGpsStatusListener listener, String packageName) { - if (mGpsStatusProvider == null) { - return false; - } int allowedResolutionLevel = getCallerAllowedResolutionLevel(); checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, LocationManager.GPS_PROVIDER); @@ -1813,6 +1810,10 @@ public class LocationManagerService extends ILocationManager.Stub { Binder.restoreCallingIdentity(ident); } + if (mGpsStatusProvider == null) { + return false; + } + try { mGpsStatusProvider.addGpsStatusListener(listener); } catch (RemoteException e) { diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java index 926235f9f2de..9596b57a5e15 100644 --- a/services/core/java/com/android/server/MmsServiceBroker.java +++ b/services/core/java/com/android/server/MmsServiceBroker.java @@ -219,7 +219,7 @@ public class MmsServiceBroker extends SystemService { // Service API calls implementation, proxied to the real MmsService in "com.android.mms.service" private final class BinderService extends IMms.Stub { @Override - public void sendMessage(long subId, String callingPkg, Uri contentUri, + public void sendMessage(int subId, String callingPkg, Uri contentUri, String locationUrl, Bundle configOverrides, PendingIntent sentIntent) throws RemoteException { mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Send MMS message"); @@ -232,7 +232,7 @@ public class MmsServiceBroker extends SystemService { } @Override - public void downloadMessage(long subId, String callingPkg, String locationUrl, + public void downloadMessage(int subId, String callingPkg, String locationUrl, Uri contentUri, Bundle configOverrides, PendingIntent downloadedIntent) throws RemoteException { mContext.enforceCallingPermission(Manifest.permission.RECEIVE_MMS, @@ -259,7 +259,7 @@ public class MmsServiceBroker extends SystemService { } @Override - public Bundle getCarrierConfigValues(long subId) throws RemoteException { + public Bundle getCarrierConfigValues(int subId) throws RemoteException { return getServiceGuarded().getCarrierConfigValues(subId); } @@ -360,7 +360,7 @@ public class MmsServiceBroker extends SystemService { } @Override - public void sendStoredMessage(long subId, String callingPkg, Uri messageUri, + public void sendStoredMessage(int subId, String callingPkg, Uri messageUri, Bundle configOverrides, PendingIntent sentIntent) throws RemoteException { mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Send stored MMS message"); diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index 24d81a0e6700..e400fb67c0c7 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -826,7 +826,9 @@ class MountService extends IMountService.Stub // On an encrypted device we can't see system properties yet, so pull // the system locale out of the mount service. - copyLocaleFromMountService(); + if ("".equals(SystemProperties.get("vold.encrypt_progress"))) { + copyLocaleFromMountService(); + } // Let package manager load internal ASECs. mPms.scanAvailableAsecs(); diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java index cf2a49f922e2..f4fb5199e730 100644 --- a/services/core/java/com/android/server/SystemConfig.java +++ b/services/core/java/com/android/server/SystemConfig.java @@ -32,8 +32,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; -import java.util.HashMap; -import java.util.HashSet; import static com.android.internal.util.ArrayUtils.appendInt; @@ -50,7 +48,7 @@ public class SystemConfig { // These are the built-in uid -> permission mappings that were read from the // system configuration files. - final SparseArray<HashSet<String>> mSystemPermissions = new SparseArray<>(); + final SparseArray<ArraySet<String>> mSystemPermissions = new SparseArray<>(); // These are the built-in shared libraries that were read from the // system configuration files. Keys are the library names; strings are the @@ -59,7 +57,7 @@ public class SystemConfig { // These are the features this devices supports that were read from the // system configuration files. - final HashMap<String, FeatureInfo> mAvailableFeatures = new HashMap<>(); + final ArrayMap<String, FeatureInfo> mAvailableFeatures = new ArrayMap<>(); public static final class PermissionEntry { public final String name; @@ -94,7 +92,7 @@ public class SystemConfig { return mGlobalGids; } - public SparseArray<HashSet<String>> getSystemPermissions() { + public SparseArray<ArraySet<String>> getSystemPermissions() { return mSystemPermissions; } @@ -102,7 +100,7 @@ public class SystemConfig { return mSharedLibraries; } - public HashMap<String, FeatureInfo> getAvailableFeatures() { + public ArrayMap<String, FeatureInfo> getAvailableFeatures() { return mAvailableFeatures; } @@ -252,9 +250,9 @@ public class SystemConfig { continue; } perm = perm.intern(); - HashSet<String> perms = mSystemPermissions.get(uid); + ArraySet<String> perms = mSystemPermissions.get(uid); if (perms == null) { - perms = new HashSet<String>(); + perms = new ArraySet<String>(); mSystemPermissions.put(uid, perms); } perms.add(perm); diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java index 7b58608ff163..fcc5339e4498 100644 --- a/services/core/java/com/android/server/TelephonyRegistry.java +++ b/services/core/java/com/android/server/TelephonyRegistry.java @@ -72,7 +72,7 @@ import com.android.server.am.BatteryStatsService; * and 15973975 by saving the phoneId of the registrant and then using the * phoneId when deciding to to make a callback. This is necessary because * a subId changes from to a dummy value when a SIM is removed and thus won't - * compare properly. Because SubscriptionManager.getPhoneId(long subId) handles + * compare properly. Because SubscriptionManager.getPhoneId(int subId) handles * the dummy value conversion we properly do the callbacks. * * Eventually we may want to remove the notion of dummy value but for now this @@ -95,7 +95,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { int events; - long subId; + int subId; int phoneId; @@ -154,7 +154,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private VoLteServiceState mVoLteServiceState = new VoLteServiceState(); - private long mDefaultSubId = SubscriptionManager.INVALID_SUB_ID; + private int mDefaultSubId = SubscriptionManager.INVALID_SUB_ID; private int mDefaultPhoneId = SubscriptionManager.INVALID_PHONE_ID; @@ -201,7 +201,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } case MSG_UPDATE_DEFAULT_SUB: { int newDefaultPhoneId = msg.arg1; - long newDefaultSubId = (Long)(msg.obj); + int newDefaultSubId = (Integer)(msg.obj); if (VDBG) { log("MSG_UPDATE_DEFAULT_SUB:current mDefaultSubId=" + mDefaultSubId + " current mDefaultPhoneId=" + mDefaultPhoneId + " newDefaultSubId= " @@ -236,7 +236,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { if (DBG) log("onReceive: userHandle=" + userHandle); mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHED, userHandle, 0)); } else if (action.equals(TelephonyIntents.ACTION_DEFAULT_SUBSCRIPTION_CHANGED)) { - Long newDefaultSubIdObj = new Long(intent.getLongExtra( + Integer newDefaultSubIdObj = new Integer(intent.getIntExtra( PhoneConstants.SUBSCRIPTION_KEY, SubscriptionManager.getDefaultSubId())); int newDefaultPhoneId = intent.getIntExtra(PhoneConstants.SLOT_KEY, SubscriptionManager.getPhoneId(mDefaultSubId)); @@ -332,13 +332,13 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override - public void listenForSubscriber(long subId, String pkgForDebug, IPhoneStateListener callback, + public void listenForSubscriber(int subId, String pkgForDebug, IPhoneStateListener callback, int events, boolean notifyNow) { listen(pkgForDebug, callback, events, notifyNow, subId); } private void listen(String pkgForDebug, IPhoneStateListener callback, int events, - boolean notifyNow, long subId) { + boolean notifyNow, int subId) { int callerUid = UserHandle.getCallingUserId(); int myUid = UserHandle.myUserId(); if (VDBG) { @@ -545,7 +545,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { broadcastCallStateChanged(state, incomingNumber, SubscriptionManager.DEFAULT_SUB_ID); } - public void notifyCallStateForSubscriber(long subId, int state, String incomingNumber) { + public void notifyCallStateForSubscriber(int subId, int state, String incomingNumber) { if (!checkNotifyPermission("notifyCallState()")) { return; } @@ -575,7 +575,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { broadcastCallStateChanged(state, incomingNumber, subId); } - public void notifyServiceStateForPhoneId(int phoneId, long subId, ServiceState state) { + public void notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state) { if (!checkNotifyPermission("notifyServiceState()")){ return; } @@ -621,7 +621,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { notifySignalStrengthForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, signalStrength); } - public void notifySignalStrengthForSubscriber(long subId, SignalStrength signalStrength) { + public void notifySignalStrengthForSubscriber(int subId, SignalStrength signalStrength) { if (!checkNotifyPermission("notifySignalStrength()")) { return; } @@ -681,7 +681,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { notifyCellInfoForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cellInfo); } - public void notifyCellInfoForSubscriber(long subId, List<CellInfo> cellInfo) { + public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) { if (!checkNotifyPermission("notifyCellInfo()")) { return; } @@ -738,7 +738,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } @Override - public void notifyMessageWaitingChangedForPhoneId(int phoneId, long subId, boolean mwi) { + public void notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi) { if (!checkNotifyPermission("notifyMessageWaitingChanged()")) { return; } @@ -768,7 +768,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { notifyCallForwardingChangedForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cfi); } - public void notifyCallForwardingChangedForSubscriber(long subId, boolean cfi) { + public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) { if (!checkNotifyPermission("notifyCallForwardingChanged()")) { return; } @@ -799,7 +799,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { notifyDataActivityForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, state); } - public void notifyDataActivityForSubscriber(long subId, int state) { + public void notifyDataActivityForSubscriber(int subId, int state) { if (!checkNotifyPermission("notifyDataActivity()" )) { return; } @@ -827,7 +827,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { networkCapabilities, networkType, roaming); } - public void notifyDataConnectionForSubscriber(long subId, int state, + public void notifyDataConnectionForSubscriber(int subId, int state, boolean isDataConnectivityPossible, String reason, String apn, String apnType, LinkProperties linkProperties, NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { @@ -916,7 +916,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { reason, apnType); } - public void notifyDataConnectionFailedForSubscriber(long subId, + public void notifyDataConnectionFailedForSubscriber(int subId, String reason, String apnType) { if (!checkNotifyPermission("notifyDataConnectionFailed()")) { return; @@ -949,7 +949,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUB_ID, cellLocation); } - public void notifyCellLocationForSubscriber(long subId, Bundle cellLocation) { + public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) { log("notifyCellLocationForSubscriber: subId=" + subId + " cellLocation=" + cellLocation); if (!checkNotifyPermission("notifyCellLocation()")) { @@ -1096,7 +1096,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - public void notifyOemHookRawEventForSubscriber(long subId, byte[] rawData) { + public void notifyOemHookRawEventForSubscriber(int subId, byte[] rawData) { if (!checkNotifyPermission("notifyOemHookRawEventForSubscriber")) { return; } @@ -1162,7 +1162,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { // the legacy intent broadcasting // - private void broadcastServiceStateChanged(ServiceState state, long subId) { + private void broadcastServiceStateChanged(ServiceState state, int subId) { long ident = Binder.clearCallingIdentity(); try { mBatteryStats.notePhoneState(state.getState()); @@ -1181,7 +1181,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); } - private void broadcastSignalStrengthChanged(SignalStrength signalStrength, long subId) { + private void broadcastSignalStrengthChanged(SignalStrength signalStrength, int subId) { long ident = Binder.clearCallingIdentity(); try { mBatteryStats.notePhoneSignalStrength(signalStrength); @@ -1200,7 +1200,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { mContext.sendStickyBroadcastAsUser(intent, UserHandle.ALL); } - private void broadcastCallStateChanged(int state, String incomingNumber, long subId) { + private void broadcastCallStateChanged(int state, String incomingNumber, int subId) { long ident = Binder.clearCallingIdentity(); try { if (state == TelephonyManager.CALL_STATE_IDLE) { @@ -1228,7 +1228,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private void broadcastDataConnectionStateChanged(int state, boolean isDataConnectivityPossible, String reason, String apn, String apnType, LinkProperties linkProperties, - NetworkCapabilities networkCapabilities, boolean roaming, long subId) { + NetworkCapabilities networkCapabilities, boolean roaming, int subId) { // Note: not reporting to the battery stats service here, because the // status bar takes care of that after taking into account all of the // required info. @@ -1260,7 +1260,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } private void broadcastDataConnectionFailed(String reason, String apnType, - long subId) { + int subId) { Intent intent = new Intent(TelephonyIntents.ACTION_DATA_CONNECTION_FAILED); intent.putExtra(PhoneConstants.FAILURE_REASON_KEY, reason); intent.putExtra(PhoneConstants.DATA_APN_TYPE_KEY, apnType); @@ -1376,11 +1376,11 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private static class LogSSC { private Time mTime; private String mS; - private long mSubId; + private int mSubId; private int mPhoneId; private ServiceState mState; - public void set(Time t, String s, long subId, int phoneId, ServiceState state) { + public void set(Time t, String s, int subId, int phoneId, ServiceState state) { mTime = t; mS = s; mSubId = subId; mPhoneId = phoneId; mState = state; } @@ -1393,7 +1393,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { private LogSSC logSSC [] = new LogSSC[10]; private int next = 0; - private void logServiceStateChanged(String s, long subId, int phoneId, ServiceState state) { + private void logServiceStateChanged(String s, int subId, int phoneId, ServiceState state) { if (logSSC == null || logSSC.length == 0) { return; } @@ -1429,7 +1429,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub { } } - boolean subIdMatch(long rSubId, long subId) { + boolean subIdMatch(int rSubId, int subId) { if(rSubId == SubscriptionManager.DEFAULT_SUB_ID) { return (subId == mDefaultSubId); } else { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 970d275ac15a..9f1ce0b44501 100755 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -8852,7 +8852,8 @@ public final class ActivityManagerService extends ActivityManagerNative task = mStackSupervisor.anyTaskForIdLocked(task.taskId); if (task != null) { if (!isSystemInitiated - && ((mFocusedActivity == null) || (task != mFocusedActivity.task))) { + && ((mStackSupervisor.getFocusedStack() == null) + || (task != mStackSupervisor.getFocusedStack().topTask()))) { throw new IllegalArgumentException("Invalid task, not in foreground"); } mStackSupervisor.setLockTaskModeLocked(task, !isSystemInitiated); diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 03dd3c0c7e49..c1bf9556d5f7 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -120,7 +120,7 @@ public final class ActivityStackSupervisor implements DisplayListener { static final boolean DEBUG_RELEASE = DEBUG || false; static final boolean DEBUG_SAVED_STATE = DEBUG || false; static final boolean DEBUG_SCREENSHOTS = DEBUG || false; - static final boolean DEBUG_STATES = DEBUG || false; + static final boolean DEBUG_STATES = DEBUG || true; static final boolean DEBUG_VISIBLE_BEHIND = DEBUG || false; public static final int HOME_STACK_ID = 0; diff --git a/services/core/java/com/android/server/am/LockTaskNotify.java b/services/core/java/com/android/server/am/LockTaskNotify.java index 5768ddbe8380..b3777ed30c21 100644 --- a/services/core/java/com/android/server/am/LockTaskNotify.java +++ b/services/core/java/com/android/server/am/LockTaskNotify.java @@ -19,6 +19,7 @@ package com.android.server.am; import android.content.Context; import android.os.Handler; import android.os.Message; +import android.view.WindowManager; import android.view.accessibility.AccessibilityManager; import android.widget.Toast; @@ -56,8 +57,7 @@ public class LockTaskNotify { if (mLastToast != null) { mLastToast.cancel(); } - mLastToast = Toast.makeText(mContext, text, Toast.LENGTH_LONG); - mLastToast.show(); + mLastToast = makeAllUserToastAndShow(text); } public void show(boolean starting) { @@ -65,7 +65,15 @@ public class LockTaskNotify { if (starting) { showString = R.string.lock_to_app_start; } - Toast.makeText(mContext, mContext.getString(showString), Toast.LENGTH_LONG).show(); + makeAllUserToastAndShow(mContext.getString(showString)); + } + + private Toast makeAllUserToastAndShow(String text) { + Toast toast = Toast.makeText(mContext, text, Toast.LENGTH_LONG); + toast.getWindowParams().privateFlags |= + WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS; + toast.show(); + return toast; } private final class H extends Handler { diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java index afc781fd32ee..b331c845a0e3 100644 --- a/services/core/java/com/android/server/am/TaskPersister.java +++ b/services/core/java/com/android/server/am/TaskPersister.java @@ -166,7 +166,7 @@ public class TaskPersister { break; } } - if (queueNdx < 0) { + if (queueNdx < 0 && task.isPersistable) { mWriteQueue.add(new TaskWriteQueueItem(task)); } } else { @@ -473,13 +473,15 @@ public class TaskPersister { if (DEBUG) Slog.d(TAG, "mRecents=" + tasks); for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord task = tasks.get(taskNdx); - if (DEBUG) Slog.d(TAG, "LazyTaskWriter: task=" + task + " persistable=" + - task.isPersistable); - if (task.isPersistable && !task.stack.isHomeStack()) { + if (DEBUG) Slog.d(TAG, "LazyTaskWriter: task=" + task + + " persistable=" + task.isPersistable); + if ((task.isPersistable || task.inRecents) + && !task.stack.isHomeStack()) { if (DEBUG) Slog.d(TAG, "adding to persistentTaskIds task=" + task); persistentTaskIds.add(task.taskId); } else { - if (DEBUG) Slog.d(TAG, "omitting from persistentTaskIds task=" + task); + if (DEBUG) Slog.d(TAG, + "omitting from persistentTaskIds task=" + task); } } } diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 4dfd23b74bb8..ee932331f38a 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -144,7 +144,7 @@ final class TaskRecord { boolean mReuseTask = false; private Bitmap mLastThumbnail; // Last thumbnail captured for this item. - private final File mLastThumbnailFile; // File containing last thubmnail. + private final File mLastThumbnailFile; // File containing last thumbnail. private final String mFilename; CharSequence lastDescription; // Last description captured for this item. diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 953bef288133..e741fc4f8dc1 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -2087,7 +2087,7 @@ public final class HdmiControlService extends SystemService { assertRunOnServiceThread(); Intent intent = new Intent(HdmiControlManager.ACTION_OSD_MESSAGE); intent.putExtra(HdmiControlManager.EXTRA_MESSAGE_ID, messageId); - intent.putExtra(HdmiControlManager.EXTRA_MESSAGE_EXTRAM_PARAM1, extra); + intent.putExtra(HdmiControlManager.EXTRA_MESSAGE_EXTRA_PARAM1, extra); getContext().sendBroadcastAsUser(intent, UserHandle.ALL, HdmiControlService.PERMISSION); } diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java index c6d2db2ccf6e..83d6986a410f 100644 --- a/services/core/java/com/android/server/job/JobSchedulerService.java +++ b/services/core/java/com/android/server/job/JobSchedulerService.java @@ -137,11 +137,15 @@ public class JobSchedulerService extends com.android.server.SystemService public void onReceive(Context context, Intent intent) { Slog.d(TAG, "Receieved: " + intent.getAction()); if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) { - int uidRemoved = intent.getIntExtra(Intent.EXTRA_UID, -1); - if (DEBUG) { - Slog.d(TAG, "Removing jobs for uid: " + uidRemoved); + // If this is an outright uninstall rather than the first half of an + // app update sequence, cancel the jobs associated with the app. + if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { + int uidRemoved = intent.getIntExtra(Intent.EXTRA_UID, -1); + if (DEBUG) { + Slog.d(TAG, "Removing jobs for uid: " + uidRemoved); + } + cancelJobsForUid(uidRemoved); } - cancelJobsForUid(uidRemoved); } else if (Intent.ACTION_USER_REMOVED.equals(intent.getAction())) { final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0); if (DEBUG) { diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java index b5aa4d83fd0e..150ad34669da 100644 --- a/services/core/java/com/android/server/net/NetworkStatsService.java +++ b/services/core/java/com/android/server/net/NetworkStatsService.java @@ -45,7 +45,6 @@ import static android.provider.Settings.Global.NETSTATS_DEV_PERSIST_BYTES; import static android.provider.Settings.Global.NETSTATS_DEV_ROTATE_AGE; import static android.provider.Settings.Global.NETSTATS_GLOBAL_ALERT_BYTES; import static android.provider.Settings.Global.NETSTATS_POLL_INTERVAL; -import static android.provider.Settings.Global.NETSTATS_REPORT_XT_OVER_DEV; import static android.provider.Settings.Global.NETSTATS_SAMPLE_ENABLED; import static android.provider.Settings.Global.NETSTATS_TIME_CACHE_MAX_AGE; import static android.provider.Settings.Global.NETSTATS_UID_BUCKET_DURATION; @@ -184,7 +183,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { public long getPollInterval(); public long getTimeCacheMaxAge(); public boolean getSampleEnabled(); - public boolean getReportXtOverDev(); public static class Config { public final long bucketDuration; @@ -229,8 +227,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { private NetworkStatsRecorder mUidRecorder; private NetworkStatsRecorder mUidTagRecorder; - /** Cached {@link #mDevRecorder} stats. */ - private NetworkStatsCollection mDevStatsCached; /** Cached {@link #mXtRecorder} stats. */ private NetworkStatsCollection mXtStatsCached; @@ -305,7 +301,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // read historical network stats from disk, since policy service // might need them right away. - mDevStatsCached = mDevRecorder.getOrLoadCompleteLocked(); mXtStatsCached = mXtRecorder.getOrLoadCompleteLocked(); // bootstrap initial stats to prevent double-counting later @@ -386,7 +381,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { mUidRecorder = null; mUidTagRecorder = null; - mDevStatsCached = null; mXtStatsCached = null; mSystemReady = false; @@ -523,48 +517,24 @@ public class NetworkStatsService extends INetworkStatsService.Stub { } /** - * Return network summary, splicing between {@link #mDevStatsCached} - * and {@link #mXtStatsCached} when appropriate. + * Return network summary, splicing between DEV and XT stats when + * appropriate. */ private NetworkStats internalGetSummaryForNetwork( NetworkTemplate template, long start, long end) { - if (!mSettings.getReportXtOverDev()) { - // shortcut when XT reporting disabled - return mDevStatsCached.getSummary(template, start, end); - } - - // splice stats between DEV and XT, switching over from DEV to XT at - // first atomic bucket. - final long firstAtomicBucket = mXtStatsCached.getFirstAtomicBucketMillis(); - final NetworkStats dev = mDevStatsCached.getSummary( - template, Math.min(start, firstAtomicBucket), Math.min(end, firstAtomicBucket)); - final NetworkStats xt = mXtStatsCached.getSummary( - template, Math.max(start, firstAtomicBucket), Math.max(end, firstAtomicBucket)); - - xt.combineAllValues(dev); - return xt; + // We've been using pure XT stats long enough that we no longer need to + // splice DEV and XT together. + return mXtStatsCached.getSummary(template, start, end); } /** - * Return network history, splicing between {@link #mDevStatsCached} - * and {@link #mXtStatsCached} when appropriate. + * Return network history, splicing between DEV and XT stats when + * appropriate. */ private NetworkStatsHistory internalGetHistoryForNetwork(NetworkTemplate template, int fields) { - if (!mSettings.getReportXtOverDev()) { - // shortcut when XT reporting disabled - return mDevStatsCached.getHistory(template, UID_ALL, SET_ALL, TAG_NONE, fields); - } - - // splice stats between DEV and XT, switching over from DEV to XT at - // first atomic bucket. - final long firstAtomicBucket = mXtStatsCached.getFirstAtomicBucketMillis(); - final NetworkStatsHistory dev = mDevStatsCached.getHistory( - template, UID_ALL, SET_ALL, TAG_NONE, fields, Long.MIN_VALUE, firstAtomicBucket); - final NetworkStatsHistory xt = mXtStatsCached.getHistory( - template, UID_ALL, SET_ALL, TAG_NONE, fields, firstAtomicBucket, Long.MAX_VALUE); - - xt.recordEntireHistory(dev); - return xt; + // We've been using pure XT stats long enough that we no longer need to + // splice DEV and XT together. + return mXtStatsCached.getHistory(template, UID_ALL, SET_ALL, TAG_NONE, fields); } @Override @@ -1329,10 +1299,6 @@ public class NetworkStatsService extends INetworkStatsService.Stub { return getGlobalBoolean(NETSTATS_SAMPLE_ENABLED, true); } @Override - public boolean getReportXtOverDev() { - return getGlobalBoolean(NETSTATS_REPORT_XT_OVER_DEV, true); - } - @Override public Config getDevConfig() { return new Config(getGlobalLong(NETSTATS_DEV_BUCKET_DURATION, HOUR_IN_MILLIS), getGlobalLong(NETSTATS_DEV_ROTATE_AGE, 15 * DAY_IN_MILLIS), diff --git a/services/core/java/com/android/server/notification/NotificationDelegate.java b/services/core/java/com/android/server/notification/NotificationDelegate.java index 97f0a1ec263d..24fc45508bc1 100644 --- a/services/core/java/com/android/server/notification/NotificationDelegate.java +++ b/services/core/java/com/android/server/notification/NotificationDelegate.java @@ -20,6 +20,7 @@ public interface NotificationDelegate { void onSetDisabled(int status); void onClearAll(int callingUid, int callingPid, int userId); void onNotificationClick(int callingUid, int callingPid, String key); + void onNotificationActionClick(int callingUid, int callingPid, String key, int actionIndex); void onNotificationClear(int callingUid, int callingPid, String pkg, String tag, int id, int userId); void onNotificationError(int callingUid, int callingPid, diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 22f060f9c8e2..090967f74e29 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -541,6 +541,20 @@ public class NotificationManagerService extends SystemService { } @Override + public void onNotificationActionClick(int callingUid, int callingPid, String key, + int actionIndex) { + synchronized (mNotificationList) { + EventLogTags.writeNotificationActionClicked(key, actionIndex); + NotificationRecord r = mNotificationsByKey.get(key); + if (r == null) { + Log.w(TAG, "No notification with key: " + key); + return; + } + // TODO: Log action click via UsageStats. + } + } + + @Override public void onNotificationClear(int callingUid, int callingPid, String pkg, String tag, int id, int userId) { cancelNotification(callingUid, callingPid, pkg, tag, id, 0, @@ -2358,6 +2372,8 @@ public class NotificationManagerService extends SystemService { // Save it for users of getHistoricalNotifications() mArchive.record(r.sbn); + + EventLogTags.writeNotificationCanceled(r.getKey(), reason); } /** diff --git a/services/core/java/com/android/server/pm/BackgroundDexOptService.java b/services/core/java/com/android/server/pm/BackgroundDexOptService.java index a7eebf832f09..cb9a45e41768 100644 --- a/services/core/java/com/android/server/pm/BackgroundDexOptService.java +++ b/services/core/java/com/android/server/pm/BackgroundDexOptService.java @@ -23,9 +23,9 @@ import android.app.job.JobService; import android.content.ComponentName; import android.content.Context; import android.os.ServiceManager; +import android.util.ArraySet; import android.util.Log; -import java.util.HashSet; import java.util.concurrent.atomic.AtomicBoolean; /** @@ -59,7 +59,7 @@ public class BackgroundDexOptService extends JobService { if (pm.isStorageLow()) { return false; } - final HashSet<String> pkgs = pm.getPackagesThatNeedDexOpt(); + final ArraySet<String> pkgs = pm.getPackagesThatNeedDexOpt(); if (pkgs == null) { return false; } diff --git a/services/core/java/com/android/server/pm/GrantedPermissions.java b/services/core/java/com/android/server/pm/GrantedPermissions.java index 14258a46a564..8f0f93542861 100644 --- a/services/core/java/com/android/server/pm/GrantedPermissions.java +++ b/services/core/java/com/android/server/pm/GrantedPermissions.java @@ -17,13 +17,12 @@ package com.android.server.pm; import android.content.pm.ApplicationInfo; - -import java.util.HashSet; +import android.util.ArraySet; class GrantedPermissions { int pkgFlags; - HashSet<String> grantedPermissions = new HashSet<String>(); + ArraySet<String> grantedPermissions = new ArraySet<String>(); int[] gids; @@ -34,7 +33,7 @@ class GrantedPermissions { @SuppressWarnings("unchecked") GrantedPermissions(GrantedPermissions base) { pkgFlags = base.pkgFlags; - grantedPermissions = (HashSet<String>) base.grantedPermissions.clone(); + grantedPermissions = new ArraySet<>(base.grantedPermissions); if (base.gids != null) { gids = base.gids.clone(); diff --git a/services/core/java/com/android/server/pm/PackageKeySetData.java b/services/core/java/com/android/server/pm/PackageKeySetData.java index 9f9bafd39035..8f12c03b8646 100644 --- a/services/core/java/com/android/server/pm/PackageKeySetData.java +++ b/services/core/java/com/android/server/pm/PackageKeySetData.java @@ -16,10 +16,9 @@ package com.android.server.pm; -import com.android.internal.util.ArrayUtils; +import android.util.ArrayMap; -import java.util.HashMap; -import java.util.Map; +import com.android.internal.util.ArrayUtils; public class PackageKeySetData { @@ -34,7 +33,7 @@ public class PackageKeySetData { private long[] mDefinedKeySets; - private final Map<String, Long> mKeySetAliases = new HashMap<String, Long>(); + private final ArrayMap<String, Long> mKeySetAliases = new ArrayMap<String, Long>(); PackageKeySetData() { mProperSigningKeySet = KEYSET_UNASSIGNED; @@ -132,7 +131,7 @@ public class PackageKeySetData { return mDefinedKeySets; } - protected Map<String, Long> getAliases() { + protected ArrayMap<String, Long> getAliases() { return mKeySetAliases; } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index b79e15756a11..ead159560b38 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -84,6 +84,8 @@ import android.app.AppGlobals; import android.app.IActivityManager; import android.app.admin.IDevicePolicyManager; import android.app.backup.IBackupManager; +import android.app.usage.UsageStats; +import android.app.usage.UsageStatsManager; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -199,8 +201,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Comparator; import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -329,6 +329,7 @@ public class PackageManagerService extends IPackageManager.Stub { final boolean mFactoryTest; final boolean mOnlyCore; final boolean mLazyDexOpt; + final long mDexOptLRUThresholdInMills; final DisplayMetrics mMetrics; final int mDefParseFlags; final String[] mSeparateProcesses; @@ -371,20 +372,20 @@ public class PackageManagerService extends IPackageManager.Stub { // Keys are String (package name), values are Package. This also serves // as the lock for the global state. Methods that must be called with // this lock held have the prefix "LP". - final HashMap<String, PackageParser.Package> mPackages = - new HashMap<String, PackageParser.Package>(); + final ArrayMap<String, PackageParser.Package> mPackages = + new ArrayMap<String, PackageParser.Package>(); // Tracks available target package names -> overlay package paths. - final HashMap<String, HashMap<String, PackageParser.Package>> mOverlays = - new HashMap<String, HashMap<String, PackageParser.Package>>(); + final ArrayMap<String, ArrayMap<String, PackageParser.Package>> mOverlays = + new ArrayMap<String, ArrayMap<String, PackageParser.Package>>(); final Settings mSettings; boolean mRestoredSettings; // System configuration read by SystemConfig. final int[] mGlobalGids; - final SparseArray<HashSet<String>> mSystemPermissions; - final HashMap<String, FeatureInfo> mAvailableFeatures; + final SparseArray<ArraySet<String>> mSystemPermissions; + final ArrayMap<String, FeatureInfo> mAvailableFeatures; // If mac_permissions.xml was found for seinfo labeling. boolean mFoundPolicyFile; @@ -403,8 +404,8 @@ public class PackageManagerService extends IPackageManager.Stub { } // Currently known shared libraries. - final HashMap<String, SharedLibraryEntry> mSharedLibraries = - new HashMap<String, SharedLibraryEntry>(); + final ArrayMap<String, SharedLibraryEntry> mSharedLibraries = + new ArrayMap<String, SharedLibraryEntry>(); // All available activities, for your resolving pleasure. final ActivityIntentResolver mActivities = @@ -422,23 +423,23 @@ public class PackageManagerService extends IPackageManager.Stub { // Mapping from provider base names (first directory in content URI codePath) // to the provider information. - final HashMap<String, PackageParser.Provider> mProvidersByAuthority = - new HashMap<String, PackageParser.Provider>(); + final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = + new ArrayMap<String, PackageParser.Provider>(); // Mapping from instrumentation class names to info about them. - final HashMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = - new HashMap<ComponentName, PackageParser.Instrumentation>(); + final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation = + new ArrayMap<ComponentName, PackageParser.Instrumentation>(); // Mapping from permission names to info about them. - final HashMap<String, PackageParser.PermissionGroup> mPermissionGroups = - new HashMap<String, PackageParser.PermissionGroup>(); + final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups = + new ArrayMap<String, PackageParser.PermissionGroup>(); // Packages whose data we have transfered into another package, thus // should no longer exist. - final HashSet<String> mTransferedPackages = new HashSet<String>(); + final ArraySet<String> mTransferedPackages = new ArraySet<String>(); // Broadcast actions that are only available to the system. - final HashSet<String> mProtectedBroadcasts = new HashSet<String>(); + final ArraySet<String> mProtectedBroadcasts = new ArraySet<String>(); /** List of packages waiting for verification. */ final SparseArray<PackageVerificationState> mPendingVerification @@ -449,7 +450,7 @@ public class PackageManagerService extends IPackageManager.Stub { final PackageInstallerService mInstallerService; - HashSet<PackageParser.Package> mDeferredDexOpt = null; + ArraySet<PackageParser.Package> mDeferredDexOpt = null; // Cache of users who need badging. SparseBooleanArray mUserNeedsBadging = new SparseBooleanArray(); @@ -473,24 +474,24 @@ public class PackageManagerService extends IPackageManager.Stub { // Set of pending broadcasts for aggregating enable/disable of components. static class PendingPackageBroadcasts { // for each user id, a map of <package name -> components within that package> - final SparseArray<HashMap<String, ArrayList<String>>> mUidMap; + final SparseArray<ArrayMap<String, ArrayList<String>>> mUidMap; public PendingPackageBroadcasts() { - mUidMap = new SparseArray<HashMap<String, ArrayList<String>>>(2); + mUidMap = new SparseArray<ArrayMap<String, ArrayList<String>>>(2); } public ArrayList<String> get(int userId, String packageName) { - HashMap<String, ArrayList<String>> packages = getOrAllocate(userId); + ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); return packages.get(packageName); } public void put(int userId, String packageName, ArrayList<String> components) { - HashMap<String, ArrayList<String>> packages = getOrAllocate(userId); + ArrayMap<String, ArrayList<String>> packages = getOrAllocate(userId); packages.put(packageName, components); } public void remove(int userId, String packageName) { - HashMap<String, ArrayList<String>> packages = mUidMap.get(userId); + ArrayMap<String, ArrayList<String>> packages = mUidMap.get(userId); if (packages != null) { packages.remove(packageName); } @@ -508,7 +509,7 @@ public class PackageManagerService extends IPackageManager.Stub { return mUidMap.keyAt(n); } - public HashMap<String, ArrayList<String>> packagesForUserId(int userId) { + public ArrayMap<String, ArrayList<String>> packagesForUserId(int userId) { return mUidMap.get(userId); } @@ -525,10 +526,10 @@ public class PackageManagerService extends IPackageManager.Stub { mUidMap.clear(); } - private HashMap<String, ArrayList<String>> getOrAllocate(int userId) { - HashMap<String, ArrayList<String>> map = mUidMap.get(userId); + private ArrayMap<String, ArrayList<String>> getOrAllocate(int userId) { + ArrayMap<String, ArrayList<String>> map = mUidMap.get(userId); if (map == null) { - map = new HashMap<String, ArrayList<String>>(); + map = new ArrayMap<String, ArrayList<String>>(); mUidMap.put(userId, map); } return map; @@ -565,7 +566,7 @@ public class PackageManagerService extends IPackageManager.Stub { static UserManagerService sUserManager; // Stores a list of users whose package restrictions file needs to be updated - private HashSet<Integer> mDirtyUsers = new HashSet<Integer>(); + private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>(); final private DefaultContainerConnection mDefContainerConn = new DefaultContainerConnection(); @@ -1294,6 +1295,15 @@ public class PackageManagerService extends IPackageManager.Stub { mSettings.addSharedUserLPw("android.uid.shell", SHELL_UID, ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PRIVILEGED); + // TODO: add a property to control this? + long dexOptLRUThresholdInMinutes; + if (mLazyDexOpt) { + dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds. + } else { + dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users. + } + mDexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000; + String separateProcesses = SystemProperties.get("debug.separate_processes"); if (separateProcesses != null && separateProcesses.length() > 0) { if ("*".equals(separateProcesses)) { @@ -1384,7 +1394,7 @@ public class PackageManagerService extends IPackageManager.Stub { // scanning install directories. final int scanFlags = SCAN_NO_PATHS | SCAN_DEFER_DEX | SCAN_BOOTING; - final HashSet<String> alreadyDexOpted = new HashSet<String>(); + final ArraySet<String> alreadyDexOpted = new ArraySet<String>(); /** * Add everything in the in the boot class path to the @@ -2369,7 +2379,7 @@ public class PackageManagerService extends IPackageManager.Stub { return PackageManager.PERMISSION_GRANTED; } } else { - HashSet<String> perms = mSystemPermissions.get(uid); + ArraySet<String> perms = mSystemPermissions.get(uid); if (perms != null && perms.contains(permName)) { return PackageManager.PERMISSION_GRANTED; } @@ -2790,11 +2800,11 @@ public class PackageManagerService extends IPackageManager.Stub { PackageManager.SIGNATURE_NO_MATCH; } - HashSet<Signature> set1 = new HashSet<Signature>(); + ArraySet<Signature> set1 = new ArraySet<Signature>(); for (Signature sig : s1) { set1.add(sig); } - HashSet<Signature> set2 = new HashSet<Signature>(); + ArraySet<Signature> set2 = new ArraySet<Signature>(); for (Signature sig : s2) { set2.add(sig); } @@ -2829,11 +2839,11 @@ public class PackageManagerService extends IPackageManager.Stub { return PackageManager.SIGNATURE_NO_MATCH; } - HashSet<Signature> existingSet = new HashSet<Signature>(); + ArraySet<Signature> existingSet = new ArraySet<Signature>(); for (Signature sig : existingSigs.mSignatures) { existingSet.add(sig); } - HashSet<Signature> scannedCompatSet = new HashSet<Signature>(); + ArraySet<Signature> scannedCompatSet = new ArraySet<Signature>(); for (Signature sig : scannedPkg.mSignatures) { try { Signature[] chainSignatures = sig.getChainSignatures(); @@ -4023,7 +4033,7 @@ public class PackageManagerService extends IPackageManager.Stub { } private void createIdmapsForPackageLI(PackageParser.Package pkg) { - HashMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); + ArrayMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName); if (overlays == null) { Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages"); return; @@ -4044,7 +4054,7 @@ public class PackageManagerService extends IPackageManager.Stub { opkg.baseCodePath + ": overlay not trusted"); return false; } - HashMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); + ArrayMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName); if (overlaySet == null) { Slog.e(TAG, "was about to create idmap for " + pkg.baseCodePath + " and " + opkg.baseCodePath + " but target package has no known overlays"); @@ -4465,7 +4475,7 @@ public class PackageManagerService extends IPackageManager.Stub { public void performBootDexOpt() { enforceSystemOrRoot("Only the system can request dexopt be performed"); - final HashSet<PackageParser.Package> pkgs; + final ArraySet<PackageParser.Package> pkgs; synchronized (mPackages) { pkgs = mDeferredDexOpt; mDeferredDexOpt = null; @@ -4488,7 +4498,7 @@ public class PackageManagerService extends IPackageManager.Stub { } // Give priority to system apps that listen for pre boot complete. Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED); - HashSet<String> pkgNames = getPackageNamesForIntent(intent); + ArraySet<String> pkgNames = getPackageNamesForIntent(intent); for (Iterator<PackageParser.Package> it = pkgs.iterator(); it.hasNext();) { PackageParser.Package pkg = it.next(); if (pkgNames.contains(pkg.packageName)) { @@ -4562,28 +4572,19 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private void filterRecentlyUsedApps(HashSet<PackageParser.Package> pkgs) { + private void filterRecentlyUsedApps(ArraySet<PackageParser.Package> pkgs) { // Filter out packages that aren't recently used. // // The exception is first boot of a non-eng device (aka !mLazyDexOpt), which // should do a full dexopt. if (mLazyDexOpt || (!isFirstBoot() && mPackageUsage.isHistoricalPackageUsageAvailable())) { - // TODO: add a property to control this? - long dexOptLRUThresholdInMinutes; - if (mLazyDexOpt) { - dexOptLRUThresholdInMinutes = 30; // only last 30 minutes of apps for eng builds. - } else { - dexOptLRUThresholdInMinutes = 7 * 24 * 60; // apps used in the 7 days for users. - } - long dexOptLRUThresholdInMills = dexOptLRUThresholdInMinutes * 60 * 1000; - int total = pkgs.size(); int skipped = 0; long now = System.currentTimeMillis(); for (Iterator<PackageParser.Package> i = pkgs.iterator(); i.hasNext();) { PackageParser.Package pkg = i.next(); long then = pkg.mLastPackageUsageTimeInMills; - if (then + dexOptLRUThresholdInMills < now) { + if (then + mDexOptLRUThresholdInMills < now) { if (DEBUG_DEXOPT) { Log.i(TAG, "Skipping dexopt of " + pkg.packageName + " last resumed: " + ((then == 0) ? "never" : new Date(then))); @@ -4598,14 +4599,14 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private HashSet<String> getPackageNamesForIntent(Intent intent) { + private ArraySet<String> getPackageNamesForIntent(Intent intent) { List<ResolveInfo> ris = null; try { ris = AppGlobals.getPackageManager().queryIntentReceivers( intent, null, 0, UserHandle.USER_OWNER); } catch (RemoteException e) { } - HashSet<String> pkgNames = new HashSet<String>(); + ArraySet<String> pkgNames = new ArraySet<String>(); if (ris != null) { for (ResolveInfo ri : ris) { pkgNames.add(ri.activityInfo.packageName); @@ -4683,8 +4684,8 @@ public class PackageManagerService extends IPackageManager.Stub { } } - public HashSet<String> getPackagesThatNeedDexOpt() { - HashSet<String> pkgs = null; + public ArraySet<String> getPackagesThatNeedDexOpt() { + ArraySet<String> pkgs = null; synchronized (mPackages) { for (PackageParser.Package p : mPackages.values()) { if (DEBUG_DEXOPT) { @@ -4694,7 +4695,7 @@ public class PackageManagerService extends IPackageManager.Stub { continue; } if (pkgs == null) { - pkgs = new HashSet<String>(); + pkgs = new ArraySet<String>(); } pkgs.add(p.packageName); } @@ -4707,7 +4708,7 @@ public class PackageManagerService extends IPackageManager.Stub { } private void performDexOptLibsLI(ArrayList<String> libs, String[] instructionSets, - boolean forceDex, boolean defer, HashSet<String> done) { + boolean forceDex, boolean defer, ArraySet<String> done) { for (int i=0; i<libs.size(); i++) { PackageParser.Package libPkg; String libName; @@ -4732,7 +4733,7 @@ public class PackageManagerService extends IPackageManager.Stub { static final int DEX_OPT_FAILED = -1; private int performDexOptLI(PackageParser.Package pkg, String[] targetInstructionSets, - boolean forceDex, boolean defer, HashSet<String> done) { + boolean forceDex, boolean defer, ArraySet<String> done) { final String[] instructionSets = targetInstructionSets != null ? targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo); @@ -4810,7 +4811,7 @@ public class PackageManagerService extends IPackageManager.Stub { // our list of deferred dexopts. if (defer && isDexOptNeeded != DexFile.UP_TO_DATE) { if (mDeferredDexOpt == null) { - mDeferredDexOpt = new HashSet<PackageParser.Package>(); + mDeferredDexOpt = new ArraySet<PackageParser.Package>(); } mDeferredDexOpt.add(pkg); return DEX_OPT_DEFERRED; @@ -4907,7 +4908,7 @@ public class PackageManagerService extends IPackageManager.Stub { } private static String[] getDexCodeInstructionSets(String[] instructionSets) { - HashSet<String> dexCodeInstructionSets = new HashSet<String>(instructionSets.length); + ArraySet<String> dexCodeInstructionSets = new ArraySet<String>(instructionSets.length); for (String instructionSet : instructionSets) { dexCodeInstructionSets.add(getDexCodeInstructionSet(instructionSet)); } @@ -4950,9 +4951,9 @@ public class PackageManagerService extends IPackageManager.Stub { private int performDexOptLI(PackageParser.Package pkg, String[] instructionSets, boolean forceDex, boolean defer, boolean inclDependencies) { - HashSet<String> done; + ArraySet<String> done; if (inclDependencies && (pkg.usesLibraries != null || pkg.usesOptionalLibraries != null)) { - done = new HashSet<String>(); + done = new ArraySet<String>(); done.add(pkg.packageName); } else { done = null; @@ -6137,7 +6138,7 @@ public class PackageManagerService extends IPackageManager.Stub { r = null; for (i=0; i<N; i++) { PackageParser.Permission p = pkg.permissions.get(i); - HashMap<String, BasePermission> permissionMap = + ArrayMap<String, BasePermission> permissionMap = p.tree ? mSettings.mPermissionTrees : mSettings.mPermissions; p.group = mPermissionGroups.get(p.info.group); @@ -6265,9 +6266,9 @@ public class PackageManagerService extends IPackageManager.Stub { if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) { if (!mOverlays.containsKey(pkg.mOverlayTarget)) { mOverlays.put(pkg.mOverlayTarget, - new HashMap<String, PackageParser.Package>()); + new ArrayMap<String, PackageParser.Package>()); } - HashMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); + ArrayMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget); map.put(pkg.packageName, pkg); PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget); if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) { @@ -6928,13 +6929,13 @@ public class PackageManagerService extends IPackageManager.Stub { return; } final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; - HashSet<String> origPermissions = gp.grantedPermissions; + ArraySet<String> origPermissions = gp.grantedPermissions; boolean changedPermission = false; if (replace) { ps.permissionsFixed = false; if (gp == ps) { - origPermissions = new HashSet<String>(gp.grantedPermissions); + origPermissions = new ArraySet<String>(gp.grantedPermissions); gp.grantedPermissions.clear(); gp.gids = mGlobalGids; } @@ -7081,7 +7082,7 @@ public class PackageManagerService extends IPackageManager.Stub { } private boolean grantSignaturePermission(String perm, PackageParser.Package pkg, - BasePermission bp, HashSet<String> origPermissions) { + BasePermission bp, ArraySet<String> origPermissions) { boolean allowed; allowed = (compareSignatures( bp.packageSetting.signatures.mSignatures, pkg.mSignatures) @@ -7339,8 +7340,8 @@ public class PackageManagerService extends IPackageManager.Stub { // } // Keys are String (activity class name), values are Activity. - private final HashMap<ComponentName, PackageParser.Activity> mActivities - = new HashMap<ComponentName, PackageParser.Activity>(); + private final ArrayMap<ComponentName, PackageParser.Activity> mActivities + = new ArrayMap<ComponentName, PackageParser.Activity>(); private int mFlags; } @@ -7538,8 +7539,8 @@ public class PackageManagerService extends IPackageManager.Stub { // } // Keys are String (activity class name), values are Activity. - private final HashMap<ComponentName, PackageParser.Service> mServices - = new HashMap<ComponentName, PackageParser.Service>(); + private final ArrayMap<ComponentName, PackageParser.Service> mServices + = new ArrayMap<ComponentName, PackageParser.Service>(); private int mFlags; }; @@ -7732,8 +7733,8 @@ public class PackageManagerService extends IPackageManager.Stub { out.println(Integer.toHexString(System.identityHashCode(filter))); } - private final HashMap<ComponentName, PackageParser.Provider> mProviders - = new HashMap<ComponentName, PackageParser.Provider>(); + private final ArrayMap<ComponentName, PackageParser.Provider> mProviders + = new ArrayMap<ComponentName, PackageParser.Provider>(); private int mFlags; }; @@ -11835,8 +11836,8 @@ public class PackageManagerService extends IPackageManager.Stub { synchronized (mPackages) { CrossProfileIntentResolver resolver = mSettings.editCrossProfileIntentResolverLPw(sourceUserId); - HashSet<CrossProfileIntentFilter> set = - new HashSet<CrossProfileIntentFilter>(resolver.filterSet()); + ArraySet<CrossProfileIntentFilter> set = + new ArraySet<CrossProfileIntentFilter>(resolver.filterSet()); for (CrossProfileIntentFilter filter : set) { if (filter.getOwnerPackage().equals(ownerPackage) && filter.getOwnerUserId() == callingUserId) { @@ -13381,4 +13382,25 @@ public class PackageManagerService extends IPackageManager.Stub { return false; } } + + public void getUsageStatsIfNoPackageUsageInfo() { + if (!mPackageUsage.isHistoricalPackageUsageAvailable()) { + UsageStatsManager usm = (UsageStatsManager) mContext.getSystemService(Context.USAGE_STATS_SERVICE); + if (usm == null) { + throw new IllegalStateException("UsageStatsManager must be initialized"); + } + long now = System.currentTimeMillis(); + Map<String, UsageStats> stats = usm.queryAndAggregateUsageStats(now - mDexOptLRUThresholdInMills, now); + for (Map.Entry<String, UsageStats> entry : stats.entrySet()) { + String packageName = entry.getKey(); + PackageParser.Package pkg = mPackages.get(packageName); + if (pkg == null) { + continue; + } + UsageStats usage = entry.getValue(); + pkg.mLastPackageUsageTimeInMills = usage.getLastTimeUsed(); + mPackageUsage.mIsHistoricalPackageUsageAvailable = true; + } + } + } } diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java index bf13fd97f5c6..1dcadb41089e 100644 --- a/services/core/java/com/android/server/pm/PackageSettingBase.java +++ b/services/core/java/com/android/server/pm/PackageSettingBase.java @@ -21,10 +21,10 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; import android.content.pm.PackageUserState; +import android.util.ArraySet; import android.util.SparseArray; import java.io.File; -import java.util.HashSet; /** * Settings base class for pending and resolved classes. @@ -321,8 +321,8 @@ class PackageSettingBase extends GrantedPermissions { void setUserState(int userId, int enabled, boolean installed, boolean stopped, boolean notLaunched, boolean hidden, - String lastDisableAppCaller, HashSet<String> enabledComponents, - HashSet<String> disabledComponents, boolean blockUninstall) { + String lastDisableAppCaller, ArraySet<String> enabledComponents, + ArraySet<String> disabledComponents, boolean blockUninstall) { PackageUserState state = modifyUserState(userId); state.enabled = enabled; state.installed = installed; @@ -335,39 +335,39 @@ class PackageSettingBase extends GrantedPermissions { state.blockUninstall = blockUninstall; } - HashSet<String> getEnabledComponents(int userId) { + ArraySet<String> getEnabledComponents(int userId) { return readUserState(userId).enabledComponents; } - HashSet<String> getDisabledComponents(int userId) { + ArraySet<String> getDisabledComponents(int userId) { return readUserState(userId).disabledComponents; } - void setEnabledComponents(HashSet<String> components, int userId) { + void setEnabledComponents(ArraySet<String> components, int userId) { modifyUserState(userId).enabledComponents = components; } - void setDisabledComponents(HashSet<String> components, int userId) { + void setDisabledComponents(ArraySet<String> components, int userId) { modifyUserState(userId).disabledComponents = components; } - void setEnabledComponentsCopy(HashSet<String> components, int userId) { + void setEnabledComponentsCopy(ArraySet<String> components, int userId) { modifyUserState(userId).enabledComponents = components != null - ? new HashSet<String>(components) : null; + ? new ArraySet<String>(components) : null; } - void setDisabledComponentsCopy(HashSet<String> components, int userId) { + void setDisabledComponentsCopy(ArraySet<String> components, int userId) { modifyUserState(userId).disabledComponents = components != null - ? new HashSet<String>(components) : null; + ? new ArraySet<String>(components) : null; } PackageUserState modifyUserStateComponents(int userId, boolean disabled, boolean enabled) { PackageUserState state = modifyUserState(userId); if (disabled && state.disabledComponents == null) { - state.disabledComponents = new HashSet<String>(1); + state.disabledComponents = new ArraySet<String>(1); } if (enabled && state.enabledComponents == null) { - state.enabledComponents = new HashSet<String>(1); + state.enabledComponents = new ArraySet<String>(1); } return state; } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 7de56c890f6b..200eb5f16afb 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -63,6 +63,8 @@ import android.content.pm.Signature; import android.content.pm.UserInfo; import android.content.pm.PackageUserState; import android.content.pm.VerifierDeviceIdentity; +import android.util.ArrayMap; +import android.util.ArraySet; import android.util.Log; import android.util.Slog; import android.util.SparseArray; @@ -78,8 +80,6 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -159,11 +159,11 @@ final class Settings { private final File mStoppedPackagesFilename; private final File mBackupStoppedPackagesFilename; - final HashMap<String, PackageSetting> mPackages = - new HashMap<String, PackageSetting>(); + final ArrayMap<String, PackageSetting> mPackages = + new ArrayMap<String, PackageSetting>(); // List of replaced system applications - private final HashMap<String, PackageSetting> mDisabledSysPackages = - new HashMap<String, PackageSetting>(); + private final ArrayMap<String, PackageSetting> mDisabledSysPackages = + new ArrayMap<String, PackageSetting>(); private static int mFirstAvailableUid = 0; @@ -206,8 +206,8 @@ final class Settings { final SparseArray<CrossProfileIntentResolver> mCrossProfileIntentResolvers = new SparseArray<CrossProfileIntentResolver>(); - final HashMap<String, SharedUserSetting> mSharedUsers = - new HashMap<String, SharedUserSetting>(); + final ArrayMap<String, SharedUserSetting> mSharedUsers = + new ArrayMap<String, SharedUserSetting>(); private final ArrayList<Object> mUserIds = new ArrayList<Object>(); private final SparseArray<Object> mOtherUserIds = new SparseArray<Object>(); @@ -217,12 +217,12 @@ final class Settings { new ArrayList<Signature>(); // Mapping from permission names to info about them. - final HashMap<String, BasePermission> mPermissions = - new HashMap<String, BasePermission>(); + final ArrayMap<String, BasePermission> mPermissions = + new ArrayMap<String, BasePermission>(); // Mapping from permission tree names to info about them. - final HashMap<String, BasePermission> mPermissionTrees = - new HashMap<String, BasePermission>(); + final ArrayMap<String, BasePermission> mPermissionTrees = + new ArrayMap<String, BasePermission>(); // Packages that have been uninstalled and still need their external // storage data deleted. @@ -232,7 +232,7 @@ final class Settings { // Keys are the new names of the packages, values are the original // names. The packages appear everwhere else under their original // names. - final HashMap<String, String> mRenamedPackages = new HashMap<String, String>(); + final ArrayMap<String, String> mRenamedPackages = new ArrayMap<String, String>(); final StringBuilder mReadMessages = new StringBuilder(); @@ -437,7 +437,7 @@ final class Settings { void transferPermissionsLPw(String origPkg, String newPkg) { // Transfer ownership of permissions to the new package. for (int i=0; i<2; i++) { - HashMap<String, BasePermission> permissions = + ArrayMap<String, BasePermission> permissions = i == 0 ? mPermissionTrees : mPermissions; for (BasePermission bp : permissions.values()) { if (origPkg.equals(bp.sourcePackage)) { @@ -582,7 +582,7 @@ final class Settings { } p.appId = dis.appId; // Clone permissions - p.grantedPermissions = new HashSet<String>(dis.grantedPermissions); + p.grantedPermissions = new ArraySet<String>(dis.grantedPermissions); // Clone component info List<UserInfo> users = getAllUsers(); if (users != null) { @@ -1138,8 +1138,8 @@ final class Settings { final boolean blockUninstall = blockUninstallStr == null ? false : Boolean.parseBoolean(blockUninstallStr); - HashSet<String> enabledComponents = null; - HashSet<String> disabledComponents = null; + ArraySet<String> enabledComponents = null; + ArraySet<String> disabledComponents = null; int packageDepth = parser.getDepth(); while ((type=parser.next()) != XmlPullParser.END_DOCUMENT @@ -1189,9 +1189,9 @@ final class Settings { } } - private HashSet<String> readComponentsLPr(XmlPullParser parser) + private ArraySet<String> readComponentsLPr(XmlPullParser parser) throws IOException, XmlPullParserException { - HashSet<String> components = null; + ArraySet<String> components = null; int type; int outerDepth = parser.getDepth(); String tagName; @@ -1207,7 +1207,7 @@ final class Settings { String componentName = parser.getAttributeValue(null, ATTR_NAME); if (componentName != null) { if (components == null) { - components = new HashSet<String>(); + components = new ArraySet<String>(); } components.add(componentName); } @@ -1921,7 +1921,7 @@ final class Settings { } ArrayList<PackageSetting> getListOfIncompleteInstallPackagesLPr() { - final HashSet<String> kList = new HashSet<String>(mPackages.keySet()); + final ArraySet<String> kList = new ArraySet<String>(mPackages.keySet()); final Iterator<String> its = kList.iterator(); final ArrayList<PackageSetting> ret = new ArrayList<PackageSetting>(); while (its.hasNext()) { @@ -2511,7 +2511,7 @@ final class Settings { return defValue; } - private void readPermissionsLPw(HashMap<String, BasePermission> out, XmlPullParser parser) + private void readPermissionsLPw(ArrayMap<String, BasePermission> out, XmlPullParser parser) throws IOException, XmlPullParserException { int outerDepth = parser.getDepth(); int type; @@ -3016,7 +3016,7 @@ final class Settings { } } - private void readGrantedPermissionsLPw(XmlPullParser parser, HashSet<String> outPerms) + private void readGrantedPermissionsLPw(XmlPullParser parser, ArraySet<String> outPerms) throws IOException, XmlPullParserException { int outerDepth = parser.getDepth(); int type; @@ -3090,8 +3090,8 @@ final class Settings { int sourceUserId = mCrossProfileIntentResolvers.keyAt(i); CrossProfileIntentResolver cpir = mCrossProfileIntentResolvers.get(sourceUserId); boolean needsWriting = false; - HashSet<CrossProfileIntentFilter> cpifs = - new HashSet<CrossProfileIntentFilter>(cpir.filterSet()); + ArraySet<CrossProfileIntentFilter> cpifs = + new ArraySet<CrossProfileIntentFilter>(cpir.filterSet()); for (CrossProfileIntentFilter cpif : cpifs) { if (cpif.getTargetUserId() == userId) { needsWriting = true; @@ -3147,7 +3147,7 @@ final class Settings { return ps; } - private String compToString(HashSet<String> cmp) { + private String compToString(ArraySet<String> cmp) { return cmp != null ? Arrays.toString(cmp.toArray()) : "[]"; } @@ -3477,7 +3477,7 @@ final class Settings { pw.print(prefix); pw.print(" lastDisabledCaller: "); pw.println(lastDisabledAppCaller); } - HashSet<String> cmp = ps.getDisabledComponents(user.id); + ArraySet<String> cmp = ps.getDisabledComponents(user.id); if (cmp != null && cmp.size() > 0) { pw.print(prefix); pw.println(" disabledComponents:"); for (String s : cmp) { diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java index ca1eeea69745..2b406f775d75 100644 --- a/services/core/java/com/android/server/pm/SharedUserSetting.java +++ b/services/core/java/com/android/server/pm/SharedUserSetting.java @@ -16,7 +16,7 @@ package com.android.server.pm; -import java.util.HashSet; +import android.util.ArraySet; /** * Settings data for a particular shared user ID we know about. @@ -29,7 +29,7 @@ final class SharedUserSetting extends GrantedPermissions { // flags that are associated with this uid, regardless of any package flags int uidFlags; - final HashSet<PackageSetting> packages = new HashSet<PackageSetting>(); + final ArraySet<PackageSetting> packages = new ArraySet<PackageSetting>(); final PackageSignatures signatures = new PackageSignatures(); diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java index 52807c025a3a..5e95dfeed1ee 100644 --- a/services/core/java/com/android/server/power/PowerManagerService.java +++ b/services/core/java/com/android/server/power/PowerManagerService.java @@ -281,6 +281,9 @@ public final class PowerManagerService extends SystemService // True if the device should wake up when plugged or unplugged. private boolean mWakeUpWhenPluggedOrUnpluggedConfig; + // True if the device should wake up when plugged or unplugged in theater mode. + private boolean mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig; + // True if the device should suspend when the screen is off due to proximity. private boolean mSuspendWhenScreenOffDueToProximityConfig; @@ -420,6 +423,9 @@ public final class PowerManagerService extends SystemService // True if the battery level is currently considered low. private boolean mBatteryLevelLow; + // True if theater mode is enabled + private boolean mTheaterModeEnabled; + private final ArrayList<PowerManagerInternal.LowPowerModeListener> mLowPowerModeListeners = new ArrayList<PowerManagerInternal.LowPowerModeListener>(); @@ -568,6 +574,9 @@ public final class PowerManagerService extends SystemService resolver.registerContentObserver(Settings.Global.getUriFor( Settings.Global.LOW_POWER_MODE_TRIGGER_LEVEL), false, mSettingsObserver, UserHandle.USER_ALL); + resolver.registerContentObserver(Settings.Global.getUriFor( + Settings.Global.THEATER_MODE_ON), + false, mSettingsObserver, UserHandle.USER_ALL); // Go. readConfigurationLocked(); updateSettingsLocked(); @@ -585,6 +594,8 @@ public final class PowerManagerService extends SystemService com.android.internal.R.bool.config_powerDecoupleInteractiveModeFromDisplay); mWakeUpWhenPluggedOrUnpluggedConfig = resources.getBoolean( com.android.internal.R.bool.config_unplugTurnsOnScreen); + mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig = resources.getBoolean( + com.android.internal.R.bool.config_allowTheaterModeWakeFromUnplug); mSuspendWhenScreenOffDueToProximityConfig = resources.getBoolean( com.android.internal.R.bool.config_suspendWhenScreenOffDueToProximity); mDreamsSupportedConfig = resources.getBoolean( @@ -636,6 +647,8 @@ public final class PowerManagerService extends SystemService UserHandle.USER_CURRENT); mStayOnWhilePluggedInSetting = Settings.Global.getInt(resolver, Settings.Global.STAY_ON_WHILE_PLUGGED_IN, BatteryManager.BATTERY_PLUGGED_AC); + mTheaterModeEnabled = Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.THEATER_MODE_ON, 0) == 1; final int oldScreenBrightnessSetting = mScreenBrightnessSetting; mScreenBrightnessSetting = Settings.System.getIntForUser(resolver, @@ -1334,6 +1347,11 @@ public final class PowerManagerService extends SystemService return false; } + // Don't wake while theater mode is enabled. + if (mTheaterModeEnabled && !mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig) { + return false; + } + // Otherwise wake up! return true; } @@ -2360,6 +2378,10 @@ public final class PowerManagerService extends SystemService + mDecoupleHalInteractiveModeFromDisplayConfig); pw.println(" mWakeUpWhenPluggedOrUnpluggedConfig=" + mWakeUpWhenPluggedOrUnpluggedConfig); + pw.println(" mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig=" + + mWakeUpWhenPluggedOrUnpluggedInTheaterModeConfig); + pw.println(" mTheaterModeEnabled=" + + mTheaterModeEnabled); pw.println(" mSuspendWhenScreenOffDueToProximityConfig=" + mSuspendWhenScreenOffDueToProximityConfig); pw.println(" mDreamsSupportedConfig=" + mDreamsSupportedConfig); diff --git a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java index f85e2d9a29b6..15e0bf03d2e0 100644 --- a/services/core/java/com/android/server/statusbar/StatusBarManagerService.java +++ b/services/core/java/com/android/server/statusbar/StatusBarManagerService.java @@ -26,6 +26,7 @@ import android.content.Context; import android.content.pm.PackageManager; import android.content.res.Resources; import android.util.Slog; +import android.view.WindowManager; import com.android.internal.statusbar.IStatusBar; import com.android.internal.statusbar.IStatusBarService; @@ -295,9 +296,10 @@ public class StatusBarManagerService extends IStatusBarService.Stub { } } - /** + /** * Hide or show the on-screen Menu key. Only call this from the window manager, typically in - * response to a window with FLAG_NEEDS_MENU_KEY set. + * response to a window with {@link android.view.WindowManager.LayoutParams#needsMenuKey} set + * to {@link android.view.WindowManager.LayoutParams#NEEDS_MENU_SET_TRUE}. */ @Override public void topAppWindowChanged(final boolean menuVisible) { @@ -523,6 +525,20 @@ public class StatusBarManagerService extends IStatusBarService.Stub { } @Override + public void onNotificationActionClick(String key, int actionIndex) { + enforceStatusBarService(); + final int callingUid = Binder.getCallingUid(); + final int callingPid = Binder.getCallingPid(); + long identity = Binder.clearCallingIdentity(); + try { + mNotificationDelegate.onNotificationActionClick(callingUid, callingPid, key, + actionIndex); + } finally { + Binder.restoreCallingIdentity(identity); + } + } + + @Override public void onNotificationError(String pkg, String tag, int id, int uid, int initialPid, String message, int userId) { enforceStatusBarService(); diff --git a/services/core/java/com/android/server/trust/TrustManagerService.java b/services/core/java/com/android/server/trust/TrustManagerService.java index fefbe0a608ec..164953589013 100644 --- a/services/core/java/com/android/server/trust/TrustManagerService.java +++ b/services/core/java/com/android/server/trust/TrustManagerService.java @@ -16,6 +16,7 @@ package com.android.server.trust; +import com.android.internal.annotations.GuardedBy; import com.android.internal.content.PackageMonitor; import com.android.internal.widget.LockPatternUtils; import com.android.server.SystemService; @@ -24,6 +25,7 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import android.Manifest; +import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.admin.DevicePolicyManager; import android.app.trust.ITrustListener; @@ -41,6 +43,7 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; +import android.os.Binder; import android.os.DeadObjectException; import android.os.Handler; import android.os.IBinder; @@ -100,8 +103,10 @@ public class TrustManagerService extends SystemService { /* package */ final TrustArchive mArchive = new TrustArchive(); private final Context mContext; private final LockPatternUtils mLockPatternUtils; + private final UserManager mUserManager; - private UserManager mUserManager; + @GuardedBy("mUserIsTrusted") + private final SparseBooleanArray mUserIsTrusted = new SparseBooleanArray(); public TrustManagerService(Context context) { super(context); @@ -120,8 +125,9 @@ public class TrustManagerService extends SystemService { if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY && !isSafeMode()) { mPackageMonitor.register(mContext, mHandler.getLooper(), UserHandle.ALL, true); mReceiver.register(mContext); - maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_OWNER); refreshAgentList(UserHandle.USER_ALL); + } else if (phase == SystemService.PHASE_BOOT_COMPLETED && !isSafeMode()) { + maybeEnableFactoryTrustAgents(mLockPatternUtils, UserHandle.USER_OWNER); } } @@ -159,7 +165,11 @@ public class TrustManagerService extends SystemService { public void updateTrust(int userId, boolean initiatedByUser) { dispatchOnTrustManagedChanged(aggregateIsTrustManaged(userId), userId); - dispatchOnTrustChanged(aggregateIsTrusted(userId), userId, initiatedByUser); + boolean trusted = aggregateIsTrusted(userId); + synchronized (mUserIsTrusted) { + mUserIsTrusted.put(userId, trusted); + } + dispatchOnTrustChanged(trusted, userId, initiatedByUser); } void refreshAgentList(int userId) { @@ -546,6 +556,16 @@ public class TrustManagerService extends SystemService { mHandler.obtainMessage(MSG_UNREGISTER_LISTENER, trustListener).sendToTarget(); } + @Override + public boolean isTrusted(int userId) throws RemoteException { + userId = ActivityManager.handleIncomingUser(getCallingPid(), getCallingUid(), userId, + false /* allowAll */, true /* requireFull */, "isTrusted", null); + userId = resolveProfileParent(userId); + synchronized (mUserIsTrusted) { + return mUserIsTrusted.get(userId); + } + } + private void enforceReportPermission() { mContext.enforceCallingOrSelfPermission( Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE, "reporting trust events"); @@ -622,6 +642,19 @@ public class TrustManagerService extends SystemService { } }; + private int resolveProfileParent(int userId) { + long identity = Binder.clearCallingIdentity(); + try { + UserInfo parent = mUserManager.getProfileParent(userId); + if (parent != null) { + return parent.getUserHandle().getIdentifier(); + } + return userId; + } finally { + Binder.restoreCallingIdentity(identity); + } + } + private final Handler mHandler = new Handler() { @Override public void handleMessage(Message msg) { diff --git a/services/core/java/com/android/server/tv/TvInputHal.java b/services/core/java/com/android/server/tv/TvInputHal.java index 558ffb5e3ddd..c12dd633c07f 100644 --- a/services/core/java/com/android/server/tv/TvInputHal.java +++ b/services/core/java/com/android/server/tv/TvInputHal.java @@ -55,7 +55,7 @@ final class TvInputHal implements Handler.Callback { private native long nativeOpen(); - private static native int nativeAddStream(long ptr, int deviceId, int streamId, + private static native int nativeAddOrUpdateStream(long ptr, int deviceId, int streamId, Surface surface); private static native int nativeRemoveStream(long ptr, int deviceId, int streamId); private static native TvStreamConfig[] nativeGetStreamConfigs(long ptr, int deviceId, @@ -80,7 +80,7 @@ final class TvInputHal implements Handler.Callback { } } - public int addStream(int deviceId, Surface surface, TvStreamConfig streamConfig) { + public int addOrUpdateStream(int deviceId, Surface surface, TvStreamConfig streamConfig) { synchronized (mLock) { if (mPtr == 0) { return ERROR_NO_INIT; @@ -89,7 +89,7 @@ final class TvInputHal implements Handler.Callback { if (generation != streamConfig.getGeneration()) { return ERROR_STALE_CONFIG; } - if (nativeAddStream(mPtr, deviceId, streamConfig.getStreamId(), surface) == 0) { + if (nativeAddOrUpdateStream(mPtr, deviceId, streamConfig.getStreamId(), surface) == 0) { return SUCCESS; } else { return ERROR_UNKNOWN; diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java index 44e4ad10c353..85659cf78c80 100644 --- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java +++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java @@ -188,6 +188,11 @@ class TvInputHardwareManager implements TvInputHal.Callback { return; } connection.updateConfigsLocked(configs); + String inputId = mHardwareInputIdMap.get(deviceId); + if (inputId != null) { + mHandler.obtainMessage(ListenerHandler.STATE_CHANGED, + convertConnectedToState(configs.length > 0), 0, inputId).sendToTarget(); + } try { connection.getCallbackLocked().onStreamConfigChanged(configs); } catch (RemoteException e) { @@ -257,6 +262,9 @@ class TvInputHardwareManager implements TvInputHal.Callback { mHardwareInputIdMap.put(deviceId, info.getId()); mInputMap.put(info.getId(), info); + // Process pending state changes + + // For logical HDMI devices, they have information from HDMI CEC signals. for (int i = 0; i < mHdmiStateMap.size(); ++i) { TvInputHardwareInfo hardwareInfo = findHardwareInfoForHdmiPortLocked(mHdmiStateMap.keyAt(i)); @@ -268,8 +276,17 @@ class TvInputHardwareManager implements TvInputHal.Callback { mHandler.obtainMessage(ListenerHandler.STATE_CHANGED, convertConnectedToState(mHdmiStateMap.valueAt(i)), 0, inputId).sendToTarget(); + return; } } + // For the rest of the devices, we can tell by the number of available streams. + Connection connection = mConnections.get(deviceId); + if (connection != null) { + mHandler.obtainMessage(ListenerHandler.STATE_CHANGED, + convertConnectedToState(connection.getConfigsLocked().length > 0), 0, + info.getId()).sendToTarget(); + return; + } } } @@ -668,14 +685,14 @@ class TvInputHardwareManager implements TvInputHal.Callback { result = mHal.removeStream(mInfo.getDeviceId(), mActiveConfig); mActiveConfig = null; } else { - if (config != mActiveConfig && mActiveConfig != null) { + if (!config.equals(mActiveConfig)) { result = mHal.removeStream(mInfo.getDeviceId(), mActiveConfig); if (result != TvInputHal.SUCCESS) { mActiveConfig = null; return false; } } - result = mHal.addStream(mInfo.getDeviceId(), surface, config); + result = mHal.addOrUpdateStream(mInfo.getDeviceId(), surface, config); if (result == TvInputHal.SUCCESS) { mActiveConfig = config; } @@ -801,7 +818,7 @@ class TvInputHardwareManager implements TvInputHal.Callback { return false; } - int result = mHal.addStream(mInfo.getDeviceId(), surface, config); + int result = mHal.addOrUpdateStream(mInfo.getDeviceId(), surface, config); return result == TvInputHal.SUCCESS; } } diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java index fde703d63dc3..f947b6ab8654 100644 --- a/services/core/java/com/android/server/wm/AccessibilityController.java +++ b/services/core/java/com/android/server/wm/AccessibilityController.java @@ -992,8 +992,7 @@ final class AccessibilityController { final int flags = windowState.mAttrs.flags; - // If the window is not touchable, do not report it but take into account - // the space it takes since the content behind it cannot be touched. + // If the window is not touchable - ignore. if ((flags & WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE) != 0) { continue; } @@ -1014,9 +1013,14 @@ final class AccessibilityController { } } - // Account for the space this window takes. - unaccountedSpace.op(boundsInScreen, unaccountedSpace, - Region.Op.REVERSE_DIFFERENCE); + // Account for the space this window takes if the window + // is not an accessibility overlay which does not change + // the reported windows. + if (windowState.mAttrs.type == WindowManager.LayoutParams + .TYPE_ACCESSIBILITY_OVERLAY) { + unaccountedSpace.op(boundsInScreen, unaccountedSpace, + Region.Op.REVERSE_DIFFERENCE); + } // We figured out what is touchable for the entire screen - done. if (unaccountedSpace.isEmpty()) { diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 30589b1c27a0..b0feca8fadab 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -376,10 +376,9 @@ class DisplayContent { stack.dump(prefix + " ", pw); } pw.println(); - pw.println(" Application tokens in bottom up Z order:"); + pw.println(" Application tokens in top down Z order:"); int ndx = 0; - final int numStacks = mStacks.size(); - for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) { + for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { ArrayList<Task> tasks = mStacks.get(stackNdx).getTasks(); for (int taskNdx = tasks.size() - 1; taskNdx >= 0; --taskNdx) { AppTokenList tokens = tasks.get(taskNdx).mAppTokens; diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 9ceac41a8bca..a60be3b95d6a 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -60,6 +60,12 @@ class Task { return removed; } + void setSendingToBottom(boolean toBottom) { + for (int appTokenNdx = 0; appTokenNdx < mAppTokens.size(); appTokenNdx++) { + mAppTokens.get(appTokenNdx).sendingToBottom = toBottom; + } + } + @Override public String toString() { return "{taskId=" + taskId + " appTokens=" + mAppTokens + "}"; diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index f82aee4d1e23..3fee608d2292 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -619,6 +619,9 @@ public class WindowManagerService extends IWindowManager.Stub boolean mTurnOnScreen; + // Whether or not a layout can cause a wake up when theater mode is enabled. + boolean mAllowTheaterModeWakeFromLayout; + DragState mDragState = null; // For frozen screen animations. @@ -881,6 +884,9 @@ public class WindowManagerService extends IWindowManager.Stub mAnimator = new WindowAnimator(this); + mAllowTheaterModeWakeFromLayout = context.getResources().getBoolean( + com.android.internal.R.bool.config_allowTheaterModeWakeFromWindowLayout); + LocalServices.addService(WindowManagerInternal.class, new LocalService()); initPolicy(); @@ -2331,6 +2337,11 @@ public class WindowManagerService extends IWindowManager.Stub + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } + if (type == TYPE_ACCESSIBILITY_OVERLAY) { + Slog.w(TAG, "Attempted to add Accessibility overlay window with unknown token " + + attrs.token + ". Aborting."); + return WindowManagerGlobal.ADD_BAD_APP_TOKEN; + } token = new WindowToken(this, attrs.token, -1, false); addToken = true; } else if (type >= FIRST_APPLICATION_WINDOW && type <= LAST_APPLICATION_WINDOW) { @@ -2374,6 +2385,12 @@ public class WindowManagerService extends IWindowManager.Stub + attrs.token + ". Aborting."); return WindowManagerGlobal.ADD_BAD_APP_TOKEN; } + } else if (type == TYPE_ACCESSIBILITY_OVERLAY) { + if (token.windowType != TYPE_ACCESSIBILITY_OVERLAY) { + Slog.w(TAG, "Attempted to add Accessibility overlay window with bad token " + + attrs.token + ". Aborting."); + return WindowManagerGlobal.ADD_BAD_APP_TOKEN; + } } else if (token.appWindowToken != null) { Slog.w(TAG, "Non-null appWindowToken for system window of type=" + type); // It is not valid to use an app token with other system types; we will @@ -2509,9 +2526,8 @@ public class WindowManagerService extends IWindowManager.Stub } mInputMonitor.updateInputWindowsLw(false /*force*/); - if (localLOGV) Slog.v( - TAG, "New client " + client.asBinder() - + ": window=" + win); + if (true || localLOGV) Slog.v(TAG, "addWindow: New client " + client.asBinder() + + ": window=" + win + " Callers=" + Debug.getCallers(5)); if (win.isVisibleOrAdding() && updateOrientationFromAppTokensLocked(false)) { reportNewConfig = true; @@ -2675,7 +2691,8 @@ public class WindowManagerService extends IWindowManager.Stub mPolicy.removeWindowLw(win); win.removeLocked(); - if (DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win); + if (true || DEBUG_ADD_REMOVE) Slog.v(TAG, "removeWindowInnerLocked: " + win + + " Callers=" + Debug.getCallers(5)); mWindowMap.remove(win.mClient.asBinder()); if (win.mAppOp != AppOpsManager.OP_NONE) { mAppOps.finishOp(win.mAppOp, win.getOwningUid(), win.getOwningPackage()); @@ -5052,6 +5069,10 @@ public class WindowManagerService extends IWindowManager.Stub } } stack.moveTaskToTop(task); + if (mAppTransition.isTransitionSet()) { + task.setSendingToBottom(false); + } + moveStackWindowsLocked(displayContent); } } finally { Binder.restoreCallingIdentity(origId); @@ -5070,6 +5091,9 @@ public class WindowManagerService extends IWindowManager.Stub } final TaskStack stack = task.mStack; stack.moveTaskToBottom(task); + if (mAppTransition.isTransitionSet()) { + task.setSendingToBottom(true); + } moveStackWindowsLocked(stack.getDisplayContent()); } } finally { @@ -9953,8 +9977,12 @@ public class WindowManagerService extends IWindowManager.Stub } if (mTurnOnScreen) { - if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!"); - mPowerManager.wakeUp(SystemClock.uptimeMillis()); + if (mAllowTheaterModeWakeFromLayout + || Settings.Global.getInt(mContext.getContentResolver(), + Settings.Global.THEATER_MODE_ON, 0) == 0) { + if (DEBUG_VISIBILITY) Slog.v(TAG, "Turning screen on after layout!"); + mPowerManager.wakeUp(SystemClock.uptimeMillis()); + } mTurnOnScreen = false; } @@ -11610,5 +11638,23 @@ public class WindowManagerService extends IWindowManager.Stub checkDrawnWindowsLocked(); } } + + @Override + public void addWindowToken(IBinder token, int type) { + WindowManagerService.this.addWindowToken(token, type); + } + + @Override + public void removeWindowToken(IBinder token, boolean removeWindows) { + synchronized(mWindowMap) { + if (removeWindows) { + WindowToken wtoken = mTokenMap.remove(token); + if (wtoken != null) { + wtoken.removeAllWindows(); + } + } + WindowManagerService.this.removeWindowToken(token); + } + } } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index abc437054c3b..e5cf7644ffb9 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -724,9 +724,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { WindowState ws = this; WindowList windows = getWindowList(); while (true) { - if ((ws.mAttrs.privateFlags - & WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY) != 0) { - return (ws.mAttrs.flags & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0; + if (ws.mAttrs.needsMenuKey != WindowManager.LayoutParams.NEEDS_MENU_UNSET) { + return ws.mAttrs.needsMenuKey == WindowManager.LayoutParams.NEEDS_MENU_SET_TRUE; } // If we reached the bottom of the range of windows we are considering, // assume no menu is needed. diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java index 22671234c538..1a672e682814 100644 --- a/services/core/java/com/android/server/wm/WindowToken.java +++ b/services/core/java/com/android/server/wm/WindowToken.java @@ -17,6 +17,7 @@ package com.android.server.wm; import android.os.IBinder; +import android.util.Slog; import java.io.PrintWriter; @@ -29,7 +30,7 @@ import java.io.PrintWriter; class WindowToken { // The window manager! final WindowManagerService service; - + // The actual token. final IBinder token; @@ -77,6 +78,15 @@ class WindowToken { explicit = _explicit; } + void removeAllWindows() { + for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) { + WindowState win = windows.get(winNdx); + if (WindowManagerService.DEBUG_WINDOW_MOVEMENT) Slog.w(WindowManagerService.TAG, + "removeAllWindows: removing win=" + win); + win.mService.removeWindowLocked(win.mSession, win); + } + } + void dump(PrintWriter pw, String prefix) { pw.print(prefix); pw.print("windows="); pw.println(windows); pw.print(prefix); pw.print("windowType="); pw.print(windowType); diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp index d5abe0c25dae..5cb05431fe9e 100644 --- a/services/core/jni/com_android_server_tv_TvInputHal.cpp +++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp @@ -235,7 +235,7 @@ public: static JTvInputHal* createInstance(JNIEnv* env, jobject thiz); - int addStream(int deviceId, int streamId, const sp<Surface>& surface); + int addOrUpdateStream(int deviceId, int streamId, const sp<Surface>& surface); int removeStream(int deviceId, int streamId); const tv_stream_config_t* getStreamConfigs(int deviceId, int* numConfigs); @@ -312,7 +312,7 @@ JTvInputHal* JTvInputHal::createInstance(JNIEnv* env, jobject thiz) { return new JTvInputHal(env, thiz, device); } -int JTvInputHal::addStream(int deviceId, int streamId, const sp<Surface>& surface) { +int JTvInputHal::addOrUpdateStream(int deviceId, int streamId, const sp<Surface>& surface) { KeyedVector<int, Connection>& connections = mConnections.editValueFor(deviceId); if (connections.indexOfKey(streamId) < 0) { connections.add(streamId, Connection()); @@ -555,14 +555,14 @@ static jlong nativeOpen(JNIEnv* env, jobject thiz) { return (jlong)JTvInputHal::createInstance(env, thiz); } -static int nativeAddStream(JNIEnv* env, jclass clazz, +static int nativeAddOrUpdateStream(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId, jint streamId, jobject jsurface) { JTvInputHal* tvInputHal = (JTvInputHal*)ptr; if (!jsurface) { return BAD_VALUE; } sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); - return tvInputHal->addStream(deviceId, streamId, surface); + return tvInputHal->addOrUpdateStream(deviceId, streamId, surface); } static int nativeRemoveStream(JNIEnv* env, jclass clazz, @@ -612,8 +612,8 @@ static JNINativeMethod gTvInputHalMethods[] = { /* name, signature, funcPtr */ { "nativeOpen", "()J", (void*) nativeOpen }, - { "nativeAddStream", "(JIILandroid/view/Surface;)I", - (void*) nativeAddStream }, + { "nativeAddOrUpdateStream", "(JIILandroid/view/Surface;)I", + (void*) nativeAddOrUpdateStream }, { "nativeRemoveStream", "(JII)I", (void*) nativeRemoveStream }, { "nativeGetStreamConfigs", "(JII)[Landroid/media/tv/TvStreamConfig;", diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index fe4b7b9cc949..9ee44b99876f 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1687,7 +1687,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { .setContentTitle(mContext.getString(R.string.ssl_ca_cert_warning)) .setContentText(contentText) .setContentIntent(notifyIntent) - .setOngoing(true) .setPriority(Notification.PRIORITY_HIGH) .setShowWhen(false) .setColor(mContext.getResources().getColor( diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 6009ffdcae61..d7f61305abdf 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -374,6 +374,8 @@ public final class SystemServer { mSystemServiceManager.startService(UsageStatsService.class); mActivityManagerService.setUsageStatsManager( LocalServices.getService(UsageStatsManagerInternal.class)); + // Update after UsageStatsService is available, needed before performBootDexOpt. + mPackageManagerService.getUsageStatsIfNoPackageUsageInfo(); // Tracks whether the updatable WebView is in a ready state and watches for update installs. mSystemServiceManager.startService(WebViewUpdateService.class); diff --git a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java index c3d4ed9f1ab5..c115339a9b1d 100644 --- a/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/NetworkStatsServiceTest.java @@ -932,7 +932,6 @@ public class NetworkStatsServiceTest extends AndroidTestCase { expect(mSettings.getPollInterval()).andReturn(HOUR_IN_MILLIS).anyTimes(); expect(mSettings.getTimeCacheMaxAge()).andReturn(DAY_IN_MILLIS).anyTimes(); expect(mSettings.getSampleEnabled()).andReturn(true).anyTimes(); - expect(mSettings.getReportXtOverDev()).andReturn(true).anyTimes(); final Config config = new Config(bucketDuration, deleteAge, deleteAge); expect(mSettings.getDevConfig()).andReturn(config).anyTimes(); diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java index a70ebf481de7..b631331e9546 100644 --- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java +++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java @@ -21,22 +21,15 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER; import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED; -import com.android.internal.content.PackageHelper; +import android.test.AndroidTestCase; +import android.util.ArraySet; +import android.util.Log; + import com.android.internal.os.AtomicFile; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; -import java.util.HashSet; - -import android.os.Debug; -import android.os.Environment; -import android.os.IBinder; -import android.os.RemoteException; -import android.os.ServiceManager; -import android.os.storage.IMountService; -import android.test.AndroidTestCase; -import android.util.Log; public class PackageManagerSettingsTests extends AndroidTestCase { @@ -182,11 +175,11 @@ public class PackageManagerSettingsTests extends AndroidTestCase { assertEquals(COMPONENT_ENABLED_STATE_ENABLED, ps.getEnabled(1)); // Enable/Disable a component - HashSet<String> components = new HashSet<String>(); + ArraySet<String> components = new ArraySet<String>(); String component1 = PACKAGE_NAME_1 + "/.Component1"; components.add(component1); ps.setDisabledComponents(components, 0); - HashSet<String> componentsDisabled = ps.getDisabledComponents(0); + ArraySet<String> componentsDisabled = ps.getDisabledComponents(0); assertEquals(1, componentsDisabled.size()); assertEquals(component1, componentsDisabled.toArray()[0]); boolean hasEnabled = diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 2ed974505de3..7ff246a1bdbc 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -38,6 +38,7 @@ import android.os.Environment; import android.os.Handler; import android.os.Looper; import android.os.Message; +import android.os.Process; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; @@ -349,8 +350,12 @@ public class UsageStatsService extends SystemService implements private class BinderService extends IUsageStatsManager.Stub { private boolean hasPermission(String callingPackage) { + final int callingUid = Binder.getCallingUid(); + if (callingUid == Process.SYSTEM_UID) { + return true; + } final int mode = mAppOps.checkOp(AppOpsManager.OP_GET_USAGE_STATS, - Binder.getCallingUid(), callingPackage); + callingUid, callingPackage); if (mode == AppOpsManager.MODE_DEFAULT) { // The default behavior here is to check if PackageManager has given the app // permission. diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java index f9349639456d..354fa2ee6498 100644 --- a/telecomm/java/android/telecom/Call.java +++ b/telecomm/java/android/telecom/Call.java @@ -484,10 +484,10 @@ public final class Call { /** * Notifies this {@code Call} that an account has been selected and to proceed with placing - * an outgoing call. + * an outgoing call. Optionally sets this account as the default account. */ - public void phoneAccountSelected(PhoneAccountHandle accountHandle) { - mInCallAdapter.phoneAccountSelected(mTelecomCallId, accountHandle); + public void phoneAccountSelected(PhoneAccountHandle accountHandle, boolean setDefault) { + mInCallAdapter.phoneAccountSelected(mTelecomCallId, accountHandle, setDefault); } diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java index 44fa157eb5b4..2932721f28b6 100644 --- a/telecomm/java/android/telecom/Connection.java +++ b/telecomm/java/android/telecom/Connection.java @@ -898,6 +898,13 @@ public abstract class Connection { } /** + * @hide + */ + public final ConnectionService getConnectionService() { + return mConnectionService; + } + + /** * Sets the conference that this connection is a part of. This will fail if the connection is * already part of a conference call. {@link #resetConference} to un-set the conference first. * @@ -927,6 +934,7 @@ public abstract class Connection { Log.d(this, "Conference reset"); mConference = null; fireConferenceChanged(); + onConferenceChanged(); } } diff --git a/telecomm/java/android/telecom/InCallAdapter.java b/telecomm/java/android/telecom/InCallAdapter.java index fd3cf2e12668..62b8dea946b4 100644 --- a/telecomm/java/android/telecom/InCallAdapter.java +++ b/telecomm/java/android/telecom/InCallAdapter.java @@ -189,14 +189,16 @@ public final class InCallAdapter { } /** - * Instructs Telecom to add a PhoneAccountHandle to the specified call + * Instructs Telecom to add a PhoneAccountHandle to the specified call. * - * @param callId The identifier of the call - * @param accountHandle The PhoneAccountHandle through which to place the call + * @param callId The identifier of the call. + * @param accountHandle The PhoneAccountHandle through which to place the call. + * @param setDefault {@code True} if this account should be set as the default for calls. */ - public void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle) { + public void phoneAccountSelected(String callId, PhoneAccountHandle accountHandle, + boolean setDefault) { try { - mAdapter.phoneAccountSelected(callId, accountHandle); + mAdapter.phoneAccountSelected(callId, accountHandle, setDefault); } catch (RemoteException e) { } } diff --git a/telecomm/java/android/telecom/PhoneAccount.java b/telecomm/java/android/telecom/PhoneAccount.java index 66b52ae1df20..402df30c6f78 100644 --- a/telecomm/java/android/telecom/PhoneAccount.java +++ b/telecomm/java/android/telecom/PhoneAccount.java @@ -105,11 +105,17 @@ public class PhoneAccount implements Parcelable { */ public static final String SCHEME_SIP = "sip"; + /** + * Indicating no color is set. + */ + public static final int NO_COLOR = -1; + private final PhoneAccountHandle mAccountHandle; private final Uri mAddress; private final Uri mSubscriptionAddress; private final int mCapabilities; private final int mIconResId; + private final int mColor; private final CharSequence mLabel; private final CharSequence mShortDescription; private final List<String> mSupportedUriSchemes; @@ -120,6 +126,7 @@ public class PhoneAccount implements Parcelable { private Uri mSubscriptionAddress; private int mCapabilities; private int mIconResId; + private int mColor = NO_COLOR; private CharSequence mLabel; private CharSequence mShortDescription; private List<String> mSupportedUriSchemes = new ArrayList<String>(); @@ -141,6 +148,7 @@ public class PhoneAccount implements Parcelable { mSubscriptionAddress = phoneAccount.getSubscriptionAddress(); mCapabilities = phoneAccount.getCapabilities(); mIconResId = phoneAccount.getIconResId(); + mColor = phoneAccount.getColor(); mLabel = phoneAccount.getLabel(); mShortDescription = phoneAccount.getShortDescription(); mSupportedUriSchemes.addAll(phoneAccount.getSupportedUriSchemes()); @@ -166,6 +174,11 @@ public class PhoneAccount implements Parcelable { return this; } + public Builder setColor(int value) { + this.mColor = value; + return this; + } + public Builder setShortDescription(CharSequence value) { this.mShortDescription = value; return this; @@ -219,6 +232,7 @@ public class PhoneAccount implements Parcelable { mSubscriptionAddress, mCapabilities, mIconResId, + mColor, mLabel, mShortDescription, mSupportedUriSchemes); @@ -231,6 +245,7 @@ public class PhoneAccount implements Parcelable { Uri subscriptionAddress, int capabilities, int iconResId, + int color, CharSequence label, CharSequence shortDescription, List<String> supportedUriSchemes) { @@ -239,6 +254,7 @@ public class PhoneAccount implements Parcelable { mSubscriptionAddress = subscriptionAddress; mCapabilities = capabilities; mIconResId = iconResId; + mColor = color; mLabel = label; mShortDescription = shortDescription; mSupportedUriSchemes = Collections.unmodifiableList(supportedUriSchemes); @@ -371,6 +387,15 @@ public class PhoneAccount implements Parcelable { } /** + * A highlight color to use in displaying information about this {@code PhoneAccount}. + * + * @return A hexadecimal color value. + */ + public int getColor() { + return mColor; + } + + /** * An icon to represent this {@code PhoneAccount} in a user interface. * * @return An icon for this {@code PhoneAccount}. @@ -418,6 +443,7 @@ public class PhoneAccount implements Parcelable { out.writeParcelable(mSubscriptionAddress, 0); out.writeInt(mCapabilities); out.writeInt(mIconResId); + out.writeInt(mColor); out.writeCharSequence(mLabel); out.writeCharSequence(mShortDescription); out.writeList(mSupportedUriSchemes); @@ -444,6 +470,7 @@ public class PhoneAccount implements Parcelable { mSubscriptionAddress = in.readParcelable(getClass().getClassLoader()); mCapabilities = in.readInt(); mIconResId = in.readInt(); + mColor = in.readInt(); mLabel = in.readCharSequence(); mShortDescription = in.readCharSequence(); diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index ed221d295e05..2652b4532899 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -31,7 +31,6 @@ import java.util.List; /** * Provides access to Telecom-related functionality. - * TODO: Move this all into PhoneManager. */ public class TelecomManager { @@ -587,7 +586,6 @@ public class TelecomManager { * * @param account The complete {@link PhoneAccount}. */ - @SystemApi public void registerPhoneAccount(PhoneAccount account) { try { if (isServiceConnected()) { @@ -603,7 +601,6 @@ public class TelecomManager { * * @param accountHandle A {@link PhoneAccountHandle} for the {@link PhoneAccount} to unregister. */ - @SystemApi public void unregisterPhoneAccount(PhoneAccountHandle accountHandle) { try { if (isServiceConnected()) { @@ -617,7 +614,6 @@ public class TelecomManager { /** * Remove all Accounts that belong to the calling package from the system. */ - @SystemApi public void clearAccounts() { try { if (isServiceConnected()) { @@ -671,7 +667,6 @@ public class TelecomManager { * Requires permission: {@link android.Manifest.permission#READ_PHONE_STATE} * </p> */ - @SystemApi public boolean isInCall() { try { if (isServiceConnected()) { @@ -823,7 +818,6 @@ public class TelecomManager { * @param extras A bundle that will be passed through to * {@link ConnectionService#onCreateIncomingConnection}. */ - @SystemApi public void addNewIncomingCall(PhoneAccountHandle phoneAccount, Bundle extras) { try { if (isServiceConnected()) { diff --git a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl index 138a877cd843..863fff29d560 100644 --- a/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl +++ b/telecomm/java/com/android/internal/telecom/IInCallAdapter.aidl @@ -46,7 +46,8 @@ oneway interface IInCallAdapter { void postDialContinue(String callId, boolean proceed); - void phoneAccountSelected(String callId, in PhoneAccountHandle accountHandle); + void phoneAccountSelected(String callId, in PhoneAccountHandle accountHandle, + boolean setDefault); void conference(String callId, String otherCallId); diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java index 27e9baf1bbec..897702dc093d 100644 --- a/telephony/java/android/telephony/PhoneNumberUtils.java +++ b/telephony/java/android/telephony/PhoneNumberUtils.java @@ -1570,7 +1570,7 @@ public class PhoneNumberUtils * listed in the RIL / SIM, otherwise return false. * @hide */ - public static boolean isEmergencyNumber(long subId, String number) { + public static boolean isEmergencyNumber(int subId, String number) { // Return true only if the specified number *exactly* matches // one of the emergency numbers listed by the RIL / SIM. return isEmergencyNumberInternal(subId, number, true /* useExactMatch */); @@ -1620,7 +1620,7 @@ public class PhoneNumberUtils * same digits as any of those emergency numbers. * @hide */ - public static boolean isPotentialEmergencyNumber(long subId, String number) { + public static boolean isPotentialEmergencyNumber(int subId, String number) { // Check against the emergency numbers listed by the RIL / SIM, // and *don't* require an exact match. return isEmergencyNumberInternal(subId, number, false /* useExactMatch */); @@ -1669,7 +1669,7 @@ public class PhoneNumberUtils * @return true if the number is in the list of emergency numbers * listed in the RIL / sim, otherwise return false. */ - private static boolean isEmergencyNumberInternal(long subId, String number, + private static boolean isEmergencyNumberInternal(int subId, String number, boolean useExactMatch) { return isEmergencyNumberInternal(subId, number, null, useExactMatch); } @@ -1698,7 +1698,7 @@ public class PhoneNumberUtils * otherwise false * @hide */ - public static boolean isEmergencyNumber(long subId, String number, String defaultCountryIso) { + public static boolean isEmergencyNumber(int subId, String number, String defaultCountryIso) { return isEmergencyNumberInternal(subId, number, defaultCountryIso, true /* useExactMatch */); @@ -1750,7 +1750,7 @@ public class PhoneNumberUtils * any of those emergency numbers. * @hide */ - public static boolean isPotentialEmergencyNumber(long subId, String number, + public static boolean isPotentialEmergencyNumber(int subId, String number, String defaultCountryIso) { return isEmergencyNumberInternal(subId, number, defaultCountryIso, @@ -1794,7 +1794,7 @@ public class PhoneNumberUtils * @return true if the number is an emergency number for the specified country. * @hide */ - private static boolean isEmergencyNumberInternal(long subId, String number, + private static boolean isEmergencyNumberInternal(int subId, String number, String defaultCountryIso, boolean useExactMatch) { // If the number passed in is null, just return false: @@ -1911,7 +1911,7 @@ public class PhoneNumberUtils * is currently in. * @hide */ - public static boolean isLocalEmergencyNumber(Context context, long subId, String number) { + public static boolean isLocalEmergencyNumber(Context context, int subId, String number) { return isLocalEmergencyNumberInternal(subId, number, context, true /* useExactMatch */); @@ -1965,7 +1965,7 @@ public class PhoneNumberUtils * * @hide */ - public static boolean isPotentialLocalEmergencyNumber(Context context, long subId, + public static boolean isPotentialLocalEmergencyNumber(Context context, int subId, String number) { return isLocalEmergencyNumberInternal(subId, number, context, @@ -2014,7 +2014,7 @@ public class PhoneNumberUtils * local country, based on the CountryDetector. * @hide */ - private static boolean isLocalEmergencyNumberInternal(long subId, String number, + private static boolean isLocalEmergencyNumberInternal(int subId, String number, Context context, boolean useExactMatch) { String countryIso; @@ -2057,7 +2057,7 @@ public class PhoneNumberUtils * to read the VM number. * @hide */ - public static boolean isVoiceMailNumber(long subId, String number) { + public static boolean isVoiceMailNumber(int subId, String number) { String vmNumber; try { @@ -2796,7 +2796,7 @@ public class PhoneNumberUtils /** * Returns Default voice subscription Id. */ - private static long getDefaultVoiceSubId() { + private static int getDefaultVoiceSubId() { return SubscriptionManager.getDefaultVoiceSubId(); } //==== End of utility methods used only in compareStrictly() ===== diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java index ec34ce8218ca..2f1a8da24d54 100644 --- a/telephony/java/android/telephony/PhoneStateListener.java +++ b/telephony/java/android/telephony/PhoneStateListener.java @@ -227,7 +227,7 @@ public class PhoneStateListener { * @hide */ /** @hide */ - protected long mSubId = SubscriptionManager.INVALID_SUB_ID; + protected int mSubId = SubscriptionManager.INVALID_SUB_ID; private final Handler mHandler; @@ -252,10 +252,10 @@ public class PhoneStateListener { /** * Create a PhoneStateListener for the Phone using the specified subscription. * This class requires Looper.myLooper() not return null. To supply your - * own non-null Looper use PhoneStateListener(long subId, Looper looper) below. + * own non-null Looper use PhoneStateListener(int subId, Looper looper) below. * @hide */ - public PhoneStateListener(long subId) { + public PhoneStateListener(int subId) { this(subId, Looper.myLooper()); } @@ -264,7 +264,7 @@ public class PhoneStateListener { * and non-null Looper. * @hide */ - public PhoneStateListener(long subId, Looper looper) { + public PhoneStateListener(int subId, Looper looper) { if (DBG) log("ctor: subId=" + subId + " looper=" + looper); mSubId = subId; mHandler = new Handler(looper) { diff --git a/telephony/java/android/telephony/SubInfoRecord.java b/telephony/java/android/telephony/SubInfoRecord.java index b9de8719a4cf..4a3d67ef25a5 100644 --- a/telephony/java/android/telephony/SubInfoRecord.java +++ b/telephony/java/android/telephony/SubInfoRecord.java @@ -16,6 +16,7 @@ package android.telephony; +import android.graphics.drawable.BitmapDrawable; import android.os.Parcel; import android.os.Parcelable; @@ -28,7 +29,7 @@ public class SubInfoRecord implements Parcelable { * Subscription Identifier, this is a device unique number * and not an index into an array */ - public long subId; + public int subId; /** The GID for a SIM that maybe associated with this subscription, empty if unknown */ public String iccId; /** @@ -90,7 +91,7 @@ public class SubInfoRecord implements Parcelable { this.mnc = 0; } - public SubInfoRecord(long subId, String iccId, int slotId, String displayName, int nameSource, + public SubInfoRecord(int subId, String iccId, int slotId, String displayName, int nameSource, int color, String number, int displayFormat, int roaming, int[] iconRes, int mcc, int mnc) { this.subId = subId; @@ -107,10 +108,35 @@ public class SubInfoRecord implements Parcelable { this.mnc = mnc; } + /** + * Returns the string displayed to the user that identifies this subscription + */ + public String getLabel() { + return this.displayName; + } + + /** + * Return the icon used to identify this SIM. + * TODO: return the correct drawable. + */ + public BitmapDrawable getIconDrawable() { + return new BitmapDrawable(); + } + + /** + * Return the color to be used for when displaying to the user. This is the value of the color. + * ex: 0x00ff00 + */ + public int getColor() { + // Note: This color is currently an index into a list of drawables, but this is soon to + // change. + return this.color; + } + public static final Parcelable.Creator<SubInfoRecord> CREATOR = new Parcelable.Creator<SubInfoRecord>() { @Override public SubInfoRecord createFromParcel(Parcel source) { - long subId = source.readLong(); + int subId = source.readInt(); String iccId = source.readString(); int slotId = source.readInt(); String displayName = source.readString(); @@ -136,7 +162,7 @@ public class SubInfoRecord implements Parcelable { @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeLong(subId); + dest.writeInt(subId); dest.writeString(iccId); dest.writeInt(slotId); dest.writeString(displayName); diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java index c96c3830b0dc..c3ad82627a0e 100644 --- a/telephony/java/android/telephony/SubscriptionManager.java +++ b/telephony/java/android/telephony/SubscriptionManager.java @@ -57,21 +57,21 @@ public class SubscriptionManager implements BaseColumns { public static final int DEFAULT_SLOT_ID = Integer.MAX_VALUE; /** Indicates the user should be asked which subscription to use. */ - public static final long ASK_USER_SUB_ID = -1001; + public static final int ASK_USER_SUB_ID = -1001; /** An invalid subscription identifier */ - public static final long INVALID_SUB_ID = -1000; + public static final int INVALID_SUB_ID = -1000; /** Indicates the caller wants the default sub id. */ - public static final long DEFAULT_SUB_ID = Long.MAX_VALUE; + public static final int DEFAULT_SUB_ID = Integer.MAX_VALUE; /** Minimum possible subid that represents a subscription */ /** @hide */ - public static final long MIN_SUB_ID_VALUE = 0; + public static final int MIN_SUB_ID_VALUE = 0; /** Maximum possible subid that represents a subscription */ /** @hide */ - public static final long MAX_SUB_ID_VALUE = DEFAULT_SUB_ID - 1; + public static final int MAX_SUB_ID_VALUE = DEFAULT_SUB_ID - 1; /** @hide */ @@ -265,7 +265,7 @@ public class SubscriptionManager implements BaseColumns { * @param subId The unique SubInfoRecord index in database * @return SubInfoRecord, maybe null */ - public static SubInfoRecord getSubInfoForSubscriber(long subId) { + public static SubInfoRecord getSubInfoForSubscriber(int subId) { if (!isValidSubId(subId)) { logd("[getSubInfoForSubscriberx]- invalid subId"); return null; @@ -475,7 +475,7 @@ public class SubscriptionManager implements BaseColumns { * @return the number of records updated * @hide */ - public static int setColor(int color, long subId) { + public static int setColor(int color, int subId) { if (VDBG) logd("[setColor]+ color:" + color + " subId:" + subId); int size = sSimBackgroundDarkRes.length; if (!isValidSubId(subId) || color < 0 || color >= size) { @@ -505,7 +505,7 @@ public class SubscriptionManager implements BaseColumns { * @return the number of records updated * @hide */ - public static int setDisplayName(String displayName, long subId) { + public static int setDisplayName(String displayName, int subId) { return setDisplayName(displayName, subId, NAME_SOURCE_UNDEFINDED); } @@ -518,7 +518,7 @@ public class SubscriptionManager implements BaseColumns { * @return the number of records updated or -1 if invalid subId * @hide */ - public static int setDisplayName(String displayName, long subId, long nameSource) { + public static int setDisplayName(String displayName, int subId, long nameSource) { if (VDBG) { logd("[setDisplayName]+ displayName:" + displayName + " subId:" + subId + " nameSource:" + nameSource); @@ -550,7 +550,7 @@ public class SubscriptionManager implements BaseColumns { * @return the number of records updated * @hide */ - public static int setDisplayNumber(String number, long subId) { + public static int setDisplayNumber(String number, int subId) { if (number == null || !isValidSubId(subId)) { logd("[setDisplayNumber]- fail"); return -1; @@ -578,7 +578,7 @@ public class SubscriptionManager implements BaseColumns { * @return the number of records updated * @hide */ - public static int setDisplayNumberFormat(int format, long subId) { + public static int setDisplayNumberFormat(int format, int subId) { if (VDBG) logd("[setDisplayNumberFormat]+ format:" + format + " subId:" + subId); if (format < 0 || !isValidSubId(subId)) { logd("[setDisplayNumberFormat]- fail, return -1"); @@ -607,7 +607,7 @@ public class SubscriptionManager implements BaseColumns { * @return the number of records updated * @hide */ - public static int setDataRoaming(int roaming, long subId) { + public static int setDataRoaming(int roaming, int subId) { if (VDBG) logd("[setDataRoaming]+ roaming:" + roaming + " subId:" + subId); if (roaming < 0 || !isValidSubId(subId)) { logd("[setDataRoaming]- fail"); @@ -633,7 +633,7 @@ public class SubscriptionManager implements BaseColumns { * @return slotId as a positive integer or a negative value if an error either * SIM_NOT_INSERTED or INVALID_SLOT_ID. */ - public static int getSlotId(long subId) { + public static int getSlotId(int subId) { if (!isValidSubId(subId)) { logd("[getSlotId]- fail"); } @@ -654,13 +654,13 @@ public class SubscriptionManager implements BaseColumns { } /** @hide */ - public static long[] getSubId(int slotId) { + public static int[] getSubId(int slotId) { if (!isValidSlotId(slotId)) { logd("[getSubId]- fail"); return null; } - long[] subId = null; + int[] subId = null; try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); @@ -675,7 +675,7 @@ public class SubscriptionManager implements BaseColumns { } /** @hide */ - public static int getPhoneId(long subId) { + public static int getPhoneId(int subId) { if (!isValidSubId(subId)) { logd("[getPhoneId]- fail"); return INVALID_PHONE_ID; @@ -732,8 +732,8 @@ public class SubscriptionManager implements BaseColumns { * getDefaultDataSubId(). * @hide */ - public static long getDefaultSubId() { - long subId = INVALID_SUB_ID; + public static int getDefaultSubId() { + int subId = INVALID_SUB_ID; try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); @@ -749,8 +749,8 @@ public class SubscriptionManager implements BaseColumns { } /** @hide */ - public static long getDefaultVoiceSubId() { - long subId = INVALID_SUB_ID; + public static int getDefaultVoiceSubId() { + int subId = INVALID_SUB_ID; try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); @@ -766,7 +766,7 @@ public class SubscriptionManager implements BaseColumns { } /** @hide */ - public static void setDefaultVoiceSubId(long subId) { + public static void setDefaultVoiceSubId(int subId) { if (VDBG) logd("setDefaultVoiceSubId sub id = " + subId); try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); @@ -791,8 +791,8 @@ public class SubscriptionManager implements BaseColumns { /** * @return subId of the DefaultSms subscription or the value INVALID_SUB_ID if an error. */ - public static long getDefaultSmsSubId() { - long subId = INVALID_SUB_ID; + public static int getDefaultSmsSubId() { + int subId = INVALID_SUB_ID; try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); @@ -808,7 +808,7 @@ public class SubscriptionManager implements BaseColumns { } /** @hide */ - public static void setDefaultSmsSubId(long subId) { + public static void setDefaultSmsSubId(int subId) { if (VDBG) logd("setDefaultSmsSubId sub id = " + subId); try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); @@ -831,8 +831,8 @@ public class SubscriptionManager implements BaseColumns { } /** @hide */ - public static long getDefaultDataSubId() { - long subId = INVALID_SUB_ID; + public static int getDefaultDataSubId() { + int subId = INVALID_SUB_ID; try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); @@ -848,7 +848,7 @@ public class SubscriptionManager implements BaseColumns { } /** @hide */ - public static void setDefaultDataSubId(long subId) { + public static void setDefaultDataSubId(int subId) { if (VDBG) logd("setDataSubscription sub id = " + subId); try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); @@ -919,7 +919,7 @@ public class SubscriptionManager implements BaseColumns { /** * @return true if a valid subId else false */ - public static boolean isValidSubId(long subId) { + public static boolean isValidSubId(int subId) { return subId > INVALID_SUB_ID ; } @@ -928,7 +928,7 @@ public class SubscriptionManager implements BaseColumns { * usable subId means its neither a INVALID_SUB_ID nor a DEFAUL_SUB_ID. * @hide */ - public static boolean isUsableSubIdValue(long subId) { + public static boolean isUsableSubIdValue(int subId) { return subId >= MIN_SUB_ID_VALUE && subId <= MAX_SUB_ID_VALUE; } @@ -952,7 +952,7 @@ public class SubscriptionManager implements BaseColumns { /** @hide */ public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId) { - long[] subIds = SubscriptionManager.getSubId(phoneId); + int[] subIds = SubscriptionManager.getSubId(phoneId); if (subIds != null && subIds.length > 0) { putPhoneIdAndSubIdExtra(intent, phoneId, subIds[0]); } else { @@ -961,7 +961,7 @@ public class SubscriptionManager implements BaseColumns { } /** @hide */ - public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, long subId) { + public static void putPhoneIdAndSubIdExtra(Intent intent, int phoneId, int subId) { if (VDBG) logd("putPhoneIdAndSubIdExtra: phoneId=" + phoneId + " subId=" + subId); intent.putExtra(PhoneConstants.SUBSCRIPTION_KEY, subId); intent.putExtra(PhoneConstants.PHONE_KEY, phoneId); @@ -975,8 +975,8 @@ public class SubscriptionManager implements BaseColumns { * is never null but the length maybe 0. * @hide */ - public static long[] getActiveSubIdList() { - long[] subId = null; + public static int[] getActiveSubIdList() { + int[] subId = null; try { ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub")); @@ -988,7 +988,7 @@ public class SubscriptionManager implements BaseColumns { } if (subId == null) { - subId = new long[0]; + subId = new int[0]; } return subId; diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index d3cef4a1c88e..a3546ed16c45 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -588,7 +588,7 @@ public class TelephonyManager { /** {@hide} */ public String getDeviceSoftwareVersion(int slotId) { // FIXME methods taking slot id should not use subscription, instead us Uicc directly - long[] subId = SubscriptionManager.getSubId(slotId); + int[] subId = SubscriptionManager.getSubId(slotId); if (subId == null || subId.length == 0) { return null; } @@ -624,7 +624,7 @@ public class TelephonyManager { /** {@hide} */ public String getDeviceId(int slotId) { // FIXME methods taking slot id should not use subscription, instead us Uicc directly - long[] subId = SubscriptionManager.getSubId(slotId); + int[] subId = SubscriptionManager.getSubId(slotId); if (subId == null || subId.length == 0) { return null; } @@ -658,7 +658,7 @@ public class TelephonyManager { */ /** {@hide} */ public String getImei(int slotId) { - long[] subId = SubscriptionManager.getSubId(slotId); + int[] subId = SubscriptionManager.getSubId(slotId); try { return getSubscriberInfo().getImeiForSubscriber(subId[0]); } catch (RemoteException ex) { @@ -684,7 +684,7 @@ public class TelephonyManager { */ /** {@hide}*/ public String getNai(int slotId) { - long[] subId = SubscriptionManager.getSubId(slotId); + int[] subId = SubscriptionManager.getSubId(slotId); try { return getSubscriberInfo().getNaiForSubscriber(subId[0]); } catch (RemoteException ex) { @@ -748,7 +748,7 @@ public class TelephonyManager { * @param subId for which the location updates are enabled */ /** @hide */ - public void enableLocationUpdates(long subId) { + public void enableLocationUpdates(int subId) { try { getITelephony().enableLocationUpdatesForSubscriber(subId); } catch (RemoteException ex) { @@ -770,7 +770,7 @@ public class TelephonyManager { } /** @hide */ - public void disableLocationUpdates(long subId) { + public void disableLocationUpdates(int subId) { try { getITelephony().disableLocationUpdatesForSubscriber(subId); } catch (RemoteException ex) { @@ -835,7 +835,7 @@ public class TelephonyManager { */ /** {@hide} */ @SystemApi - public int getCurrentPhoneType(long subId) { + public int getCurrentPhoneType(int subId) { int phoneId = SubscriptionManager.getPhoneId(subId); try{ ITelephony telephony = getITelephony(); @@ -1047,7 +1047,7 @@ public class TelephonyManager { * @param subId */ /** {@hide} */ - public String getNetworkOperatorName(long subId) { + public String getNetworkOperatorName(int subId) { int phoneId = SubscriptionManager.getPhoneId(subId); return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ALPHA, ""); } @@ -1074,7 +1074,7 @@ public class TelephonyManager { * @param subId */ /** {@hide} */ - public String getNetworkOperator(long subId) { + public String getNetworkOperator(int subId) { int phoneId = SubscriptionManager.getPhoneId(subId); return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_NUMERIC, ""); } @@ -1098,7 +1098,7 @@ public class TelephonyManager { * @param subId */ /** {@hide} */ - public boolean isNetworkRoaming(long subId) { + public boolean isNetworkRoaming(int subId) { int phoneId = SubscriptionManager.getPhoneId(subId); return Boolean.parseBoolean(getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ISROAMING, null)); @@ -1127,7 +1127,7 @@ public class TelephonyManager { * @param subId for which Network CountryIso is returned */ /** {@hide} */ - public String getNetworkCountryIso(long subId) { + public String getNetworkCountryIso(int subId) { int phoneId = SubscriptionManager.getPhoneId(subId); return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_OPERATOR_ISO_COUNTRY, ""); } @@ -1199,7 +1199,7 @@ public class TelephonyManager { * @see #NETWORK_TYPE_HSPAP */ /** {@hide} */ - public int getNetworkType(long subId) { + public int getNetworkType(int subId) { try { ITelephony telephony = getITelephony(); if (telephony != null) { @@ -1253,7 +1253,7 @@ public class TelephonyManager { * @param subId for which network type is returned */ /** {@hide} */ - public int getDataNetworkType(long subId) { + public int getDataNetworkType(int subId) { try{ ITelephony telephony = getITelephony(); if (telephony != null) { @@ -1285,7 +1285,7 @@ public class TelephonyManager { * */ /** {@hide} */ - public int getVoiceNetworkType(long subId) { + public int getVoiceNetworkType(int subId) { try{ ITelephony telephony = getITelephony(); if (telephony != null) { @@ -1442,7 +1442,7 @@ public class TelephonyManager { */ /** {@hide} */ // FIXME Input argument slotId should be of type int - public boolean hasIccCard(long slotId) { + public boolean hasIccCard(int slotId) { try { return getITelephony().hasIccCardUsingSlotId(slotId); @@ -1487,7 +1487,7 @@ public class TelephonyManager { /** {@hide} */ // FIXME the argument to pass is subId ?? public int getSimState(int slotId) { - long[] subId = SubscriptionManager.getSubId(slotId); + int[] subId = SubscriptionManager.getSubId(slotId); if (subId == null || subId.length == 0) { return SIM_STATE_ABSENT; } @@ -1527,7 +1527,7 @@ public class TelephonyManager { * @see #getSimState */ public String getSimOperator() { - long subId = SubscriptionManager.getDefaultDataSubId(); + int subId = SubscriptionManager.getDefaultDataSubId(); if (!SubscriptionManager.isUsableSubIdValue(subId)) { subId = SubscriptionManager.getDefaultSmsSubId(); if (!SubscriptionManager.isUsableSubIdValue(subId)) { @@ -1552,7 +1552,7 @@ public class TelephonyManager { * @param subId for which SimOperator is returned */ /** {@hide} */ - public String getSimOperator(long subId) { + public String getSimOperator(int subId) { int phoneId = SubscriptionManager.getPhoneId(subId); String operator = getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC, ""); @@ -1581,7 +1581,7 @@ public class TelephonyManager { * @param subId for which SimOperatorName is returned */ /** {@hide} */ - public String getSimOperatorName(long subId) { + public String getSimOperatorName(int subId) { int phoneId = SubscriptionManager.getPhoneId(subId); return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_ICC_OPERATOR_ALPHA, ""); } @@ -1599,7 +1599,7 @@ public class TelephonyManager { * @param subId for which SimCountryIso is returned */ /** {@hide} */ - public String getSimCountryIso(long subId) { + public String getSimCountryIso(int subId) { int phoneId = SubscriptionManager.getPhoneId(subId); return getTelephonyProperty(phoneId, TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY, ""); @@ -1625,7 +1625,7 @@ public class TelephonyManager { * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE} */ /** {@hide} */ - public String getSimSerialNumber(long subId) { + public String getSimSerialNumber(int subId) { try { return getSubscriberInfo().getIccSerialNumberForSubscriber(subId); } catch (RemoteException ex) { @@ -1661,7 +1661,7 @@ public class TelephonyManager { * */ /** {@hide} */ - public int getLteOnCdmaMode(long subId) { + public int getLteOnCdmaMode(int subId) { try { return getITelephony().getLteOnCdmaModeForSubscriber(subId); } catch (RemoteException ex) { @@ -1701,7 +1701,7 @@ public class TelephonyManager { * @param subId whose subscriber id is returned */ /** {@hide} */ - public String getSubscriberId(long subId) { + public String getSubscriberId(int subId) { try { return getSubscriberInfo().getSubscriberIdForSubscriber(subId); } catch (RemoteException ex) { @@ -1740,7 +1740,7 @@ public class TelephonyManager { * @param subscription whose subscriber id is returned */ /** {@hide} */ - public String getGroupIdLevel1(long subId) { + public String getGroupIdLevel1(int subId) { try { return getSubscriberInfo().getGroupIdLevel1ForSubscriber(subId); } catch (RemoteException ex) { @@ -1772,7 +1772,7 @@ public class TelephonyManager { * @param subId whose phone number for line 1 is returned */ /** {@hide} */ - public String getLine1NumberForSubscriber(long subId) { + public String getLine1NumberForSubscriber(int subId) { String number = null; try { number = getITelephony().getLine1NumberForDisplay(subId); @@ -1824,7 +1824,7 @@ public class TelephonyManager { * @param number The dialing number * @hide */ - public void setLine1NumberForDisplayForSubscriber(long subId, String alphaTag, String number) { + public void setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number) { try { getITelephony().setLine1NumberForDisplayForSubscriber(subId, alphaTag, number); } catch (RemoteException ex) { @@ -1856,7 +1856,7 @@ public class TelephonyManager { * nobody seems to call this. */ /** {@hide} */ - public String getLine1AlphaTagForSubscriber(long subId) { + public String getLine1AlphaTagForSubscriber(int subId) { String alphaTag = null; try { alphaTag = getITelephony().getLine1AlphaTagForDisplay(subId); @@ -1899,7 +1899,7 @@ public class TelephonyManager { * @param subId for which msisdn is returned */ /** {@hide} */ - public String getMsisdn(long subId) { + public String getMsisdn(int subId) { try { return getSubscriberInfo().getMsisdnForSubscriber(subId); } catch (RemoteException ex) { @@ -1929,7 +1929,7 @@ public class TelephonyManager { * @param subId whose voice mail number is returned */ /** {@hide} */ - public String getVoiceMailNumber(long subId) { + public String getVoiceMailNumber(int subId) { try { return getSubscriberInfo().getVoiceMailNumberForSubscriber(subId); } catch (RemoteException ex) { @@ -1961,7 +1961,7 @@ public class TelephonyManager { * @param subId */ /** {@hide} */ - public String getCompleteVoiceMailNumber(long subId) { + public String getCompleteVoiceMailNumber(int subId) { try { return getSubscriberInfo().getCompleteVoiceMailNumberForSubscriber(subId); } catch (RemoteException ex) { @@ -1991,7 +1991,7 @@ public class TelephonyManager { * @param subId whose voice message count is returned */ /** {@hide} */ - public int getVoiceMessageCount(long subId) { + public int getVoiceMessageCount(int subId) { try { return getITelephony().getVoiceMessageCountForSubscriber(subId); } catch (RemoteException ex) { @@ -2023,7 +2023,7 @@ public class TelephonyManager { * voice mail number is returned */ /** {@hide} */ - public String getVoiceMailAlphaTag(long subId) { + public String getVoiceMailAlphaTag(int subId) { try { return getSubscriberInfo().getVoiceMailAlphaTagForSubscriber(subId); } catch (RemoteException ex) { @@ -2120,7 +2120,7 @@ public class TelephonyManager { * @param subId whose call state is returned */ /** {@hide} */ - public int getCallState(long subId) { + public int getCallState(int subId) { try { return getITelephony().getCallStateForSubscriber(subId); } catch (RemoteException ex) { @@ -2271,7 +2271,7 @@ public class TelephonyManager { * Returns the CDMA ERI icon index to display for a subscription */ /** {@hide} */ - public int getCdmaEriIconIndex(long subId) { + public int getCdmaEriIconIndex(int subId) { try { return getITelephony().getCdmaEriIconIndexForSubscriber(subId); } catch (RemoteException ex) { @@ -2299,7 +2299,7 @@ public class TelephonyManager { * 1 - FLASHING */ /** {@hide} */ - public int getCdmaEriIconMode(long subId) { + public int getCdmaEriIconMode(int subId) { try { return getITelephony().getCdmaEriIconModeForSubscriber(subId); } catch (RemoteException ex) { @@ -2324,7 +2324,7 @@ public class TelephonyManager { * */ /** {@hide} */ - public String getCdmaEriText(long subId) { + public String getCdmaEriText(int subId) { try { return getITelephony().getCdmaEriTextForSubscriber(subId); } catch (RemoteException ex) { @@ -2696,7 +2696,7 @@ public class TelephonyManager { /** * Returns Default subscription. */ - private static long getDefaultSubscription() { + private static int getDefaultSubscription() { return SubscriptionManager.getDefaultSubId(); } @@ -2938,7 +2938,7 @@ public class TelephonyManager { * @return the response of SIM Authentication, or null if not available * @hide */ - public String getIccSimChallengeResponse(long subId, int appType, String data) { + public String getIccSimChallengeResponse(int subId, int appType, String data) { try { return getSubscriberInfo().getIccSimChallengeResponse(subId, appType, data); } catch (RemoteException ex) { @@ -3119,7 +3119,7 @@ public class TelephonyManager { /** @hide */ @SystemApi - public String getCdmaMdn(long subId) { + public String getCdmaMdn(int subId) { try { return getITelephony().getCdmaMdn(subId); } catch (RemoteException ex) { @@ -3137,7 +3137,7 @@ public class TelephonyManager { /** @hide */ @SystemApi - public String getCdmaMin(long subId) { + public String getCdmaMin(int subId) { try { return getITelephony().getCdmaMin(subId); } catch (RemoteException ex) { @@ -3468,7 +3468,7 @@ public class TelephonyManager { * @param enable true means enabling the simplified UI. * @hide */ - public void enableSimplifiedNetworkSettingsForSubscriber(long subId, boolean enable) { + public void enableSimplifiedNetworkSettingsForSubscriber(int subId, boolean enable) { try { getITelephony().enableSimplifiedNetworkSettingsForSubscriber(subId, enable); } catch (RemoteException ex) { @@ -3501,7 +3501,7 @@ public class TelephonyManager { * @return true if the simplified UI is enabled. * @hide */ - public boolean getSimplifiedNetworkSettingsEnabledForSubscriber(long subId) { + public boolean getSimplifiedNetworkSettingsEnabledForSubscriber(int subId) { try { return getITelephony().getSimplifiedNetworkSettingsEnabledForSubscriber(subId); } catch (RemoteException ex) { @@ -3528,4 +3528,25 @@ public class TelephonyManager { } return -1; } + + /** @hide */ + @SystemApi + public void enableVideoCalling(boolean enable) { + try { + getITelephony().enableVideoCalling(enable); + } catch (RemoteException e) { + Log.e(TAG, "Error calling ITelephony#enableVideoCalling", e); + } + } + + /** @hide */ + @SystemApi + public boolean isVideoCallingEnabled() { + try { + return getITelephony().isVideoCallingEnabled(); + } catch (RemoteException e) { + Log.e(TAG, "Error calling ITelephony#isVideoCallingEnabled", e); + } + return false; + } } diff --git a/telephony/java/com/android/ims/internal/IImsCallSession.aidl b/telephony/java/com/android/ims/internal/IImsCallSession.aidl index 98b2d8a9d0bb..16b0cd5e1c95 100644 --- a/telephony/java/com/android/ims/internal/IImsCallSession.aidl +++ b/telephony/java/com/android/ims/internal/IImsCallSession.aidl @@ -160,10 +160,13 @@ interface IImsCallSession { void resume(in ImsStreamMediaProfile profile); /** - * Merges the active & hold call. When it succeeds, {@link Listener#callSessionMerged} - * is called. + * Merges the active & hold call. When the merge starts, + * {@link Listener#callSessionMergeStarted} is called. + * {@link Listener#callSessionMergeComplete} is called if the merge is successful, and + * {@link Listener#callSessionMergeFailed} is called if the merge fails. * - * @see Listener#callSessionMerged, Listener#callSessionMergeFailed + * @see Listener#callSessionMergeStarted, Listener#callSessionMergeComplete, + * Listener#callSessionMergeFailed */ void merge(); @@ -225,4 +228,10 @@ interface IImsCallSession { * intermediates between the propriety implementation and Telecomm/InCall. */ IImsVideoCallProvider getVideoCallProvider(); + + /** + * Determines if the current session is multiparty. + * @return {@code True} if the session is multiparty. + */ + boolean isMultiparty(); } diff --git a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl index 11da6e6aa547..84d1c54575f8 100644 --- a/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl +++ b/telephony/java/com/android/ims/internal/IImsCallSessionListener.aidl @@ -48,10 +48,11 @@ interface IImsCallSessionListener { void callSessionResumeReceived(in IImsCallSession session, in ImsCallProfile profile); /** - * Notifiies the result of call merge operation. + * Notifies the result of call merge operation. */ - void callSessionMerged(in IImsCallSession session, + void callSessionMergeStarted(in IImsCallSession session, in IImsCallSession newSession, in ImsCallProfile profile); + void callSessionMergeComplete(in IImsCallSession session); void callSessionMergeFailed(in IImsCallSession session, in ImsReasonInfo reasonInfo); diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java index 88e5bd60b32c..5cd5d4e8f97d 100644 --- a/telephony/java/com/android/internal/telephony/CallerInfo.java +++ b/telephony/java/com/android/internal/telephony/CallerInfo.java @@ -301,7 +301,7 @@ public class CallerInfo { public static CallerInfo getCallerInfo(Context context, String number) { if (VDBG) Rlog.v(TAG, "getCallerInfo() based on number..."); - long subId = SubscriptionManager.getDefaultSubId(); + int subId = SubscriptionManager.getDefaultSubId(); return getCallerInfo(context, number, subId); } @@ -316,7 +316,7 @@ public class CallerInfo { * a matching number is not found, then a generic caller info is returned, * with all relevant fields empty or null. */ - public static CallerInfo getCallerInfo(Context context, String number, long subId) { + public static CallerInfo getCallerInfo(Context context, String number, int subId) { if (TextUtils.isEmpty(number)) { return null; @@ -418,12 +418,12 @@ public class CallerInfo { // string in the phone number field. /* package */ CallerInfo markAsVoiceMail() { - long subId = SubscriptionManager.getDefaultSubId(); + int subId = SubscriptionManager.getDefaultSubId(); return markAsVoiceMail(subId); } - /* package */ CallerInfo markAsVoiceMail(long subId) { + /* package */ CallerInfo markAsVoiceMail(int subId) { mIsVoiceMail = true; try { diff --git a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java index 0d183896b5bf..aae7617eabe9 100644 --- a/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java +++ b/telephony/java/com/android/internal/telephony/CallerInfoAsyncQuery.java @@ -81,7 +81,7 @@ public class CallerInfoAsyncQuery { public int event; public String number; - public long subId; + public int subId; } @@ -388,7 +388,7 @@ public class CallerInfoAsyncQuery { public static CallerInfoAsyncQuery startQuery(int token, Context context, String number, OnQueryCompleteListener listener, Object cookie) { - long subId = SubscriptionManager.getDefaultSubId(); + int subId = SubscriptionManager.getDefaultSubId(); return startQuery(token, context, number, listener, cookie, subId); } @@ -404,7 +404,7 @@ public class CallerInfoAsyncQuery { * the phone type of the incoming connection. */ public static CallerInfoAsyncQuery startQuery(int token, Context context, String number, - OnQueryCompleteListener listener, Object cookie, long subId) { + OnQueryCompleteListener listener, Object cookie, int subId) { if (DBG) { Rlog.d(LOG_TAG, "##### CallerInfoAsyncQuery startQuery()... #####"); diff --git a/telephony/java/com/android/internal/telephony/DcParamObject.java b/telephony/java/com/android/internal/telephony/DcParamObject.java index 2736e6f2dcdf..139939cbd0c1 100644 --- a/telephony/java/com/android/internal/telephony/DcParamObject.java +++ b/telephony/java/com/android/internal/telephony/DcParamObject.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2014 MediaTek Inc. + * Copyright (C) 2014 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. @@ -21,9 +21,9 @@ import android.os.Parcel; public class DcParamObject implements Parcelable { - private long mSubId; + private int mSubId; - public DcParamObject(long subId) { + public DcParamObject(int subId) { mSubId = subId; } @@ -40,7 +40,7 @@ public class DcParamObject implements Parcelable { } private void readFromParcel(Parcel in) { - mSubId = in.readLong(); + mSubId = in.readInt(); } public static final Parcelable.Creator<DcParamObject> CREATOR = new Parcelable.Creator<DcParamObject>() { @@ -52,7 +52,7 @@ public class DcParamObject implements Parcelable { } }; - public long getSubId() { + public int getSubId() { return mSubId; } } diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java index defb43ba7ffc..a4e948686775 100644 --- a/telephony/java/com/android/internal/telephony/DctConstants.java +++ b/telephony/java/com/android/internal/telephony/DctConstants.java @@ -99,6 +99,7 @@ public class DctConstants { public static final int EVENT_PROVISIONING_APN_ALARM = BASE + 39; public static final int CMD_NET_STAT_POLL = BASE + 40; public static final int EVENT_DATA_RAT_CHANGED = BASE + 41; + public static final int CMD_CLEAR_PROVISIONING_SPINNER = BASE + 42; /***** Constants *****/ diff --git a/telephony/java/com/android/internal/telephony/IMms.aidl b/telephony/java/com/android/internal/telephony/IMms.aidl index ebfefd199497..032249957527 100644 --- a/telephony/java/com/android/internal/telephony/IMms.aidl +++ b/telephony/java/com/android/internal/telephony/IMms.aidl @@ -39,7 +39,7 @@ interface IMms { * @param sentIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is successfully sent, or failed */ - void sendMessage(long subId, String callingPkg, in Uri contentUri, + void sendMessage(int subId, String callingPkg, in Uri contentUri, String locationUrl, in Bundle configOverrides, in PendingIntent sentIntent); /** @@ -56,7 +56,7 @@ interface IMms { * @param downloadedIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is downloaded, or the download is failed */ - void downloadMessage(long subId, String callingPkg, String locationUrl, + void downloadMessage(int subId, String callingPkg, String locationUrl, in Uri contentUri, in Bundle configOverrides, in PendingIntent downloadedIntent); @@ -99,7 +99,7 @@ interface IMms { * * @param subId the SIM id */ - Bundle getCarrierConfigValues(long subId); + Bundle getCarrierConfigValues(int subId); /** * Import a text message into system's SMS store @@ -204,7 +204,7 @@ interface IMms { * @param sentIntent if not NULL this <code>PendingIntent</code> is * broadcast when the message is successfully sent, or failed */ - void sendStoredMessage(long subId, String callingPkg, in Uri messageUri, + void sendStoredMessage(int subId, String callingPkg, in Uri messageUri, in Bundle configOverrides, in PendingIntent sentIntent); /** diff --git a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl index 98fd70caf120..eec533383107 100644 --- a/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl +++ b/telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl @@ -30,18 +30,18 @@ interface IPhoneSubInfo { /** * Retrieves the unique Network Access ID */ - String getNaiForSubscriber(long subId); + String getNaiForSubscriber(int subId); /** * Retrieves the unique device ID of a subId for the device, e.g., IMEI * for GSM phones. */ - String getDeviceIdForSubscriber(long subId); + String getDeviceIdForSubscriber(int subId); /** * Retrieves the IMEI. */ - String getImeiForSubscriber(long subId); + String getImeiForSubscriber(int subId); /** * Retrieves the software version number for the device, e.g., IMEI/SV @@ -53,7 +53,7 @@ interface IPhoneSubInfo { * Retrieves the software version number of a subId for the device, e.g., IMEI/SV * for GSM phones. */ - String getDeviceSvnUsingSubId(long subId); + String getDeviceSvnUsingSubId(int subId); /** * Retrieves the unique sbuscriber ID, e.g., IMSI for GSM phones. @@ -63,7 +63,7 @@ interface IPhoneSubInfo { /** * Retrieves the unique subscriber ID of a given subId, e.g., IMSI for GSM phones. */ - String getSubscriberIdForSubscriber(long subId); + String getSubscriberIdForSubscriber(int subId); /** * Retrieves the Group Identifier Level1 for GSM phones. @@ -73,7 +73,7 @@ interface IPhoneSubInfo { /** * Retrieves the Group Identifier Level1 for GSM phones of a subId. */ - String getGroupIdLevel1ForSubscriber(long subId); + String getGroupIdLevel1ForSubscriber(int subId); /** * Retrieves the serial number of the ICC, if applicable. @@ -83,7 +83,7 @@ interface IPhoneSubInfo { /** * Retrieves the serial number of a given subId. */ - String getIccSerialNumberForSubscriber(long subId); + String getIccSerialNumberForSubscriber(int subId); /** * Retrieves the phone number string for line 1. @@ -93,7 +93,7 @@ interface IPhoneSubInfo { /** * Retrieves the phone number string for line 1 of a subcription. */ - String getLine1NumberForSubscriber(long subId); + String getLine1NumberForSubscriber(int subId); /** @@ -104,7 +104,7 @@ interface IPhoneSubInfo { /** * Retrieves the alpha identifier for line 1 of a subId. */ - String getLine1AlphaTagForSubscriber(long subId); + String getLine1AlphaTagForSubscriber(int subId); /** @@ -115,7 +115,7 @@ interface IPhoneSubInfo { /** * Retrieves the Msisdn of a subId. */ - String getMsisdnForSubscriber(long subId); + String getMsisdnForSubscriber(int subId); /** * Retrieves the voice mail number. @@ -125,7 +125,7 @@ interface IPhoneSubInfo { /** * Retrieves the voice mail number of a given subId. */ - String getVoiceMailNumberForSubscriber(long subId); + String getVoiceMailNumberForSubscriber(int subId); /** * Retrieves the complete voice mail number. @@ -135,7 +135,7 @@ interface IPhoneSubInfo { /** * Retrieves the complete voice mail number for particular subId */ - String getCompleteVoiceMailNumberForSubscriber(long subId); + String getCompleteVoiceMailNumberForSubscriber(int subId); /** * Retrieves the alpha identifier associated with the voice mail number. @@ -146,7 +146,7 @@ interface IPhoneSubInfo { * Retrieves the alpha identifier associated with the voice mail number * of a subId. */ - String getVoiceMailAlphaTagForSubscriber(long subId); + String getVoiceMailAlphaTagForSubscriber(int subId); /** * Returns the IMS private user identity (IMPI) that was loaded from the ISIM. @@ -199,5 +199,5 @@ interface IPhoneSubInfo { * @param data authentication challenge data * @return challenge response */ - String getIccSimChallengeResponse(long subId, int appType, String data); + String getIccSimChallengeResponse(int subId, int appType, String data); } diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl index 32bb8b491849..560af450d326 100644 --- a/telephony/java/com/android/internal/telephony/ISms.aidl +++ b/telephony/java/com/android/internal/telephony/ISms.aidl @@ -47,7 +47,7 @@ interface ISms { * @param subId the subId id. * @return list of SmsRawData of all sms on ICC */ - List<SmsRawData> getAllMessagesFromIccEfForSubscriber(in long subId, String callingPkg); + List<SmsRawData> getAllMessagesFromIccEfForSubscriber(in int subId, String callingPkg); /** * Update the specified message on the ICC. @@ -75,7 +75,7 @@ interface ISms { * @return success or not * */ - boolean updateMessageOnIccEfForSubscriber(in long subId, String callingPkg, + boolean updateMessageOnIccEfForSubscriber(in int subId, String callingPkg, int messageIndex, int newStatus, in byte[] pdu); /** @@ -99,7 +99,7 @@ interface ISms { * @return success or not * */ - boolean copyMessageToIccEfForSubscriber(in long subId, String callingPkg, int status, + boolean copyMessageToIccEfForSubscriber(in int subId, String callingPkg, int status, in byte[] pdu, in byte[] smsc); /** @@ -152,7 +152,7 @@ interface ISms { * raw pdu of the status report is in the extended data ("pdu"). * @param subId the subId id. */ - void sendDataForSubscriber(long subId, String callingPkg, in String destAddr, + void sendDataForSubscriber(int subId, String callingPkg, in String destAddr, in String scAddr, in int destPort, in byte[] data, in PendingIntent sentIntent, in PendingIntent deliveryIntent); @@ -206,7 +206,7 @@ interface ISms { * raw pdu of the status report is in the extended data ("pdu"). * @param subId the subId on which the SMS has to be sent. */ - void sendTextForSubscriber(in long subId, String callingPkg, in String destAddr, + void sendTextForSubscriber(in int subId, String callingPkg, in String destAddr, in String scAddr, in String text, in PendingIntent sentIntent, in PendingIntent deliveryIntent); @@ -283,7 +283,7 @@ interface ISms { * extended data ("pdu"). * @param subId the subId on which the SMS has to be sent. */ - void sendMultipartTextForSubscriber(in long subId, String callingPkg, + void sendMultipartTextForSubscriber(in int subId, String callingPkg, in String destinationAddress, in String scAddress, in List<String> parts, in List<PendingIntent> sentIntents, in List<PendingIntent> deliveryIntents); @@ -315,7 +315,7 @@ interface ISms { * * @see #disableCellBroadcast(int) */ - boolean enableCellBroadcastForSubscriber(in long subId, int messageIdentifier); + boolean enableCellBroadcastForSubscriber(in int subId, int messageIdentifier); /** * Disable reception of cell broadcast (SMS-CB) messages with the given @@ -344,7 +344,7 @@ interface ISms { * * @see #enableCellBroadcast(int) */ - boolean disableCellBroadcastForSubscriber(in long subId, int messageIdentifier); + boolean disableCellBroadcastForSubscriber(in int subId, int messageIdentifier); /* * Enable reception of cell broadcast (SMS-CB) messages with the given @@ -377,7 +377,7 @@ interface ISms { * * @see #disableCellBroadcastRange(int, int) */ - boolean enableCellBroadcastRangeForSubscriber(long subId, int startMessageId, int endMessageId); + boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId); /** * Disable reception of cell broadcast (SMS-CB) messages with the given @@ -410,7 +410,7 @@ interface ISms { * * @see #enableCellBroadcastRange(int, int, int) */ - boolean disableCellBroadcastRangeForSubscriber(long subId, int startMessageId, + boolean disableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId); /** @@ -423,7 +423,7 @@ interface ISms { * Returns the premium SMS send permission for the specified package. * Requires system permission. */ - int getPremiumSmsPermissionForSubscriber(long subId, String packageName); + int getPremiumSmsPermissionForSubscriber(int subId, String packageName); /** * Set the SMS send permission for the specified package. @@ -439,7 +439,7 @@ interface ISms { * Set the SMS send permission for the specified package. * Requires system permission. */ - void setPremiumSmsPermissionForSubscriber(long subId, String packageName, int permission); + void setPremiumSmsPermissionForSubscriber(int subId, String packageName, int permission); /** * SMS over IMS is supported if IMS is registered and SMS is supported @@ -459,13 +459,13 @@ interface ISms { * * @see #getImsSmsFormat() */ - boolean isImsSmsSupportedForSubscriber(long subId); + boolean isImsSmsSupportedForSubscriber(int subId); /* * get user prefered SMS subId * @return subId id */ - long getPreferredSmsSubscription(); + int getPreferredSmsSubscription(); /** * Gets SMS format supported on IMS. SMS over IMS format is @@ -489,7 +489,7 @@ interface ISms { * * @see #isImsSmsSupported() */ - String getImsSmsFormatForSubscriber(long subId); + String getImsSmsFormatForSubscriber(int subId); /* * Get SMS prompt property, enabled or not @@ -524,7 +524,7 @@ interface ISms { * broadcast when the message is delivered to the recipient. The * raw pdu of the status report is in the extended data ("pdu"). */ - void sendStoredText(long subId, String callingPkg, in Uri messageUri, String scAddress, + void sendStoredText(int subId, String callingPkg, in Uri messageUri, String scAddress, in PendingIntent sentIntent, in PendingIntent deliveryIntent); /** @@ -560,7 +560,7 @@ interface ISms { * to the recipient. The raw pdu of the status report is in the * extended data ("pdu"). */ - void sendStoredMultipartText(long subId, String callingPkg, in Uri messageUri, + void sendStoredMultipartText(int subId, String callingPkg, in Uri messageUri, String scAddress, in List<PendingIntent> sentIntents, in List<PendingIntent> deliveryIntents); } diff --git a/telephony/java/com/android/internal/telephony/ISub.aidl b/telephony/java/com/android/internal/telephony/ISub.aidl index b87365e2bd64..daf850ecc9c1 100755 --- a/telephony/java/com/android/internal/telephony/ISub.aidl +++ b/telephony/java/com/android/internal/telephony/ISub.aidl @@ -25,7 +25,7 @@ interface ISub { * @param subId The unique SubInfoRecord index in database * @return SubInfoRecord, maybe null */ - SubInfoRecord getSubInfoForSubscriber(long subId); + SubInfoRecord getSubInfoForSubscriber(int subId); /** * Get the SubInfoRecord according to an IccId @@ -79,7 +79,7 @@ interface ISub { * @param subId the unique SubInfoRecord index in database * @return the number of records updated */ - int setColor(int color, long subId); + int setColor(int color, int subId); /** * Set display name by simInfo index @@ -87,7 +87,7 @@ interface ISub { * @param subId the unique SubInfoRecord index in database * @return the number of records updated */ - int setDisplayName(String displayName, long subId); + int setDisplayName(String displayName, int subId); /** * Set display name by simInfo index with name source @@ -96,7 +96,7 @@ interface ISub { * @param nameSource, 0: DEFAULT_SOURCE, 1: SIM_SOURCE, 2: USER_INPUT * @return the number of records updated */ - int setDisplayNameUsingSrc(String displayName, long subId, long nameSource); + int setDisplayNameUsingSrc(String displayName, int subId, long nameSource); /** * Set phone number by subId @@ -104,7 +104,7 @@ interface ISub { * @param subId the unique SubInfoRecord index in database * @return the number of records updated */ - int setDisplayNumber(String number, long subId); + int setDisplayNumber(String number, int subId); /** * Set number display format. 0: none, 1: the first four digits, 2: the last four digits @@ -112,7 +112,7 @@ interface ISub { * @param subId the unique SubInfoRecord index in database * @return the number of records updated */ - int setDisplayNumberFormat(int format, long subId); + int setDisplayNumberFormat(int format, int subId); /** * Set data roaming by simInfo index @@ -120,35 +120,35 @@ interface ISub { * @param subId the unique SubInfoRecord index in database * @return the number of records updated */ - int setDataRoaming(int roaming, long subId); + int setDataRoaming(int roaming, int subId); - int getSlotId(long subId); + int getSlotId(int subId); - long[] getSubId(int slotId); + int[] getSubId(int slotId); - long getDefaultSubId(); + int getDefaultSubId(); int clearSubInfo(); - int getPhoneId(long subId); + int getPhoneId(int subId); /** * Get the default data subscription * @return Id of the data subscription */ - long getDefaultDataSubId(); + int getDefaultDataSubId(); - void setDefaultDataSubId(long subId); + void setDefaultDataSubId(int subId); - long getDefaultVoiceSubId(); + int getDefaultVoiceSubId(); - void setDefaultVoiceSubId(long subId); + void setDefaultVoiceSubId(int subId); - long getDefaultSmsSubId(); + int getDefaultSmsSubId(); - void setDefaultSmsSubId(long subId); + void setDefaultSmsSubId(int subId); void clearDefaultsForInactiveSubIds(); - long[] getActiveSubIdList(); + int[] getActiveSubIdList(); } diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl index 58807b26652f..13f0e3f32b23 100644 --- a/telephony/java/com/android/internal/telephony/ITelephony.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl @@ -28,7 +28,7 @@ import java.util.List; /** * Interface used to interact with the phone. Mostly this is used by the * TelephonyManager class. A few places are still using this directly. - * Please clean them up if possible and use TelephonyManager insteadl. + * Please clean them up if possible and use TelephonyManager instead. * * {@hide} */ @@ -60,7 +60,7 @@ interface ITelephony { * @param subId user preferred subId. * @return whether it hung up */ - boolean endCallForSubscriber(long subId); + boolean endCallForSubscriber(int subId); /** * Answer the currently-ringing call. @@ -94,7 +94,7 @@ interface ITelephony { * TODO: this should be a oneway call (especially since it's called * directly from the key queue thread). */ - void answerRingingCallForSubscriber(long subId); + void answerRingingCallForSubscriber(int subId); /** * Silence the ringer if an incoming call is currently ringing. @@ -121,7 +121,7 @@ interface ITelephony { * @param subId user preferred subId. * @return true if the phone state is OFFHOOK. */ - boolean isOffhookForSubscriber(long subId); + boolean isOffhookForSubscriber(int subId); /** * Check if an incoming phone call is ringing or call waiting @@ -130,7 +130,7 @@ interface ITelephony { * @param subId user preferred subId. * @return true if the phone state is RINGING. */ - boolean isRingingForSubscriber(long subId); + boolean isRingingForSubscriber(int subId); /** * Check if an incoming phone call is ringing or call waiting. @@ -150,7 +150,7 @@ interface ITelephony { * @param subId user preferred subId. * @return true if the phone state is IDLE. */ - boolean isIdleForSubscriber(long subId); + boolean isIdleForSubscriber(int subId); /** * Check to see if the radio is on or not. @@ -163,7 +163,7 @@ interface ITelephony { * @param subId user preferred subId. * @return returns true if the radio is on. */ - boolean isRadioOnForSubscriber(long subId); + boolean isRadioOnForSubscriber(int subId); /** * Check if the SIM pin lock is enabled. @@ -185,7 +185,7 @@ interface ITelephony { * @param subId user preferred subId. * @return whether the operation was a success. */ - boolean supplyPinForSubscriber(long subId, String pin); + boolean supplyPinForSubscriber(int subId, String pin); /** * Supply puk to unlock the SIM and set SIM pin to new pin. @@ -204,7 +204,7 @@ interface ITelephony { * @param subId user preferred subId. * @return whether the operation was a success. */ - boolean supplyPukForSubscriber(long subId, String puk, String pin); + boolean supplyPukForSubscriber(int subId, String puk, String pin); /** * Supply a pin to unlock the SIM. Blocks until a result is determined. @@ -222,7 +222,7 @@ interface ITelephony { * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code * retValue[1] = number of attempts remaining if known otherwise -1 */ - int[] supplyPinReportResultForSubscriber(long subId, String pin); + int[] supplyPinReportResultForSubscriber(int subId, String pin); /** * Supply puk to unlock the SIM and set SIM pin to new pin. @@ -244,7 +244,7 @@ interface ITelephony { * @return retValue[0] = Phone.PIN_RESULT_SUCCESS on success. Otherwise error code * retValue[1] = number of attempts remaining if known otherwise -1 */ - int[] supplyPukReportResultForSubscriber(long subId, String puk, String pin); + int[] supplyPukReportResultForSubscriber(int subId, String puk, String pin); /** * Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated @@ -263,7 +263,7 @@ interface ITelephony { * @param subId user preferred subId. * @return true if MMI command is executed. */ - boolean handlePinMmiForSubscriber(long subId, String dialString); + boolean handlePinMmiForSubscriber(int subId, String dialString); /** * Toggles the radio on or off. @@ -274,7 +274,7 @@ interface ITelephony { * Toggles the radio on or off on particular subId. * @param subId user preferred subId. */ - void toggleRadioOnOffForSubscriber(long subId); + void toggleRadioOnOffForSubscriber(int subId); /** * Set the radio to on or off @@ -285,7 +285,7 @@ interface ITelephony { * Set the radio to on or off on particular subId. * @param subId user preferred subId. */ - boolean setRadioForSubscriber(long subId, boolean turnOn); + boolean setRadioForSubscriber(int subId, boolean turnOn); /** * Set the radio to on or off unconditionally @@ -301,7 +301,7 @@ interface ITelephony { * Request to update location information for a subscrition in service state * @param subId user preferred subId. */ - void updateServiceLocationForSubscriber(long subId); + void updateServiceLocationForSubscriber(int subId); /** * Enable location update notifications. @@ -312,7 +312,7 @@ interface ITelephony { * Enable location update notifications. * @param subId user preferred subId. */ - void enableLocationUpdatesForSubscriber(long subId); + void enableLocationUpdatesForSubscriber(int subId); /** * Disable location update notifications. @@ -323,7 +323,7 @@ interface ITelephony { * Disable location update notifications. * @param subId user preferred subId. */ - void disableLocationUpdatesForSubscriber(long subId); + void disableLocationUpdatesForSubscriber(int subId); /** * Allow mobile data connections. @@ -352,7 +352,7 @@ interface ITelephony { /** * Returns the call state for a subId. */ - int getCallStateForSubscriber(long subId); + int getCallStateForSubscriber(int subId); int getDataActivity(); int getDataState(); @@ -370,7 +370,7 @@ interface ITelephony { * and TelephonyManager.PHONE_TYPE_GSM if RILConstants.GSM_PHONE * @param subId user preferred subId. */ - int getActivePhoneTypeForSubscriber(long subId); + int getActivePhoneTypeForSubscriber(int subId); /** * Returns the CDMA ERI icon index to display @@ -381,7 +381,7 @@ interface ITelephony { * Returns the CDMA ERI icon index to display on particular subId. * @param subId user preferred subId. */ - int getCdmaEriIconIndexForSubscriber(long subId); + int getCdmaEriIconIndexForSubscriber(int subId); /** * Returns the CDMA ERI icon mode, @@ -396,7 +396,7 @@ interface ITelephony { * 1 - FLASHING * @param subId user preferred subId. */ - int getCdmaEriIconModeForSubscriber(long subId); + int getCdmaEriIconModeForSubscriber(int subId); /** * Returns the CDMA ERI text, @@ -407,7 +407,7 @@ interface ITelephony { * Returns the CDMA ERI text for particular subId, * @param subId user preferred subId. */ - String getCdmaEriTextForSubscriber(long subId); + String getCdmaEriTextForSubscriber(int subId); /** * Returns true if OTA service provisioning needs to run. @@ -426,7 +426,7 @@ interface ITelephony { * @param subId user preferred subId. * Returns the unread count of voicemails */ - int getVoiceMessageCountForSubscriber(long subId); + int getVoiceMessageCountForSubscriber(int subId); /** * Returns the network type for data transmission @@ -438,7 +438,7 @@ interface ITelephony { * @param subId user preferred subId. * Returns the network type */ - int getNetworkTypeForSubscriber(long subId); + int getNetworkTypeForSubscriber(int subId); /** * Returns the network type for data transmission @@ -450,7 +450,7 @@ interface ITelephony { * @param subId user preferred subId. * Returns the network type */ - int getDataNetworkTypeForSubscriber(long subId); + int getDataNetworkTypeForSubscriber(int subId); /** * Returns the network type for voice @@ -462,7 +462,7 @@ interface ITelephony { * @param subId user preferred subId. * Returns the network type */ - int getVoiceNetworkTypeForSubscriber(long subId); + int getVoiceNetworkTypeForSubscriber(int subId); /** * Return true if an ICC card is present @@ -474,7 +474,7 @@ interface ITelephony { * @param slotId user preferred slotId. * Return true if an ICC card is present */ - boolean hasIccCardUsingSlotId(long slotId); + boolean hasIccCardUsingSlotId(int slotId); /** * Return if the current radio is LTE on CDMA. This @@ -494,7 +494,7 @@ interface ITelephony { * @return {@link Phone#LTE_ON_CDMA_UNKNOWN}, {@link Phone#LTE_ON_CDMA_FALSE} * or {@link PHone#LTE_ON_CDMA_TRUE} */ - int getLteOnCdmaModeForSubscriber(long subId); + int getLteOnCdmaModeForSubscriber(int subId); /** * Returns the all observed cell information of the device. @@ -689,13 +689,13 @@ interface ITelephony { * Return MDN string for CDMA phone. * @param subId user preferred subId. */ - String getCdmaMdn(long subId); + String getCdmaMdn(int subId); /** * Return MIN string for CDMA phone. * @param subId user preferred subId. */ - String getCdmaMin(long subId); + String getCdmaMin(int subId); /** * Has the calling application been granted special privileges by the carrier. @@ -733,7 +733,7 @@ interface ITelephony { * @param subId for which the simplified UI should be enabled or disabled. * @param enable true means enabling the simplified UI. */ - void enableSimplifiedNetworkSettingsForSubscriber(long subId, boolean enable); + void enableSimplifiedNetworkSettingsForSubscriber(int subId, boolean enable); /** * Get whether a simplified Mobile Network Settings UI is enabled for the @@ -742,7 +742,7 @@ interface ITelephony { * @param subId for which the simplified UI should be enabled or disabled. * @return true if the simplified UI is enabled. */ - boolean getSimplifiedNetworkSettingsEnabledForSubscriber(long subId); + boolean getSimplifiedNetworkSettingsEnabledForSubscriber(int subId); /** * Set the line 1 phone number string and its alphatag for the current ICCID @@ -754,7 +754,7 @@ interface ITelephony { * @param alphaTag alpha-tagging of the dailing nubmer * @param number The dialing number */ - void setLine1NumberForDisplayForSubscriber(long subId, String alphaTag, String number); + void setLine1NumberForDisplayForSubscriber(int subId, String alphaTag, String number); /** * Returns the displayed dialing number string if it was set previously via @@ -763,7 +763,7 @@ interface ITelephony { * @param subId whose dialing number for line 1 is returned. * @return the displayed dialing number if set, or null if not set. */ - String getLine1NumberForDisplay(long subId); + String getLine1NumberForDisplay(int subId); /** * Returns the displayed alphatag of the dialing number if it was set @@ -773,7 +773,7 @@ interface ITelephony { * @return the displayed alphatag of the dialing number if set, or null if * not set. */ - String getLine1AlphaTagForDisplay(long subId); + String getLine1AlphaTagForDisplay(int subId); /** * Override the operator branding for the current ICCID. @@ -831,4 +831,18 @@ interface ITelephony { * @return phone radio type and access technology */ int getRadioAccessFamily(in int phoneId); + + /** + * Enables or disables video calling. + * + * @param enable Whether to enable video calling. + */ + void enableVideoCalling(boolean enable); + + /** + * Whether video calling has been enabled by the user. + * + * @return {@code True} if the user has enabled video calling, {@code false} otherwise. + */ + boolean isVideoCallingEnabled(); } diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl index 39defcf44e85..ee3f8b0f3f68 100644 --- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl +++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl @@ -30,28 +30,28 @@ import com.android.internal.telephony.IPhoneStateListener; interface ITelephonyRegistry { void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow); - void listenForSubscriber(in long subId, String pkg, IPhoneStateListener callback, int events, + void listenForSubscriber(in int subId, String pkg, IPhoneStateListener callback, int events, boolean notifyNow); void notifyCallState(int state, String incomingNumber); - void notifyCallStateForSubscriber(in long subId, int state, String incomingNumber); - void notifyServiceStateForPhoneId(in int phoneId, in long subId, in ServiceState state); + void notifyCallStateForSubscriber(in int subId, int state, String incomingNumber); + void notifyServiceStateForPhoneId(in int phoneId, in int subId, in ServiceState state); void notifySignalStrength(in SignalStrength signalStrength); - void notifySignalStrengthForSubscriber(in long subId, in SignalStrength signalStrength); - void notifyMessageWaitingChangedForPhoneId(in int phoneId, in long subId, in boolean mwi); + void notifySignalStrengthForSubscriber(in int subId, in SignalStrength signalStrength); + void notifyMessageWaitingChangedForPhoneId(in int phoneId, in int subId, in boolean mwi); void notifyCallForwardingChanged(boolean cfi); - void notifyCallForwardingChangedForSubscriber(in long subId, boolean cfi); + void notifyCallForwardingChangedForSubscriber(in int subId, boolean cfi); void notifyDataActivity(int state); - void notifyDataActivityForSubscriber(in long subId, int state); + void notifyDataActivityForSubscriber(in int subId, int state); void notifyDataConnection(int state, boolean isDataConnectivityPossible, String reason, String apn, String apnType, in LinkProperties linkProperties, in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); - void notifyDataConnectionForSubscriber(long subId, int state, boolean isDataConnectivityPossible, + void notifyDataConnectionForSubscriber(int subId, int state, boolean isDataConnectivityPossible, String reason, String apn, String apnType, in LinkProperties linkProperties, in NetworkCapabilities networkCapabilities, int networkType, boolean roaming); void notifyDataConnectionFailed(String reason, String apnType); - void notifyDataConnectionFailedForSubscriber(long subId, String reason, String apnType); + void notifyDataConnectionFailedForSubscriber(int subId, String reason, String apnType); void notifyCellLocation(in Bundle cellLocation); - void notifyCellLocationForSubscriber(in long subId, in Bundle cellLocation); + void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation); void notifyOtaspChanged(in int otaspMode); void notifyCellInfo(in List<CellInfo> cellInfo); void notifyPreciseCallState(int ringingCallState, int foregroundCallState, @@ -59,8 +59,8 @@ interface ITelephonyRegistry { void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause); void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, String failCause); - void notifyCellInfoForSubscriber(in long subId, in List<CellInfo> cellInfo); + void notifyCellInfoForSubscriber(in int subId, in List<CellInfo> cellInfo); void notifyDataConnectionRealTimeInfo(in DataConnectionRealTimeInfo dcRtInfo); void notifyVoLteServiceStateChanged(in VoLteServiceState lteState); - void notifyOemHookRawEventForSubscriber(in long subId, in byte[] rawData); + void notifyOemHookRawEventForSubscriber(in int subId, in byte[] rawData); } diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index bc2f1fd0134f..8531944c4b8b 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -342,6 +342,24 @@ </activity> <activity + android:name="HardwareCanvasTextureViewActivity" + android:label="TextureView/HardwareCanvas"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="com.android.test.hwui.TEST" /> + </intent-filter> + </activity> + + <activity + android:name="HardwareCanvasSurfaceViewActivity" + android:label="SurfaceView/HardwareCanvas"> + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + <category android:name="com.android.test.hwui.TEST" /> + </intent-filter> + </activity> + + <activity android:name="GLTextureViewActivity" android:label="TextureView/OpenGL"> <intent-filter> diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasSurfaceViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasSurfaceViewActivity.java new file mode 100644 index 000000000000..b1431c586631 --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasSurfaceViewActivity.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2014 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.test.hwui; + +import android.app.Activity; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.os.Bundle; +import android.view.Gravity; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceHolder.Callback; +import android.view.SurfaceView; +import android.widget.FrameLayout; + +@SuppressWarnings({"UnusedDeclaration"}) +public class HardwareCanvasSurfaceViewActivity extends Activity implements Callback { + private SurfaceView mSurfaceView; + private HardwareCanvasSurfaceViewActivity.RenderingThread mThread; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + FrameLayout content = new FrameLayout(this); + + mSurfaceView = new SurfaceView(this); + mSurfaceView.getHolder().addCallback(this); + + content.addView(mSurfaceView, new FrameLayout.LayoutParams( + FrameLayout.LayoutParams.MATCH_PARENT, + FrameLayout.LayoutParams.MATCH_PARENT, + Gravity.CENTER)); + setContentView(content); + } + + @Override + public void surfaceCreated(SurfaceHolder holder) { + mThread = new RenderingThread(holder.getSurface()); + mThread.start(); + } + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + mThread.setSize(width, height); + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + if (mThread != null) mThread.stopRendering(); + } + + private static class RenderingThread extends Thread { + private final Surface mSurface; + private volatile boolean mRunning = true; + private int mWidth, mHeight; + + public RenderingThread(Surface surface) { + mSurface = surface; + } + + void setSize(int width, int height) { + mWidth = width; + mHeight = height; + } + + @Override + public void run() { + float x = 0.0f; + float y = 0.0f; + float speedX = 5.0f; + float speedY = 3.0f; + + Paint paint = new Paint(); + paint.setColor(0xff00ff00); + + while (mRunning && !Thread.interrupted()) { + final Canvas canvas = mSurface.lockHardwareCanvas(); + try { + canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR); + canvas.drawRect(x, y, x + 20.0f, y + 20.0f, paint); + } finally { + mSurface.unlockCanvasAndPost(canvas); + } + + if (x + 20.0f + speedX >= mWidth || x + speedX <= 0.0f) { + speedX = -speedX; + } + if (y + 20.0f + speedY >= mHeight || y + speedY <= 0.0f) { + speedY = -speedY; + } + + x += speedX; + y += speedY; + + try { + Thread.sleep(15); + } catch (InterruptedException e) { + // Interrupted + } + } + } + + void stopRendering() { + interrupt(); + mRunning = false; + } + } +} diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasTextureViewActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasTextureViewActivity.java new file mode 100644 index 000000000000..63a6efa712fb --- /dev/null +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/HardwareCanvasTextureViewActivity.java @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2014 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.test.hwui; + +import android.app.Activity; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.PorterDuff; +import android.graphics.SurfaceTexture; +import android.os.Bundle; +import android.view.Gravity; +import android.view.Surface; +import android.view.TextureView; +import android.widget.FrameLayout; + +@SuppressWarnings({"UnusedDeclaration"}) +public class HardwareCanvasTextureViewActivity extends Activity + implements TextureView.SurfaceTextureListener { + private TextureView mTextureView; + private HardwareCanvasTextureViewActivity.RenderingThread mThread; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + FrameLayout content = new FrameLayout(this); + + mTextureView = new TextureView(this); + mTextureView.setSurfaceTextureListener(this); + mTextureView.setOpaque(false); + + content.addView(mTextureView, new FrameLayout.LayoutParams(500, 500, Gravity.CENTER)); + setContentView(content); + } + + @Override + public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { + mThread = new RenderingThread(mTextureView); + mThread.start(); + } + + @Override + public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { + // Ignored + } + + @Override + public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { + if (mThread != null) mThread.stopRendering(); + return true; + } + + @Override + public void onSurfaceTextureUpdated(SurfaceTexture surface) { + // Ignored + } + + private static class RenderingThread extends Thread { + private final TextureView mView; + private final Surface mSurface; + private volatile boolean mRunning = true; + + public RenderingThread(TextureView view) { + mView = view; + mSurface = new Surface(mView.getSurfaceTexture()); + } + + @Override + public void run() { + float x = 0.0f; + float y = 0.0f; + float speedX = 5.0f; + float speedY = 3.0f; + + Paint paint = new Paint(); + paint.setColor(0xff00ff00); + + while (mRunning && !Thread.interrupted()) { + final Canvas canvas = mSurface.lockHardwareCanvas(); + try { + canvas.drawColor(0x00000000, PorterDuff.Mode.CLEAR); + canvas.drawRect(x, y, x + 20.0f, y + 20.0f, paint); + } finally { + mSurface.unlockCanvasAndPost(canvas); + } + + if (x + 20.0f + speedX >= mView.getWidth() || x + speedX <= 0.0f) { + speedX = -speedX; + } + if (y + 20.0f + speedY >= mView.getHeight() || y + speedY <= 0.0f) { + speedY = -speedY; + } + + x += speedX; + y += speedY; + + try { + Thread.sleep(15); + } catch (InterruptedException e) { + // Interrupted + } + } + } + + void stopRendering() { + interrupt(); + mRunning = false; + } + } +} diff --git a/tools/aapt/AaptAssets.cpp b/tools/aapt/AaptAssets.cpp index 117fc2435076..b7f64f63fdbc 100644 --- a/tools/aapt/AaptAssets.cpp +++ b/tools/aapt/AaptAssets.cpp @@ -1141,9 +1141,10 @@ bail: ssize_t AaptAssets::slurpFullTree(Bundle* bundle, const String8& srcDir, const AaptGroupEntry& kind, const String8& resType, - sp<FilePathStore>& fullResPaths) + sp<FilePathStore>& fullResPaths, + const bool overwrite) { - ssize_t res = AaptDir::slurpFullTree(bundle, srcDir, kind, resType, fullResPaths); + ssize_t res = AaptDir::slurpFullTree(bundle, srcDir, kind, resType, fullResPaths, overwrite); if (res > 0) { mGroupEntries.add(kind); } diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h index d809c5b3003c..7ae5368d80bd 100644 --- a/tools/aapt/AaptAssets.h +++ b/tools/aapt/AaptAssets.h @@ -591,7 +591,8 @@ private: const String8& srcDir, const AaptGroupEntry& kind, const String8& resType, - sp<FilePathStore>& fullResPaths); + sp<FilePathStore>& fullResPaths, + const bool overwrite=false); ssize_t slurpResourceTree(Bundle* bundle, const String8& srcDir); ssize_t slurpResourceZip(Bundle* bundle, const char* filename); diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp index 1e9e3e20ddf8..f5f70c5cf2ed 100644 --- a/tools/aapt/Command.cpp +++ b/tools/aapt/Command.cpp @@ -307,6 +307,7 @@ enum { PUBLIC_KEY_ATTR = 0x010103a6, CATEGORY_ATTR = 0x010103e8, BANNER_ATTR = 0x10103f2, + ISGAME_ATTR = 0x10103f4, }; String8 getComponentName(String8 &pkgName, String8 &componentName) { @@ -1127,13 +1128,35 @@ int doDump(Bundle* bundle) error.string()); goto bail; } + + String8 banner = AaptXml::getResolvedAttribute(res, tree, BANNER_ATTR, &error); + if (error != "") { + fprintf(stderr, "ERROR getting 'android:banner' attribute: %s\n", + error.string()); + goto bail; + } printf("application: label='%s' ", ResTable::normalizeForOutput(label.string()).string()); - printf("icon='%s'\n", ResTable::normalizeForOutput(icon.string()).string()); + printf("icon='%s'", ResTable::normalizeForOutput(icon.string()).string()); + if (banner != "") { + printf(" banner='%s'", ResTable::normalizeForOutput(banner.string()).string()); + } + printf("\n"); if (testOnly != 0) { printf("testOnly='%d'\n", testOnly); } + int32_t isGame = AaptXml::getResolvedIntegerAttribute(res, tree, + ISGAME_ATTR, 0, &error); + if (error != "") { + fprintf(stderr, "ERROR getting 'android:isGame' attribute: %s\n", + error.string()); + goto bail; + } + if (isGame != 0) { + printf("application-isGame\n"); + } + int32_t debuggable = AaptXml::getResolvedIntegerAttribute(res, tree, DEBUGGABLE_ATTR, 0, &error); if (error != "") { diff --git a/tools/aapt/ConfigDescription.h b/tools/aapt/ConfigDescription.h index 779c423fce1a..4f999a2ff0c6 100644 --- a/tools/aapt/ConfigDescription.h +++ b/tools/aapt/ConfigDescription.h @@ -28,10 +28,12 @@ struct ConfigDescription : public android::ResTable_config { memset(this, 0, sizeof(*this)); size = sizeof(android::ResTable_config); } + ConfigDescription(const android::ResTable_config&o) { *static_cast<android::ResTable_config*>(this) = o; size = sizeof(android::ResTable_config); } + ConfigDescription(const ConfigDescription&o) { *static_cast<android::ResTable_config*>(this) = o; } @@ -41,6 +43,7 @@ struct ConfigDescription : public android::ResTable_config { size = sizeof(android::ResTable_config); return *this; } + ConfigDescription& operator=(const ConfigDescription& o) { *static_cast<android::ResTable_config*>(this) = o; return *this; diff --git a/tools/aapt/ResourceIdCache.cpp b/tools/aapt/ResourceIdCache.cpp index d60a07fc243b..8835fb0130a3 100644 --- a/tools/aapt/ResourceIdCache.cpp +++ b/tools/aapt/ResourceIdCache.cpp @@ -9,8 +9,6 @@ #include <utils/Log.h> #include "ResourceIdCache.h" #include <map> -using namespace std; - static size_t mHits = 0; static size_t mMisses = 0; @@ -29,7 +27,7 @@ struct CacheEntry { CacheEntry(const android::String16& name, uint32_t resId) : hashedName(name), id(resId) { } }; -static map< uint32_t, CacheEntry > mIdMap; +static std::map< uint32_t, CacheEntry > mIdMap; // djb2; reasonable choice for strings when collisions aren't particularly important @@ -63,7 +61,7 @@ uint32_t ResourceIdCache::lookup(const android::String16& package, bool onlyPublic) { const String16 hashedName = makeHashableName(package, type, name, onlyPublic); const uint32_t hashcode = hash(hashedName); - map<uint32_t, CacheEntry>::iterator item = mIdMap.find(hashcode); + std::map<uint32_t, CacheEntry>::iterator item = mIdMap.find(hashcode); if (item == mIdMap.end()) { // cache miss mMisses++; diff --git a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java index bef5181339b8..49932620054e 100644 --- a/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/FontFamily_Delegate.java @@ -213,6 +213,10 @@ public class FontFamily_Delegate { return null; } + @Nullable + /*package*/ static String getFontLocation() { + return sFontLocation; + } // ---- native methods ---- diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java index 276e134f3785..b9460b4c4d92 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java @@ -27,6 +27,8 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import static android.graphics.FontFamily_Delegate.getFontLocation; + /** * Delegate implementing the native methods of android.graphics.Typeface * @@ -48,8 +50,6 @@ public final class Typeface_Delegate { private static final DelegateManager<Typeface_Delegate> sManager = new DelegateManager<Typeface_Delegate>(Typeface_Delegate.class); - // ---- delegate helper data ---- - private static String sFontLocation; // ---- delegate data ---- @@ -61,11 +61,8 @@ public final class Typeface_Delegate { private static long sDefaultTypeface; + // ---- Public Helper methods ---- - public static synchronized void setFontLocation(String fontLocation) { - sFontLocation = fontLocation; - FontFamily_Delegate.setFontLocation(fontLocation); - } public static Typeface_Delegate getDelegate(long nativeTypeface) { return sManager.getDelegate(nativeTypeface); @@ -131,6 +128,18 @@ public final class Typeface_Delegate { return fonts; } + /** + * Clear the default typefaces when disposing bridge. + */ + public static void resetDefaults() { + // Sometimes this is called before the Bridge is initialized. In that case, we don't want to + // initialize Typeface because the SDK fonts location hasn't been set. + if (FontFamily_Delegate.getFontLocation() != null) { + Typeface.sDefaults = null; + } + } + + // ---- native methods ---- @LayoutlibDelegate @@ -193,7 +202,7 @@ public final class Typeface_Delegate { @LayoutlibDelegate /*package*/ static File getSystemFontConfigLocation() { - return new File(sFontLocation); + return new File(getFontLocation()); } // ---- Private delegate/helper methods ---- 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 3d0e1e8f7034..825731b57996 100644 --- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java +++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java @@ -38,7 +38,7 @@ import com.ibm.icu.util.ULocale; import android.content.res.BridgeAssetManager; import android.graphics.Bitmap; -import android.graphics.Typeface_Accessor; +import android.graphics.FontFamily_Delegate; import android.graphics.Typeface_Delegate; import android.os.Looper; import android.os.Looper_Accessor; @@ -250,7 +250,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { } // load the fonts. - Typeface_Delegate.setFontLocation(fontLocation.getAbsolutePath()); + FontFamily_Delegate.setFontLocation(fontLocation.getAbsolutePath()); // now parse com.android.internal.R (and only this one as android.R is a subset of // the internal version), and put the content in the maps. @@ -303,7 +303,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge { BridgeAssetManager.clearSystem(); // dispose of the default typeface. - Typeface_Accessor.resetDefaults(); + Typeface_Delegate.resetDefaults(); return true; } diff --git a/tools/split-select/Abi.cpp b/tools/split-select/Abi.cpp new file mode 100644 index 000000000000..20654b613384 --- /dev/null +++ b/tools/split-select/Abi.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2014 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 "Abi.h" + +namespace split { +namespace abi { + +static const std::vector<Variant> sNoneVariants = {}; +static const std::vector<Variant> sArmVariants = + {Variant::armeabi, Variant::armeabi_v7a, Variant::arm64_v8a}; +static const std::vector<Variant> sIntelVariants = {Variant::x86, Variant::x86_64}; +static const std::vector<Variant> sMipsVariants = {Variant::mips, Variant::mips64}; + +Family getFamily(Variant variant) { + switch (variant) { + case Variant::none: + return Family::none; + case Variant::armeabi: + case Variant::armeabi_v7a: + case Variant::arm64_v8a: + return Family::arm; + case Variant::x86: + case Variant::x86_64: + return Family::intel; + case Variant::mips: + case Variant::mips64: + return Family::mips; + } + return Family::none; +} + +const std::vector<Variant>& getVariants(Family family) { + switch (family) { + case Family::none: + return sNoneVariants; + case Family::arm: + return sArmVariants; + case Family::intel: + return sIntelVariants; + case Family::mips: + return sMipsVariants; + } + return sNoneVariants; +} + +const char* toString(Variant variant) { + switch (variant) { + case Variant::none: + return ""; + case Variant::armeabi: + return "armeabi"; + case Variant::armeabi_v7a: + return "armeabi-v7a"; + case Variant::arm64_v8a: + return "arm64-v8a"; + case Variant::x86: + return "x86"; + case Variant::x86_64: + return "x86_64"; + case Variant::mips: + return "mips"; + case Variant::mips64: + return "mips64"; + } + return ""; +} + +} // namespace abi +} // namespace split diff --git a/tools/split-select/Abi.h b/tools/split-select/Abi.h new file mode 100644 index 000000000000..3e00eba547ec --- /dev/null +++ b/tools/split-select/Abi.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2014 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 H_ANDROID_SPLIT_ABI +#define H_ANDROID_SPLIT_ABI + +#include <vector> + +namespace split { +namespace abi { + +enum class Variant { + none = 0, + armeabi, + armeabi_v7a, + arm64_v8a, + x86, + x86_64, + mips, + mips64, +}; + +enum class Family { + none, + arm, + intel, + mips, +}; + +Family getFamily(Variant variant); +const std::vector<Variant>& getVariants(Family family); +const char* toString(Variant variant); + +} // namespace abi +} // namespace split + +#endif // H_ANDROID_SPLIT_ABI diff --git a/tools/split-select/Android.mk b/tools/split-select/Android.mk new file mode 100644 index 000000000000..d0b72877e5b6 --- /dev/null +++ b/tools/split-select/Android.mk @@ -0,0 +1,119 @@ +# +# Copyright (C) 2014 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This tool is prebuilt if we're doing an app-only build. +ifeq ($(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)),) + +# TODO(adamlesinski): Enable OS X builds when I figure out how +# to build with clang and libc++ +ifneq ($(HOST_OS),darwin) + +# ========================================================== +# Setup some common variables for the different build +# targets here. +# ========================================================== +LOCAL_PATH:= $(call my-dir) + +main := Main.cpp +sources := \ + Abi.cpp \ + Grouper.cpp \ + Rule.cpp \ + RuleGenerator.cpp \ + SplitDescription.cpp + +testSources := \ + Grouper_test.cpp \ + Rule_test.cpp \ + RuleGenerator_test.cpp + +cIncludes := \ + external/zlib \ + frameworks/base/tools + +hostLdLibs := +hostStaticLibs := \ + libaapt \ + libandroidfw \ + libpng \ + liblog \ + libutils \ + libcutils \ + libexpat \ + libziparchive-host + +cFlags := -std=c++11 -Wall -Werror + +ifeq ($(HOST_OS),linux) + hostLdLibs += -lrt -ldl -lpthread +endif + +# Statically link libz for MinGW (Win SDK under Linux), +# and dynamically link for all others. +ifneq ($(strip $(USE_MINGW)),) + hostStaticLibs += libz +else + hostLdLibs += -lz +endif + + +# ========================================================== +# Build the host static library: libsplit-select +# ========================================================== +include $(CLEAR_VARS) +LOCAL_MODULE := libsplit-select + +LOCAL_SRC_FILES := $(sources) + +LOCAL_C_INCLUDES += $(cIncludes) +LOCAL_CFLAGS += $(cFlags) -D_DARWIN_UNLIMITED_STREAMS + +include $(BUILD_HOST_STATIC_LIBRARY) + + +# ========================================================== +# Build the host tests: libsplit-select_tests +# ========================================================== +include $(CLEAR_VARS) +LOCAL_MODULE := libsplit-select_tests +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(testSources) + +LOCAL_C_INCLUDES += $(cIncludes) +LOCAL_STATIC_LIBRARIES += libsplit-select $(hostStaticLibs) +LOCAL_LDLIBS += $(hostLdLibs) +LOCAL_CFLAGS += $(cFlags) + +include $(BUILD_HOST_NATIVE_TEST) + +# ========================================================== +# Build the host executable: split-select +# ========================================================== +include $(CLEAR_VARS) +LOCAL_MODULE := split-select + +LOCAL_SRC_FILES := $(main) + +LOCAL_C_INCLUDES += $(cIncludes) +LOCAL_STATIC_LIBRARIES += libsplit-select $(hostStaticLibs) +LOCAL_LDLIBS += $(hostLdLibs) +LOCAL_CFLAGS += $(cFlags) + +include $(BUILD_HOST_EXECUTABLE) + +endif # Not OS X +endif # No TARGET_BUILD_APPS or TARGET_BUILD_PDK diff --git a/tools/split-select/Grouper.cpp b/tools/split-select/Grouper.cpp new file mode 100644 index 000000000000..15edf89bd60f --- /dev/null +++ b/tools/split-select/Grouper.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2014 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 "Grouper.h" + +#include "SplitDescription.h" + +#include <utils/KeyedVector.h> +#include <utils/Vector.h> + +using namespace android; + +namespace split { + +template <typename Key, typename Value> +static void addToVector(KeyedVector<Key, SortedVector<Value> >& group, + const Key& key, const Value& value) { + ssize_t idx = group.indexOfKey(key); + if (idx < 0) { + idx = group.add(key, SortedVector<Value>()); + } + group.editValueAt(idx).add(value); +} + +Vector<SortedVector<SplitDescription> > +groupByMutualExclusivity(const Vector<SplitDescription>& splits) { + Vector<SortedVector<SplitDescription> > groups; + + // Find mutually exclusive splits and group them. + KeyedVector<SplitDescription, SortedVector<SplitDescription> > densityGroups; + KeyedVector<SplitDescription, SortedVector<SplitDescription> > abiGroups; + KeyedVector<SplitDescription, SortedVector<SplitDescription> > localeGroups; + for (const SplitDescription& split : splits) { + if (split.config.density != 0) { + SplitDescription key(split); + key.config.density = 0; + key.config.sdkVersion = 0; // Ignore density so we can support anydpi. + addToVector(densityGroups, key, split); + } else if (split.abi != abi::Variant::none) { + SplitDescription key(split); + key.abi = abi::Variant::none; + addToVector(abiGroups, key, split); + } else if (split.config.locale != 0) { + SplitDescription key(split); + key.config.clearLocale(); + addToVector(localeGroups, key, split); + } else { + groups.add(); + groups.editTop().add(split); + } + } + + const size_t densityCount = densityGroups.size(); + for (size_t i = 0; i < densityCount; i++) { + groups.add(densityGroups[i]); + } + + const size_t abiCount = abiGroups.size(); + for (size_t i = 0; i < abiCount; i++) { + groups.add(abiGroups[i]); + } + + const size_t localeCount = localeGroups.size(); + for (size_t i = 0; i < localeCount; i++) { + groups.add(localeGroups[i]); + } + return groups; +} + +} // namespace split diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java b/tools/split-select/Grouper.h index adad2ac55f27..5cb0b5b862df 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Accessor.java +++ b/tools/split-select/Grouper.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2011 The Android Open Source Project + * Copyright (C) 2014 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,14 +14,19 @@ * limitations under the License. */ -package android.graphics; +#ifndef H_ANDROID_SPLIT_GROUPER +#define H_ANDROID_SPLIT_GROUPER -/** - * Class allowing access to package-protected methods/fields. - */ -public class Typeface_Accessor { +#include "SplitDescription.h" + +#include <utils/SortedVector.h> +#include <utils/Vector.h> + +namespace split { + +android::Vector<android::SortedVector<SplitDescription> > +groupByMutualExclusivity(const android::Vector<SplitDescription>& splits); + +} // namespace split - public static void resetDefaults() { - Typeface.sDefaults = null; - } -} +#endif // H_ANDROID_SPLIT_GROUPER diff --git a/tools/split-select/Grouper_test.cpp b/tools/split-select/Grouper_test.cpp new file mode 100644 index 000000000000..4d146cdd8ed1 --- /dev/null +++ b/tools/split-select/Grouper_test.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2014 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 "Grouper.h" + +#include "SplitDescription.h" + +#include <gtest/gtest.h> +#include <initializer_list> +#include <utils/String8.h> +#include <utils/Vector.h> + +using namespace android; + +namespace split { + +class GrouperTest : public ::testing::Test { +protected: + virtual void SetUp() { + Vector<SplitDescription> splits; + addSplit(splits, "en-rUS-sw600dp-hdpi"); + addSplit(splits, "fr-rFR-sw600dp-hdpi"); + addSplit(splits, "fr-rFR-sw600dp-xhdpi"); + addSplit(splits, ":armeabi"); + addSplit(splits, "en-rUS-sw300dp-xhdpi"); + addSplit(splits, "large"); + addSplit(splits, "pl-rPL"); + addSplit(splits, "xlarge"); + addSplit(splits, "en-rUS-sw600dp-xhdpi"); + addSplit(splits, "en-rUS-sw300dp-hdpi"); + addSplit(splits, "xxhdpi"); + addSplit(splits, "hdpi"); + addSplit(splits, "de-rDE"); + addSplit(splits, "xhdpi"); + addSplit(splits, ":x86"); + addSplit(splits, "anydpi"); + addSplit(splits, "v7"); + addSplit(splits, "v8"); + addSplit(splits, "sw600dp"); + addSplit(splits, "sw300dp"); + mGroups = groupByMutualExclusivity(splits); + } + + void addSplit(Vector<SplitDescription>& splits, const char* str); + void expectHasGroupWithSplits(std::initializer_list<const char*> l); + + Vector<SortedVector<SplitDescription> > mGroups; +}; + +TEST_F(GrouperTest, shouldHaveCorrectNumberOfGroups) { + EXPECT_EQ(12u, mGroups.size()); +} + +TEST_F(GrouperTest, shouldGroupDensities) { + expectHasGroupWithSplits({"en-rUS-sw300dp-hdpi", "en-rUS-sw300dp-xhdpi"}); + expectHasGroupWithSplits({"en-rUS-sw600dp-hdpi", "en-rUS-sw600dp-xhdpi"}); + expectHasGroupWithSplits({"fr-rFR-sw600dp-hdpi", "fr-rFR-sw600dp-xhdpi"}); + expectHasGroupWithSplits({"hdpi", "xhdpi", "xxhdpi", "anydpi"}); +} + +TEST_F(GrouperTest, shouldGroupAbi) { + expectHasGroupWithSplits({":armeabi", ":x86"}); +} + +TEST_F(GrouperTest, shouldGroupLocale) { + expectHasGroupWithSplits({"pl-rPL", "de-rDE"}); +} + +TEST_F(GrouperTest, shouldGroupEachSplitIntoItsOwnGroup) { + expectHasGroupWithSplits({"large"}); + expectHasGroupWithSplits({"xlarge"}); + expectHasGroupWithSplits({"v7"}); + expectHasGroupWithSplits({"v8"}); + expectHasGroupWithSplits({"sw600dp"}); + expectHasGroupWithSplits({"sw300dp"}); +} + +// +// Helper methods +// + +void GrouperTest::expectHasGroupWithSplits(std::initializer_list<const char*> l) { + Vector<SplitDescription> splits; + for (const char* str : l) { + splits.add(); + if (!SplitDescription::parse(String8(str), &splits.editTop())) { + ADD_FAILURE() << "Failed to parse SplitDescription " << str; + return; + } + } + const size_t splitCount = splits.size(); + + const size_t groupCount = mGroups.size(); + for (size_t i = 0; i < groupCount; i++) { + const SortedVector<SplitDescription>& group = mGroups[i]; + if (group.size() != splitCount) { + continue; + } + + size_t found = 0; + for (size_t j = 0; j < splitCount; j++) { + if (group.indexOf(splits[j]) >= 0) { + found++; + } + } + + if (found == splitCount) { + return; + } + } + + String8 errorMessage("Failed to find expected group ["); + for (size_t i = 0; i < splitCount; i++) { + if (i != 0) { + errorMessage.append(", "); + } + errorMessage.append(splits[i].toString()); + } + errorMessage.append("].\nActual:\n"); + + for (size_t i = 0; i < groupCount; i++) { + errorMessage.appendFormat("Group %d:\n", int(i + 1)); + const SortedVector<SplitDescription>& group = mGroups[i]; + for (size_t j = 0; j < group.size(); j++) { + errorMessage.append(" "); + errorMessage.append(group[j].toString()); + errorMessage.append("\n"); + } + } + ADD_FAILURE() << errorMessage.string(); +} + +void GrouperTest::addSplit(Vector<SplitDescription>& splits, const char* str) { + splits.add(); + EXPECT_TRUE(SplitDescription::parse(String8(str), &splits.editTop())); +} + +} // namespace split diff --git a/tools/split-select/Main.cpp b/tools/split-select/Main.cpp new file mode 100644 index 000000000000..d6251c3c1511 --- /dev/null +++ b/tools/split-select/Main.cpp @@ -0,0 +1,314 @@ +/* + * Copyright (C) 2014 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 <algorithm> +#include <cstdio> + +#include "aapt/AaptUtil.h" + +#include "Grouper.h" +#include "Rule.h" +#include "RuleGenerator.h" +#include "SplitDescription.h" + +#include <androidfw/AssetManager.h> +#include <androidfw/ResourceTypes.h> +#include <utils/KeyedVector.h> +#include <utils/Vector.h> + +using namespace android; + +namespace split { + +static void usage() { + fprintf(stderr, + "split-select --help\n" + "split-select --target <config> --split <path/to/apk> [--split <path/to/apk> [...]]\n" + "split-select --generate --split <path/to/apk> [--split <path/to/apk> [...]]\n" + "\n" + " --help Displays more information about this program.\n" + " --target <config> Performs the Split APK selection on the given configuration.\n" + " --generate Generates the logic for selecting the Split APK, in JSON format.\n" + " --split <path/to/apk> Includes a Split APK in the selection process.\n" + "\n" + " Where <config> is an extended AAPT resource qualifier of the form\n" + " 'resource-qualifiers:extended-qualifiers', where 'resource-qualifiers' is an AAPT resource\n" + " qualifier (ex: en-rUS-sw600dp-xhdpi), and 'extended-qualifiers' is an ordered list of one\n" + " qualifier (or none) from each category:\n" + " Architecture: armeabi, armeabi-v7a, arm64-v8a, x86, x86_64, mips\n"); +} + +static void help() { + usage(); + fprintf(stderr, "\n" + " Generates the logic for selecting a Split APK given some target Android device configuration.\n" + " Using the flag --generate will emit a JSON encoded tree of rules that must be satisfied in order\n" + " to install the given Split APK. Using the flag --target along with the device configuration\n" + " will emit the set of Split APKs to install, following the same logic that would have been emitted\n" + " via JSON.\n"); +} + +class SplitSelector { +public: + SplitSelector() = default; + SplitSelector(const Vector<SplitDescription>& splits); + + Vector<SplitDescription> getBestSplits(const SplitDescription& target) const; + + template <typename RuleGenerator> + KeyedVector<SplitDescription, sp<Rule> > getRules() const; + +private: + Vector<SortedVector<SplitDescription> > mGroups; +}; + +SplitSelector::SplitSelector(const Vector<SplitDescription>& splits) + : mGroups(groupByMutualExclusivity(splits)) { +} + +static void selectBestFromGroup(const SortedVector<SplitDescription>& splits, + const SplitDescription& target, Vector<SplitDescription>& splitsOut) { + SplitDescription bestSplit; + bool isSet = false; + const size_t splitCount = splits.size(); + for (size_t j = 0; j < splitCount; j++) { + const SplitDescription& thisSplit = splits[j]; + if (!thisSplit.match(target)) { + continue; + } + + if (!isSet || thisSplit.isBetterThan(bestSplit, target)) { + isSet = true; + bestSplit = thisSplit; + } + } + + if (isSet) { + splitsOut.add(bestSplit); + } +} + +Vector<SplitDescription> SplitSelector::getBestSplits(const SplitDescription& target) const { + Vector<SplitDescription> bestSplits; + const size_t groupCount = mGroups.size(); + for (size_t i = 0; i < groupCount; i++) { + selectBestFromGroup(mGroups[i], target, bestSplits); + } + return bestSplits; +} + +template <typename RuleGenerator> +KeyedVector<SplitDescription, sp<Rule> > SplitSelector::getRules() const { + KeyedVector<SplitDescription, sp<Rule> > rules; + + const size_t groupCount = mGroups.size(); + for (size_t i = 0; i < groupCount; i++) { + const SortedVector<SplitDescription>& splits = mGroups[i]; + const size_t splitCount = splits.size(); + for (size_t j = 0; j < splitCount; j++) { + sp<Rule> rule = Rule::simplify(RuleGenerator::generate(splits, j)); + if (rule != NULL) { + rules.add(splits[j], rule); + } + } + } + return rules; +} + +Vector<SplitDescription> select(const SplitDescription& target, const Vector<SplitDescription>& splits) { + const SplitSelector selector(splits); + return selector.getBestSplits(target); +} + +void generate(const KeyedVector<String8, Vector<SplitDescription> >& splits) { + Vector<SplitDescription> allSplits; + const size_t apkSplitCount = splits.size(); + for (size_t i = 0; i < apkSplitCount; i++) { + allSplits.appendVector(splits[i]); + } + const SplitSelector selector(allSplits); + KeyedVector<SplitDescription, sp<Rule> > rules(selector.getRules<RuleGenerator>()); + + fprintf(stdout, "[\n"); + for (size_t i = 0; i < apkSplitCount; i++) { + sp<Rule> masterRule = new Rule(); + masterRule->op = Rule::OR_SUBRULES; + const Vector<SplitDescription>& splitDescriptions = splits[i]; + const size_t splitDescriptionCount = splitDescriptions.size(); + for (size_t j = 0; j < splitDescriptionCount; j++) { + masterRule->subrules.add(rules.valueFor(splitDescriptions[j])); + } + masterRule = Rule::simplify(masterRule); + fprintf(stdout, " {\n \"path\": \"%s\",\n \"rules\": %s\n }%s\n", + splits.keyAt(i).string(), + masterRule->toJson(2).string(), + i < apkSplitCount - 1 ? "," : ""); + } + fprintf(stdout, "]\n"); +} + +static void removeRuntimeQualifiers(ConfigDescription* outConfig) { + outConfig->imsi = 0; + outConfig->orientation = ResTable_config::ORIENTATION_ANY; + outConfig->screenWidth = ResTable_config::SCREENWIDTH_ANY; + outConfig->screenHeight = ResTable_config::SCREENHEIGHT_ANY; + outConfig->uiMode &= ResTable_config::UI_MODE_NIGHT_ANY; +} + +static Vector<SplitDescription> extractSplitDescriptionsFromApk(const String8& path) { + AssetManager assetManager; + Vector<SplitDescription> splits; + int32_t cookie = 0; + if (!assetManager.addAssetPath(path, &cookie)) { + return splits; + } + + const ResTable& res = assetManager.getResources(false); + if (res.getError() == NO_ERROR) { + Vector<ResTable_config> configs; + res.getConfigurations(&configs); + const size_t configCount = configs.size(); + for (size_t i = 0; i < configCount; i++) { + splits.add(); + splits.editTop().config = configs[i]; + } + } + + AssetDir* dir = assetManager.openNonAssetDir(cookie, "lib"); + if (dir != NULL) { + const size_t fileCount = dir->getFileCount(); + for (size_t i = 0; i < fileCount; i++) { + splits.add(); + Vector<String8> parts = AaptUtil::splitAndLowerCase(dir->getFileName(i), '-'); + if (parseAbi(parts, 0, &splits.editTop()) < 0) { + fprintf(stderr, "Malformed library %s\n", dir->getFileName(i).string()); + splits.pop(); + } + } + delete dir; + } + return splits; +} + +static int main(int argc, char** argv) { + // Skip over the first argument. + argc--; + argv++; + + bool generateFlag = false; + String8 targetConfigStr; + Vector<String8> splitApkPaths; + while (argc > 0) { + const String8 arg(*argv); + if (arg == "--target") { + argc--; + argv++; + if (argc < 1) { + fprintf(stderr, "Missing parameter for --split.\n"); + usage(); + return 1; + } + targetConfigStr.setTo(*argv); + } else if (arg == "--split") { + argc--; + argv++; + if (argc < 1) { + fprintf(stderr, "Missing parameter for --split.\n"); + usage(); + return 1; + } + splitApkPaths.add(String8(*argv)); + } else if (arg == "--generate") { + generateFlag = true; + } else if (arg == "--help") { + help(); + return 0; + } else { + fprintf(stderr, "Unknown argument '%s'\n", arg.string()); + usage(); + return 1; + } + argc--; + argv++; + } + + if (!generateFlag && targetConfigStr == "") { + usage(); + return 1; + } + + if (splitApkPaths.size() == 0) { + usage(); + return 1; + } + + SplitDescription targetSplit; + if (!generateFlag) { + if (!SplitDescription::parse(targetConfigStr, &targetSplit)) { + fprintf(stderr, "Invalid --target config: '%s'\n", + targetConfigStr.string()); + usage(); + return 1; + } + + // We don't want to match on things that will change at run-time + // (orientation, w/h, etc.). + removeRuntimeQualifiers(&targetSplit.config); + } + + KeyedVector<String8, Vector<SplitDescription> > apkPathSplitMap; + KeyedVector<SplitDescription, String8> splitApkPathMap; + Vector<SplitDescription> splitConfigs; + const size_t splitCount = splitApkPaths.size(); + for (size_t i = 0; i < splitCount; i++) { + Vector<SplitDescription> splits = extractSplitDescriptionsFromApk(splitApkPaths[i]); + if (splits.isEmpty()) { + fprintf(stderr, "Invalid --split path: '%s'. No splits found.\n", + splitApkPaths[i].string()); + usage(); + return 1; + } + apkPathSplitMap.replaceValueFor(splitApkPaths[i], splits); + const size_t apkSplitDescriptionCount = splits.size(); + for (size_t j = 0; j < apkSplitDescriptionCount; j++) { + splitApkPathMap.replaceValueFor(splits[j], splitApkPaths[i]); + } + splitConfigs.appendVector(splits); + } + + if (!generateFlag) { + Vector<SplitDescription> matchingConfigs = select(targetSplit, splitConfigs); + const size_t matchingConfigCount = matchingConfigs.size(); + SortedVector<String8> matchingSplitPaths; + for (size_t i = 0; i < matchingConfigCount; i++) { + matchingSplitPaths.add(splitApkPathMap.valueFor(matchingConfigs[i])); + } + + const size_t matchingSplitApkPathCount = matchingSplitPaths.size(); + for (size_t i = 0; i < matchingSplitApkPathCount; i++) { + fprintf(stderr, "%s\n", matchingSplitPaths[i].string()); + } + } else { + generate(apkPathSplitMap); + } + return 0; +} + +} // namespace split + +int main(int argc, char** argv) { + return split::main(argc, argv); +} diff --git a/tools/split-select/Rule.cpp b/tools/split-select/Rule.cpp new file mode 100644 index 000000000000..9559fe2fea1b --- /dev/null +++ b/tools/split-select/Rule.cpp @@ -0,0 +1,196 @@ +/* + * Copyright (C) 2014 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 "Rule.h" + +#include <utils/String8.h> + +using namespace android; + +namespace split { + +inline static void indentStr(String8& str, int indent) { + while (indent > 0) { + str.append(" "); + indent--; + } +} + +String8 Rule::toJson(int indent) const { + String8 str; + indentStr(str, indent); + str.append("{\n"); + indent++; + indentStr(str, indent); + str.append("\"op\": \""); + switch (op) { + case ALWAYS_TRUE: + str.append("ALWAYS_TRUE"); + break; + case GREATER_THAN: + str.append("GREATER_THAN"); + break; + case LESS_THAN: + str.append("LESS_THAN"); + break; + case EQUALS: + str.append("EQUALS"); + break; + case AND_SUBRULES: + str.append("AND_SUBRULES"); + break; + case OR_SUBRULES: + str.append("OR_SUBRULES"); + break; + case CONTAINS_ANY: + str.append("CONTAINS_ANY"); + break; + default: + str.appendFormat("%d", op); + break; + } + str.append("\""); + + if (negate) { + str.append(",\n"); + indentStr(str, indent); + str.append("\"negate\": true"); + } + + bool includeKey = true; + switch (op) { + case AND_SUBRULES: + case OR_SUBRULES: + includeKey = false; + break; + default: + break; + } + + if (includeKey) { + str.append(",\n"); + indentStr(str, indent); + str.append("\"property\": \""); + switch (key) { + case NONE: + str.append("NONE"); + break; + case SDK_VERSION: + str.append("SDK_VERSION"); + break; + case SCREEN_DENSITY: + str.append("SCREEN_DENSITY"); + break; + case NATIVE_PLATFORM: + str.append("NATIVE_PLATFORM"); + break; + case LANGUAGE: + str.append("LANGUAGE"); + break; + default: + str.appendFormat("%d", key); + break; + } + str.append("\""); + } + + if (op == AND_SUBRULES || op == OR_SUBRULES) { + str.append(",\n"); + indentStr(str, indent); + str.append("\"subrules\": [\n"); + const size_t subruleCount = subrules.size(); + for (size_t i = 0; i < subruleCount; i++) { + str.append(subrules[i]->toJson(indent + 1)); + if (i != subruleCount - 1) { + str.append(","); + } + str.append("\n"); + } + indentStr(str, indent); + str.append("]"); + } else { + switch (key) { + case SDK_VERSION: + case SCREEN_DENSITY: { + str.append(",\n"); + indentStr(str, indent); + str.append("\"args\": ["); + const size_t argCount = longArgs.size(); + for (size_t i = 0; i < argCount; i++) { + if (i != 0) { + str.append(", "); + } + str.appendFormat("%d", longArgs[i]); + } + str.append("]"); + break; + } + case LANGUAGE: + case NATIVE_PLATFORM: { + str.append(",\n"); + indentStr(str, indent); + str.append("\"args\": ["); + const size_t argCount = stringArgs.size(); + for (size_t i = 0; i < argCount; i++) { + if (i != 0) { + str.append(", "); + } + str.append(stringArgs[i]); + } + str.append("]"); + break; + } + default: + break; + } + } + str.append("\n"); + indent--; + indentStr(str, indent); + str.append("}"); + return str; +} + +sp<Rule> Rule::simplify(sp<Rule> rule) { + if (rule->op != AND_SUBRULES && rule->op != OR_SUBRULES) { + return rule; + } + + Vector<sp<Rule> > newSubrules; + newSubrules.setCapacity(rule->subrules.size()); + const size_t subruleCount = rule->subrules.size(); + for (size_t i = 0; i < subruleCount; i++) { + sp<Rule> simplifiedRule = simplify(rule->subrules.editItemAt(i)); + if (simplifiedRule != NULL) { + if (simplifiedRule->op == rule->op) { + newSubrules.appendVector(simplifiedRule->subrules); + } else { + newSubrules.add(simplifiedRule); + } + } + } + + const size_t newSubruleCount = newSubrules.size(); + if (newSubruleCount == 0) { + return NULL; + } else if (subruleCount == 1) { + return newSubrules.editTop(); + } + rule->subrules = newSubrules; + return rule; +} + +} // namespace split diff --git a/tools/split-select/Rule.h b/tools/split-select/Rule.h new file mode 100644 index 000000000000..8029931f7c6a --- /dev/null +++ b/tools/split-select/Rule.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2014 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 H_ANDROID_SPLIT_RULE +#define H_ANDROID_SPLIT_RULE + +#include "SplitDescription.h" + +#include <utils/RefBase.h> +#include <utils/StrongPointer.h> +#include <utils/String8.h> +#include <utils/Vector.h> + +namespace split { + +struct Rule : public virtual android::RefBase { + inline Rule(); + + enum Operator { + LESS_THAN = 1, + GREATER_THAN, + EQUALS, + CONTAINS_ANY, + CONTAINS_ALL, + IS_TRUE, + IS_FALSE, + AND_SUBRULES, + OR_SUBRULES, + ALWAYS_TRUE, + }; + + Operator op; + + enum Key { + NONE = 0, + SDK_VERSION, + SCREEN_DENSITY, + LANGUAGE, + NATIVE_PLATFORM, + TOUCH_SCREEN, + SCREEN_SIZE, + SCREEN_LAYOUT, + }; + + Key key; + bool negate; + + android::Vector<android::String8> stringArgs; + android::Vector<int> longArgs; + android::Vector<double> doubleArgs; + android::Vector<android::sp<Rule> > subrules; + + android::String8 toJson(int indent=0) const; + + static android::sp<Rule> simplify(android::sp<Rule> rule); +}; + +Rule::Rule() +: op(ALWAYS_TRUE) +, key(NONE) +, negate(false) {} + +} // namespace split + +#endif // H_ANDROID_SPLIT_RULE diff --git a/tools/split-select/RuleGenerator.cpp b/tools/split-select/RuleGenerator.cpp new file mode 100644 index 000000000000..669ae781aace --- /dev/null +++ b/tools/split-select/RuleGenerator.cpp @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2014 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 "RuleGenerator.h" + +#include <algorithm> +#include <cmath> +#include <vector> +#include <androidfw/ResourceTypes.h> + +using namespace android; + +namespace split { + +// Calculate the point at which the density selection changes between l and h. +static inline int findMid(int l, int h) { + double root = sqrt((h*h) + (8*l*h)); + return (double(-h) + root) / 2.0; +} + +sp<Rule> RuleGenerator::generateDensity(const Vector<int>& allDensities, size_t index) { + sp<Rule> densityRule = new Rule(); + densityRule->op = Rule::AND_SUBRULES; + + const bool anyDensity = allDensities[index] == ResTable_config::DENSITY_ANY; + sp<Rule> any = new Rule(); + any->op = Rule::EQUALS; + any->key = Rule::SCREEN_DENSITY; + any->longArgs.add((int)ResTable_config::DENSITY_ANY); + any->negate = !anyDensity; + densityRule->subrules.add(any); + + if (!anyDensity) { + if (index > 0) { + sp<Rule> gt = new Rule(); + gt->op = Rule::GREATER_THAN; + gt->key = Rule::SCREEN_DENSITY; + gt->longArgs.add(findMid(allDensities[index - 1], allDensities[index]) - 1); + densityRule->subrules.add(gt); + } + + if (index + 1 < allDensities.size() && allDensities[index + 1] != ResTable_config::DENSITY_ANY) { + sp<Rule> lt = new Rule(); + lt->op = Rule::LESS_THAN; + lt->key = Rule::SCREEN_DENSITY; + lt->longArgs.add(findMid(allDensities[index], allDensities[index + 1])); + densityRule->subrules.add(lt); + } + } + return densityRule; +} + +sp<Rule> RuleGenerator::generateAbi(const Vector<abi::Variant>& splitAbis, size_t index) { + const abi::Variant thisAbi = splitAbis[index]; + const std::vector<abi::Variant>& familyVariants = abi::getVariants(abi::getFamily(thisAbi)); + + std::vector<abi::Variant>::const_iterator start = + std::find(familyVariants.begin(), familyVariants.end(), thisAbi); + + std::vector<abi::Variant>::const_iterator end = familyVariants.end(); + if (index + 1 < splitAbis.size()) { + end = std::find(start, familyVariants.end(), splitAbis[index + 1]); + } + + sp<Rule> abiRule = new Rule(); + abiRule->op = Rule::CONTAINS_ANY; + abiRule->key = Rule::NATIVE_PLATFORM; + while (start != end) { + abiRule->stringArgs.add(String8(abi::toString(*start))); + ++start; + } + return abiRule; +} + +sp<Rule> RuleGenerator::generate(const SortedVector<SplitDescription>& group, size_t index) { + sp<Rule> rootRule = new Rule(); + rootRule->op = Rule::AND_SUBRULES; + + if (group[index].config.locale != 0) { + sp<Rule> locale = new Rule(); + locale->op = Rule::EQUALS; + locale->key = Rule::LANGUAGE; + char str[RESTABLE_MAX_LOCALE_LEN]; + group[index].config.getBcp47Locale(str); + locale->stringArgs.add(String8(str)); + rootRule->subrules.add(locale); + } + + if (group[index].config.sdkVersion != 0) { + sp<Rule> sdk = new Rule(); + sdk->op = Rule::GREATER_THAN; + sdk->key = Rule::SDK_VERSION; + sdk->longArgs.add(group[index].config.sdkVersion - 1); + rootRule->subrules.add(sdk); + } + + if (group[index].config.density != 0) { + size_t densityIndex = 0; + Vector<int> allDensities; + allDensities.add(group[index].config.density); + + const size_t groupSize = group.size(); + for (size_t i = 0; i < groupSize; i++) { + if (group[i].config.density != group[index].config.density) { + // This group differs by density. + allDensities.clear(); + for (size_t j = 0; j < groupSize; j++) { + allDensities.add(group[j].config.density); + } + densityIndex = index; + break; + } + } + rootRule->subrules.add(generateDensity(allDensities, densityIndex)); + } + + if (group[index].abi != abi::Variant::none) { + size_t abiIndex = 0; + Vector<abi::Variant> allVariants; + allVariants.add(group[index].abi); + + const size_t groupSize = group.size(); + for (size_t i = 0; i < groupSize; i++) { + if (group[i].abi != group[index].abi) { + // This group differs by ABI. + allVariants.clear(); + for (size_t j = 0; j < groupSize; j++) { + allVariants.add(group[j].abi); + } + abiIndex = index; + break; + } + } + rootRule->subrules.add(generateAbi(allVariants, abiIndex)); + } + + return rootRule; +} + +} // namespace split diff --git a/tools/split-select/RuleGenerator.h b/tools/split-select/RuleGenerator.h new file mode 100644 index 000000000000..619acd92287c --- /dev/null +++ b/tools/split-select/RuleGenerator.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2014 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 H_ANDROID_SPLIT_RULE_GENERATOR +#define H_ANDROID_SPLIT_RULE_GENERATOR + +#include "Abi.h" +#include "Rule.h" +#include "SplitDescription.h" + +#include <utils/SortedVector.h> +#include <utils/Vector.h> + +namespace split { + +struct RuleGenerator { + // Generate rules for a Split given the group of mutually exclusive splits it belongs to + static android::sp<Rule> generate(const android::SortedVector<SplitDescription>& group, size_t index); + + static android::sp<Rule> generateAbi(const android::Vector<abi::Variant>& allVariants, size_t index); + static android::sp<Rule> generateDensity(const android::Vector<int>& allDensities, size_t index); +}; + +} // namespace split + +#endif // H_ANDROID_SPLIT_RULE_GENERATOR diff --git a/tools/split-select/RuleGenerator_test.cpp b/tools/split-select/RuleGenerator_test.cpp new file mode 100644 index 000000000000..60baabe414b4 --- /dev/null +++ b/tools/split-select/RuleGenerator_test.cpp @@ -0,0 +1,155 @@ +/* + * Copyright (C) 2014 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 "RuleGenerator.h" + +#include <algorithm> +#include <gtest/gtest.h> +#include <utils/String8.h> + +using namespace android; + +namespace split { + +static void expectDensityRule(const Vector<int>& densities, int density, int greaterThan, int lessThan); +static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant, + std::initializer_list<const char*> matches); + +TEST(RuleGeneratorTest, testAbiRules) { + Vector<abi::Variant> abis; + abis.add(abi::Variant::armeabi); + abis.add(abi::Variant::armeabi_v7a); + abis.add(abi::Variant::x86); + std::sort(abis.begin(), abis.end()); + + expectAbiRule(abis, abi::Variant::armeabi, {"armeabi"}); + expectAbiRule(abis, abi::Variant::armeabi_v7a, {"armeabi-v7a", "arm64-v8a"}); + expectAbiRule(abis, abi::Variant::x86, {"x86", "x86_64"}); +} + +TEST(RuleGeneratorTest, testDensityRules) { + Vector<int> densities; + densities.add(ConfigDescription::DENSITY_HIGH); + densities.add(ConfigDescription::DENSITY_XHIGH); + densities.add(ConfigDescription::DENSITY_XXHIGH); + densities.add(ConfigDescription::DENSITY_ANY); + + ASSERT_LT(263, ConfigDescription::DENSITY_XHIGH); + ASSERT_GT(262, ConfigDescription::DENSITY_HIGH); + ASSERT_LT(363, ConfigDescription::DENSITY_XXHIGH); + ASSERT_GT(362, ConfigDescription::DENSITY_XHIGH); + + expectDensityRule(densities, ConfigDescription::DENSITY_HIGH, 0, 263); + expectDensityRule(densities, ConfigDescription::DENSITY_XHIGH, 262, 363); + expectDensityRule(densities, ConfigDescription::DENSITY_XXHIGH, 362, 0); + expectDensityRule(densities, ConfigDescription::DENSITY_ANY, 0, 0); +} + +// +// Helper methods. +// + +static void expectDensityRule(const Vector<int>& densities, int density, int greaterThan, int lessThan) { + const int* iter = std::find(densities.begin(), densities.end(), density); + if (densities.end() == iter) { + ADD_FAILURE() << density << "dpi was not in the density list."; + return; + } + + sp<Rule> rule = RuleGenerator::generateDensity(densities, iter - densities.begin()); + if (rule->op != Rule::AND_SUBRULES) { + ADD_FAILURE() << "Op in rule for " << density << "dpi is not Rule::AND_SUBRULES."; + return; + } + + size_t index = 0; + + bool isAnyDpi = density == ConfigDescription::DENSITY_ANY; + + sp<Rule> anyDpiRule = rule->subrules[index++]; + EXPECT_EQ(Rule::EQUALS, anyDpiRule->op) + << "for " << density << "dpi ANY DPI rule"; + EXPECT_EQ(Rule::SCREEN_DENSITY, anyDpiRule->key) + << "for " << density << "dpi ANY DPI rule"; + EXPECT_EQ(isAnyDpi == false, anyDpiRule->negate) + << "for " << density << "dpi ANY DPI rule"; + if (anyDpiRule->longArgs.size() == 1) { + EXPECT_EQ(ConfigDescription::DENSITY_ANY, anyDpiRule->longArgs[0]) + << "for " << density << "dpi ANY DPI rule"; + } else { + EXPECT_EQ(1u, anyDpiRule->longArgs.size()) + << "for " << density << "dpi ANY DPI rule"; + } + + + if (greaterThan != 0) { + sp<Rule> greaterThanRule = rule->subrules[index++]; + EXPECT_EQ(Rule::GREATER_THAN, greaterThanRule->op) + << "for " << density << "dpi GREATER_THAN rule"; + EXPECT_EQ(Rule::SCREEN_DENSITY, greaterThanRule->key) + << "for " << density << "dpi GREATER_THAN rule"; + if (greaterThanRule->longArgs.size() == 1) { + EXPECT_EQ(greaterThan, greaterThanRule->longArgs[0]) + << "for " << density << "dpi GREATER_THAN rule"; + } else { + EXPECT_EQ(1u, greaterThanRule->longArgs.size()) + << "for " << density << "dpi GREATER_THAN rule"; + } + } + + if (lessThan != 0) { + sp<Rule> lessThanRule = rule->subrules[index++]; + EXPECT_EQ(Rule::LESS_THAN, lessThanRule->op) + << "for " << density << "dpi LESS_THAN rule"; + EXPECT_EQ(Rule::SCREEN_DENSITY, lessThanRule->key) + << "for " << density << "dpi LESS_THAN rule"; + if (lessThanRule->longArgs.size() == 1) { + EXPECT_EQ(lessThan, lessThanRule->longArgs[0]) + << "for " << density << "dpi LESS_THAN rule"; + } else { + EXPECT_EQ(1u, lessThanRule->longArgs.size()) + << "for " << density << "dpi LESS_THAN rule"; + } + } +} + +static void expectAbiRule(const Vector<abi::Variant>& abis, abi::Variant variant, + std::initializer_list<const char*> matches) { + const abi::Variant* iter = std::find(abis.begin(), abis.end(), variant); + if (abis.end() == iter) { + ADD_FAILURE() << abi::toString(variant) << " was not in the abi list."; + return; + } + + sp<Rule> rule = RuleGenerator::generateAbi(abis, iter - abis.begin()); + + EXPECT_EQ(Rule::CONTAINS_ANY, rule->op) + << "for " << abi::toString(variant) << " rule"; + EXPECT_EQ(Rule::NATIVE_PLATFORM, rule->key) + << " for " << abi::toString(variant) << " rule"; + EXPECT_EQ(matches.size(), rule->stringArgs.size()) + << " for " << abi::toString(variant) << " rule"; + + for (const char* match : matches) { + if (rule->stringArgs.end() == + std::find(rule->stringArgs.begin(), rule->stringArgs.end(), String8(match))) { + ADD_FAILURE() << "Rule for abi " << abi::toString(variant) + << " does not contain match for expected abi " << match; + } + } +} + +} // namespace split diff --git a/tools/split-select/Rule_test.cpp b/tools/split-select/Rule_test.cpp new file mode 100644 index 000000000000..aca74331dfc8 --- /dev/null +++ b/tools/split-select/Rule_test.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2014 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 "Rule.h" + +#include "SplitDescription.h" + +#include <algorithm> +#include <string> +#include <gtest/gtest.h> +#include <utils/String8.h> + +using namespace android; + +namespace split { + +TEST(RuleTest, generatesValidJson) { + sp<Rule> rule = new Rule(); + rule->op = Rule::AND_SUBRULES; + + sp<Rule> subrule = new Rule(); + subrule->op = Rule::EQUALS; + subrule->key = Rule::SDK_VERSION; + subrule->longArgs.add(7); + rule->subrules.add(subrule); + + subrule = new Rule(); + subrule->op = Rule::OR_SUBRULES; + rule->subrules.add(subrule); + + sp<Rule> subsubrule = new Rule(); + subsubrule->op = Rule::GREATER_THAN; + subsubrule->key = Rule::SCREEN_DENSITY; + subsubrule->longArgs.add(10); + subrule->subrules.add(subsubrule); + + subsubrule = new Rule(); + subsubrule->op = Rule::LESS_THAN; + subsubrule->key = Rule::SCREEN_DENSITY; + subsubrule->longArgs.add(5); + subrule->subrules.add(subsubrule); + + std::string expected( + "{" + " \"op\": \"AND_SUBRULES\"," + " \"subrules\": [" + " {" + " \"op\": \"EQUALS\"," + " \"property\": \"SDK_VERSION\"," + " \"args\": [7]" + " }," + " {" + " \"op\": \"OR_SUBRULES\"," + " \"subrules\": [" + " {" + " \"op\": \"GREATER_THAN\"," + " \"property\": \"SCREEN_DENSITY\"," + " \"args\": [10]" + " }," + " {" + " \"op\": \"LESS_THAN\"," + " \"property\": \"SCREEN_DENSITY\"," + " \"args\": [5]" + " }" + " ]" + " }" + " ]" + "}"); + // Trim + expected.erase(std::remove_if(expected.begin(), expected.end(), ::isspace), expected.end()); + + std::string result(rule->toJson().string()); + + // Trim + result.erase(std::remove_if(result.begin(), result.end(), ::isspace), result.end()); + + ASSERT_EQ(expected, result); +} + +TEST(RuleTest, simplifiesSingleSubruleRules) { + sp<Rule> rule = new Rule(); + rule->op = Rule::AND_SUBRULES; + + sp<Rule> subrule = new Rule(); + subrule->op = Rule::EQUALS; + subrule->key = Rule::SDK_VERSION; + subrule->longArgs.add(7); + rule->subrules.add(subrule); + + sp<Rule> simplified = Rule::simplify(rule); + EXPECT_EQ(Rule::EQUALS, simplified->op); + EXPECT_EQ(Rule::SDK_VERSION, simplified->key); + ASSERT_EQ(1u, simplified->longArgs.size()); + EXPECT_EQ(7, simplified->longArgs[0]); +} + +TEST(RuleTest, simplifiesNestedSameOpSubrules) { + sp<Rule> rule = new Rule(); + rule->op = Rule::AND_SUBRULES; + + sp<Rule> subrule = new Rule(); + subrule->op = Rule::AND_SUBRULES; + rule->subrules.add(subrule); + + sp<Rule> subsubrule = new Rule(); + subsubrule->op = Rule::EQUALS; + subsubrule->key = Rule::SDK_VERSION; + subsubrule->longArgs.add(7); + subrule->subrules.add(subsubrule); + + subrule = new Rule(); + subrule->op = Rule::EQUALS; + subrule->key = Rule::SDK_VERSION; + subrule->longArgs.add(8); + rule->subrules.add(subrule); + + sp<Rule> simplified = Rule::simplify(rule); + EXPECT_EQ(Rule::AND_SUBRULES, simplified->op); + ASSERT_EQ(2u, simplified->subrules.size()); + + sp<Rule> simplifiedSubrule = simplified->subrules[0]; + EXPECT_EQ(Rule::EQUALS, simplifiedSubrule->op); + EXPECT_EQ(Rule::SDK_VERSION, simplifiedSubrule->key); + ASSERT_EQ(1u, simplifiedSubrule->longArgs.size()); + EXPECT_EQ(7, simplifiedSubrule->longArgs[0]); + + simplifiedSubrule = simplified->subrules[1]; + EXPECT_EQ(Rule::EQUALS, simplifiedSubrule->op); + EXPECT_EQ(Rule::SDK_VERSION, simplifiedSubrule->key); + ASSERT_EQ(1u, simplifiedSubrule->longArgs.size()); + EXPECT_EQ(8, simplifiedSubrule->longArgs[0]); +} + +} // namespace split diff --git a/tools/split-select/SplitDescription.cpp b/tools/split-select/SplitDescription.cpp new file mode 100644 index 000000000000..8037ef01f909 --- /dev/null +++ b/tools/split-select/SplitDescription.cpp @@ -0,0 +1,175 @@ +/* + * Copyright (C) 2014 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 "SplitDescription.h" + +#include "aapt/AaptConfig.h" +#include "aapt/AaptUtil.h" + +#include <utils/String8.h> +#include <utils/Vector.h> + +using namespace android; + +namespace split { + +SplitDescription::SplitDescription() +: abi(abi::Variant::none) { +} + +int SplitDescription::compare(const SplitDescription& rhs) const { + int cmp; + cmp = (int)abi - (int)rhs.abi; + if (cmp != 0) return cmp; + return config.compareLogical(rhs.config); +} + +bool SplitDescription::isBetterThan(const SplitDescription& o, const SplitDescription& target) const { + if (abi != abi::Variant::none || o.abi != abi::Variant::none) { + abi::Family family = abi::getFamily(abi); + abi::Family oFamily = abi::getFamily(o.abi); + if (family != oFamily) { + return family != abi::Family::none; + } + + if (int(target.abi) - int(abi) < int(target.abi) - int(o.abi)) { + return true; + } + } + return config.isBetterThan(o.config, &target.config); +} + +bool SplitDescription::match(const SplitDescription& o) const { + if (abi != abi::Variant::none) { + abi::Family family = abi::getFamily(abi); + abi::Family oFamily = abi::getFamily(o.abi); + if (family != oFamily) { + return false; + } + + if (int(abi) > int(o.abi)) { + return false; + } + } + return config.match(o.config); +} + +String8 SplitDescription::toString() const { + String8 extension; + if (abi != abi::Variant::none) { + if (extension.isEmpty()) { + extension.append(":"); + } else { + extension.append("-"); + } + extension.append(abi::toString(abi)); + } + String8 str(config.toString()); + str.append(extension); + return str; +} + +ssize_t parseAbi(const Vector<String8>& parts, const ssize_t index, + SplitDescription* outSplit) { + const ssize_t N = parts.size(); + abi::Variant abi = abi::Variant::none; + ssize_t endIndex = index; + if (parts[endIndex] == "arm64") { + endIndex++; + if (endIndex < N) { + if (parts[endIndex] == "v8a") { + endIndex++; + abi = abi::Variant::arm64_v8a; + } + } + } else if (parts[endIndex] == "armeabi") { + endIndex++; + abi = abi::Variant::armeabi; + if (endIndex < N) { + if (parts[endIndex] == "v7a") { + endIndex++; + abi = abi::Variant::armeabi_v7a; + } + } + } else if (parts[endIndex] == "x86") { + endIndex++; + abi = abi::Variant::x86; + } else if (parts[endIndex] == "x86_64") { + endIndex++; + abi = abi::Variant::x86_64; + } else if (parts[endIndex] == "mips") { + endIndex++; + abi = abi::Variant::mips; + } else if (parts[endIndex] == "mips64") { + endIndex++; + abi = abi::Variant::mips64; + } + + if (abi == abi::Variant::none && endIndex != index) { + return -1; + } + + if (outSplit != NULL) { + outSplit->abi = abi; + } + return endIndex; +} + +bool SplitDescription::parse(const String8& str, SplitDescription* outSplit) { + ssize_t index = str.find(":"); + + String8 configStr; + String8 extensionStr; + if (index >= 0) { + configStr.setTo(str.string(), index); + extensionStr.setTo(str.string() + index + 1); + } else { + configStr.setTo(str); + } + + SplitDescription split; + if (!AaptConfig::parse(configStr, &split.config)) { + return false; + } + + Vector<String8> parts = AaptUtil::splitAndLowerCase(extensionStr, '-'); + const ssize_t N = parts.size(); + index = 0; + + if (extensionStr.length() == 0) { + goto success; + } + + index = parseAbi(parts, index, &split); + if (index < 0) { + return false; + } else { + if (index == N) { + goto success; + } + } + + // Unrecognized + return false; + +success: + if (outSplit != NULL) { + *outSplit = split; + } + return true; +} + +} // namespace split diff --git a/tools/split-select/SplitDescription.h b/tools/split-select/SplitDescription.h new file mode 100644 index 000000000000..5fcafc86f9c4 --- /dev/null +++ b/tools/split-select/SplitDescription.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2014 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 H_ANDROID_SPLIT_SPLIT_DESCRIPTION +#define H_ANDROID_SPLIT_SPLIT_DESCRIPTION + +#include "aapt/ConfigDescription.h" +#include "Abi.h" + +#include <utils/String8.h> +#include <utils/Vector.h> + +namespace split { + +struct SplitDescription { + SplitDescription(); + SplitDescription(const SplitDescription&) = default; + + ConfigDescription config; + abi::Variant abi; + + int compare(const SplitDescription& rhs) const; + inline bool operator<(const SplitDescription& rhs) const; + inline bool operator==(const SplitDescription& rhs) const; + inline bool operator!=(const SplitDescription& rhs) const; + + bool match(const SplitDescription& o) const; + bool isBetterThan(const SplitDescription& o, const SplitDescription& target) const; + + android::String8 toString() const; + + static bool parse(const android::String8& str, SplitDescription* outSplit); +}; + +ssize_t parseAbi(const android::Vector<android::String8>& parts, const ssize_t index, + SplitDescription* outSplit); + +bool SplitDescription::operator<(const SplitDescription& rhs) const { + return compare(rhs) < 0; +} + +bool SplitDescription::operator==(const SplitDescription& rhs) const { + return compare(rhs) == 0; +} + +bool SplitDescription::operator!=(const SplitDescription& rhs) const { + return compare(rhs) != 0; +} + +} // namespace split + +#endif // H_ANDROID_SPLIT_SPLIT_DESCRIPTION |