diff options
220 files changed, 3537 insertions, 931 deletions
@@ -555,8 +555,6 @@ aidl_files := \ frameworks/base/core/java/android/service/chooser/ChooserTarget.aidl \ frameworks/base/core/java/android/speech/tts/Voice.aidl \ frameworks/base/core/java/android/app/usage/UsageEvents.aidl \ - frameworks/base/core/java/android/app/AssistStructure.aidl \ - frameworks/base/core/java/android/app/AssistContent.aidl \ frameworks/base/core/java/android/app/Notification.aidl \ frameworks/base/core/java/android/app/NotificationManager.aidl \ frameworks/base/core/java/android/app/WallpaperInfo.aidl \ @@ -566,6 +564,8 @@ aidl_files := \ frameworks/base/core/java/android/app/AlarmManager.aidl \ frameworks/base/core/java/android/app/SearchableInfo.aidl \ frameworks/base/core/java/android/app/VoiceInteractor.aidl \ + frameworks/base/core/java/android/app/assist/AssistContent.aidl \ + frameworks/base/core/java/android/app/assist/AssistStructure.aidl \ frameworks/base/core/java/android/app/job/JobParameters.aidl \ frameworks/base/core/java/android/app/job/JobInfo.aidl \ frameworks/base/core/java/android/appwidget/AppWidgetProviderInfo.aidl \ diff --git a/api/current.txt b/api/current.txt index 3c878c8..c9a8efb 100644 --- a/api/current.txt +++ b/api/current.txt @@ -3445,7 +3445,7 @@ package android.app { method public void onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder); method public boolean onPrepareOptionsMenu(android.view.Menu); method public boolean onPreparePanel(int, android.view.View, android.view.Menu); - method public void onProvideAssistContent(android.app.AssistContent); + method public void onProvideAssistContent(android.app.assist.AssistContent); method public void onProvideAssistData(android.os.Bundle); method public void onRequestPermissionsResult(int, java.lang.String[], int[]); method protected void onRestart(); @@ -3996,26 +3996,19 @@ package android.app { field public java.lang.String serviceDetails; } - public class AssistContent implements android.os.Parcelable { + public deprecated class AssistContent { ctor public AssistContent(); - method public int describeContents(); method public android.content.ClipData getClipData(); - method public android.content.Intent getIntent(); method public android.net.Uri getWebUri(); method public void setClipData(android.content.ClipData); method public void setIntent(android.content.Intent); method public void setWebUri(android.net.Uri); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.app.AssistContent> CREATOR; } - public final class AssistStructure implements android.os.Parcelable { - method public int describeContents(); + public deprecated class AssistStructure { + ctor public AssistStructure(); method public android.content.ComponentName getActivityComponent(); - method public android.app.AssistStructure.WindowNode getWindowNodeAt(int); method public int getWindowNodeCount(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.app.AssistStructure> CREATOR; } public static class AssistStructure.ViewNode { @@ -4384,6 +4377,7 @@ package android.app { method public void setSharedElementReturnTransition(android.transition.Transition); method public void setTargetFragment(android.app.Fragment, int); method public void setUserVisibleHint(boolean); + method public boolean shouldShowRequestPermissionRationale(java.lang.String); method public void startActivity(android.content.Intent); method public void startActivity(android.content.Intent, android.os.Bundle); method public void startActivityForResult(android.content.Intent, int); @@ -5899,6 +5893,26 @@ package android.app.admin { } +package android.app.assist { + + public final class AssistContent extends android.app.AssistContent implements android.os.Parcelable { + ctor public AssistContent(android.os.Parcel); + method public int describeContents(); + method public android.content.Intent getIntent(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.app.assist.AssistContent> CREATOR; + } + + public final class AssistStructure extends android.app.AssistStructure implements android.os.Parcelable { + ctor public AssistStructure(); + method public int describeContents(); + method public android.app.AssistStructure.WindowNode getWindowNodeAt(int); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.app.assist.AssistStructure> CREATOR; + } + +} + package android.app.backup { public abstract class BackupAgent extends android.content.ContextWrapper { @@ -13191,6 +13205,7 @@ package android.hardware.camera2 { method public abstract void close(); method public abstract android.hardware.camera2.CameraDevice getDevice(); method public abstract android.view.Surface getInputSurface(); + method public abstract boolean isConstrainedHighSpeed(); method public abstract boolean isReprocessable(); method public abstract void prepare(android.view.Surface) throws android.hardware.camera2.CameraAccessException; method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; @@ -13311,6 +13326,8 @@ package android.hardware.camera2 { method public abstract void close(); method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException; method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; + method public abstract void createConstrainedHighSpeedCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; + method public abstract java.util.List<android.hardware.camera2.CaptureRequest> createConstrainedHighSpeedRequestList(android.hardware.camera2.CaptureRequest) throws android.hardware.camera2.CameraAccessException; method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException; method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; method public abstract java.lang.String getId(); @@ -13441,7 +13458,7 @@ package android.hardware.camera2 { field public static final int CONTROL_SCENE_MODE_FACE_PRIORITY = 1; // 0x1 field public static final int CONTROL_SCENE_MODE_FIREWORKS = 12; // 0xc field public static final int CONTROL_SCENE_MODE_HDR = 18; // 0x12 - field public static final int CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17; // 0x11 + field public static final deprecated int CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17; // 0x11 field public static final int CONTROL_SCENE_MODE_LANDSCAPE = 4; // 0x4 field public static final int CONTROL_SCENE_MODE_NIGHT = 5; // 0x5 field public static final int CONTROL_SCENE_MODE_NIGHT_PORTRAIT = 6; // 0x6 @@ -13488,6 +13505,7 @@ package android.hardware.camera2 { field public static final int NOISE_REDUCTION_MODE_OFF = 0; // 0x0 field public static final int REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0; // 0x0 field public static final int REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE = 6; // 0x6 + field public static final int REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO = 9; // 0x9 field public static final int REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8; // 0x8 field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2; // 0x2 field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1; // 0x1 @@ -28930,7 +28948,7 @@ package android.service.voice { method public android.view.View onCreateContentView(); method public void onDestroy(); method public boolean[] onGetSupportedCommands(java.lang.String[]); - method public void onHandleAssist(android.os.Bundle, android.app.AssistStructure, android.app.AssistContent); + method public void onHandleAssist(android.os.Bundle, android.app.assist.AssistStructure, android.app.assist.AssistContent); method public void onHide(); method public boolean onKeyDown(int, android.view.KeyEvent); method public boolean onKeyLongPress(int, android.view.KeyEvent); @@ -32454,7 +32472,7 @@ package android.text { method public android.text.StaticLayout.Builder setLineSpacing(float, float); method public android.text.StaticLayout.Builder setMaxLines(int); method public android.text.StaticLayout.Builder setText(java.lang.CharSequence); - method public android.text.StaticLayout.Builder setTextDir(android.text.TextDirectionHeuristic); + method public android.text.StaticLayout.Builder setTextDirection(android.text.TextDirectionHeuristic); } public abstract interface TextDirectionHeuristic { diff --git a/api/system-current.txt b/api/system-current.txt index 65ca29a..2f26891 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -3531,7 +3531,7 @@ package android.app { method public void onPrepareNavigateUpTaskStack(android.app.TaskStackBuilder); method public boolean onPrepareOptionsMenu(android.view.Menu); method public boolean onPreparePanel(int, android.view.View, android.view.Menu); - method public void onProvideAssistContent(android.app.AssistContent); + method public void onProvideAssistContent(android.app.assist.AssistContent); method public void onProvideAssistData(android.os.Bundle); method public void onRequestPermissionsResult(int, java.lang.String[], int[]); method protected void onRestart(); @@ -4092,26 +4092,19 @@ package android.app { field public java.lang.String serviceDetails; } - public class AssistContent implements android.os.Parcelable { + public deprecated class AssistContent { ctor public AssistContent(); - method public int describeContents(); method public android.content.ClipData getClipData(); - method public android.content.Intent getIntent(); method public android.net.Uri getWebUri(); method public void setClipData(android.content.ClipData); method public void setIntent(android.content.Intent); method public void setWebUri(android.net.Uri); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.app.AssistContent> CREATOR; } - public final class AssistStructure implements android.os.Parcelable { - method public int describeContents(); + public deprecated class AssistStructure { + ctor public AssistStructure(); method public android.content.ComponentName getActivityComponent(); - method public android.app.AssistStructure.WindowNode getWindowNodeAt(int); method public int getWindowNodeCount(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.app.AssistStructure> CREATOR; } public static class AssistStructure.ViewNode { @@ -4480,6 +4473,7 @@ package android.app { method public void setSharedElementReturnTransition(android.transition.Transition); method public void setTargetFragment(android.app.Fragment, int); method public void setUserVisibleHint(boolean); + method public boolean shouldShowRequestPermissionRationale(java.lang.String); method public void startActivity(android.content.Intent); method public void startActivity(android.content.Intent, android.os.Bundle); method public void startActivityForResult(android.content.Intent, int); @@ -6014,6 +6008,26 @@ package android.app.admin { } +package android.app.assist { + + public final class AssistContent extends android.app.AssistContent implements android.os.Parcelable { + ctor public AssistContent(android.os.Parcel); + method public int describeContents(); + method public android.content.Intent getIntent(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.app.assist.AssistContent> CREATOR; + } + + public final class AssistStructure extends android.app.AssistStructure implements android.os.Parcelable { + ctor public AssistStructure(); + method public int describeContents(); + method public android.app.AssistStructure.WindowNode getWindowNodeAt(int); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.app.assist.AssistStructure> CREATOR; + } + +} + package android.app.backup { public abstract class BackupAgent extends android.content.ContextWrapper { @@ -13509,6 +13523,7 @@ package android.hardware.camera2 { method public abstract void close(); method public abstract android.hardware.camera2.CameraDevice getDevice(); method public abstract android.view.Surface getInputSurface(); + method public abstract boolean isConstrainedHighSpeed(); method public abstract boolean isReprocessable(); method public abstract void prepare(android.view.Surface) throws android.hardware.camera2.CameraAccessException; method public abstract int setRepeatingBurst(java.util.List<android.hardware.camera2.CaptureRequest>, android.hardware.camera2.CameraCaptureSession.CaptureCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; @@ -13629,6 +13644,8 @@ package android.hardware.camera2 { method public abstract void close(); method public abstract android.hardware.camera2.CaptureRequest.Builder createCaptureRequest(int) throws android.hardware.camera2.CameraAccessException; method public abstract void createCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; + method public abstract void createConstrainedHighSpeedCaptureSession(java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; + method public abstract java.util.List<android.hardware.camera2.CaptureRequest> createConstrainedHighSpeedRequestList(android.hardware.camera2.CaptureRequest) throws android.hardware.camera2.CameraAccessException; method public abstract android.hardware.camera2.CaptureRequest.Builder createReprocessCaptureRequest(android.hardware.camera2.TotalCaptureResult) throws android.hardware.camera2.CameraAccessException; method public abstract void createReprocessableCaptureSession(android.hardware.camera2.params.InputConfiguration, java.util.List<android.view.Surface>, android.hardware.camera2.CameraCaptureSession.StateCallback, android.os.Handler) throws android.hardware.camera2.CameraAccessException; method public abstract java.lang.String getId(); @@ -13759,7 +13776,7 @@ package android.hardware.camera2 { field public static final int CONTROL_SCENE_MODE_FACE_PRIORITY = 1; // 0x1 field public static final int CONTROL_SCENE_MODE_FIREWORKS = 12; // 0xc field public static final int CONTROL_SCENE_MODE_HDR = 18; // 0x12 - field public static final int CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17; // 0x11 + field public static final deprecated int CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17; // 0x11 field public static final int CONTROL_SCENE_MODE_LANDSCAPE = 4; // 0x4 field public static final int CONTROL_SCENE_MODE_NIGHT = 5; // 0x5 field public static final int CONTROL_SCENE_MODE_NIGHT_PORTRAIT = 6; // 0x6 @@ -13806,6 +13823,7 @@ package android.hardware.camera2 { field public static final int NOISE_REDUCTION_MODE_OFF = 0; // 0x0 field public static final int REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE = 0; // 0x0 field public static final int REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE = 6; // 0x6 + field public static final int REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO = 9; // 0x9 field public static final int REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8; // 0x8 field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_POST_PROCESSING = 2; // 0x2 field public static final int REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR = 1; // 0x1 @@ -31063,7 +31081,7 @@ package android.service.voice { method public android.view.View onCreateContentView(); method public void onDestroy(); method public boolean[] onGetSupportedCommands(java.lang.String[]); - method public void onHandleAssist(android.os.Bundle, android.app.AssistStructure, android.app.AssistContent); + method public void onHandleAssist(android.os.Bundle, android.app.assist.AssistStructure, android.app.assist.AssistContent); method public void onHide(); method public boolean onKeyDown(int, android.view.KeyEvent); method public boolean onKeyLongPress(int, android.view.KeyEvent); @@ -34719,7 +34737,7 @@ package android.text { method public android.text.StaticLayout.Builder setLineSpacing(float, float); method public android.text.StaticLayout.Builder setMaxLines(int); method public android.text.StaticLayout.Builder setText(java.lang.CharSequence); - method public android.text.StaticLayout.Builder setTextDir(android.text.TextDirectionHeuristic); + method public android.text.StaticLayout.Builder setTextDirection(android.text.TextDirectionHeuristic); } public abstract interface TextDirectionHeuristic { diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java index 250b002..cdf7429 100644 --- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java +++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java @@ -20,6 +20,7 @@ import android.content.ComponentName; import android.content.Context; import android.os.RemoteException; import android.os.ServiceManager; +import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; @@ -39,8 +40,10 @@ public final class Telecom extends BaseCommand { (new Telecom()).run(args); } - private static final String COMMAND_SET_PHONE_ACOUNT_ENABLED = "set-phone-account-enabled"; - private static final String COMMAND_SET_PHONE_ACOUNT_DISABLED = "set-phone-account-disabled"; + private static final String COMMAND_SET_PHONE_ACCOUNT_ENABLED = "set-phone-account-enabled"; + private static final String COMMAND_SET_PHONE_ACCOUNT_DISABLED = "set-phone-account-disabled"; + private static final String COMMAND_REGISTER_PHONE_ACCOUNT = "register-phone-account"; + private static final String COMMAND_UNREGISTER_PHONE_ACCOUNT = "unregister-phone-account"; private static final String COMMAND_SET_DEFAULT_DIALER = "set-default-dialer"; private static final String COMMAND_GET_DEFAULT_DIALER = "get-default-dialer"; @@ -54,6 +57,8 @@ public final class Telecom extends BaseCommand { "usage: telecom [subcommand] [options]\n" + "usage: telecom set-phone-account-enabled <COMPONENT> <ID>\n" + "usage: telecom set-phone-account-disabled <COMPONENT> <ID>\n" + + "usage: telecom register-phone-account <COMPONENT> <ID> <LABEL>\n" + + "usage: telecom unregister-phone-account <COMPONENT> <ID>\n" + "usage: telecom set-default-dialer <PACKAGE>\n" + "usage: telecom get-default-dialer <PACKAGE>\n" + "\n" + @@ -63,9 +68,9 @@ public final class Telecom extends BaseCommand { "telecom set-phone-account-disabled: Disables the given phone account, if it \n" + " has already been registered with telecom.\n" + "\n" + - "telecom set-default_dialer: Sets the default dialer to the given component. \n" + + "telecom set-default-dialer: Sets the default dialer to the given component. \n" + "\n" + - "telecom get-default_dialer: Displays the current default dialer. \n" + "telecom get-default-dialer: Displays the current default dialer. \n" ); } @@ -80,12 +85,18 @@ public final class Telecom extends BaseCommand { String command = nextArgRequired(); switch (command) { - case COMMAND_SET_PHONE_ACOUNT_ENABLED: + case COMMAND_SET_PHONE_ACCOUNT_ENABLED: runSetPhoneAccountEnabled(true); break; - case COMMAND_SET_PHONE_ACOUNT_DISABLED: + case COMMAND_SET_PHONE_ACCOUNT_DISABLED: runSetPhoneAccountEnabled(false); break; + case COMMAND_REGISTER_PHONE_ACCOUNT: + runRegisterPhoneAccount(); + break; + case COMMAND_UNREGISTER_PHONE_ACCOUNT: + runUnregisterPhoneAccount(); + break; case COMMAND_SET_DEFAULT_DIALER: runSetDefaultDialer(); break; @@ -98,9 +109,7 @@ public final class Telecom extends BaseCommand { } private void runSetPhoneAccountEnabled(boolean enabled) throws RemoteException { - final ComponentName component = parseComponentName(nextArgRequired()); - final String accountId = nextArgRequired(); - final PhoneAccountHandle handle = new PhoneAccountHandle(component, accountId); + final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs(); final boolean success = mTelecomService.enablePhoneAccount(handle, enabled); if (success) { System.out.println("Success - " + handle + (enabled ? " enabled." : " disabled.")); @@ -109,6 +118,21 @@ public final class Telecom extends BaseCommand { } } + private void runRegisterPhoneAccount() throws RemoteException { + final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs(); + final String label = nextArgRequired(); + PhoneAccount account = PhoneAccount.builder(handle, label) + .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER).build(); + mTelecomService.registerPhoneAccount(account); + System.out.println("Success - " + handle + " registered."); + } + + private void runUnregisterPhoneAccount() throws RemoteException { + final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs(); + mTelecomService.unregisterPhoneAccount(handle); + System.out.println("Success - " + handle + " unregistered."); + } + private void runSetDefaultDialer() throws RemoteException { final String packageName = nextArgRequired(); final boolean success = mTelecomService.setDefaultDialer(packageName); @@ -124,6 +148,12 @@ public final class Telecom extends BaseCommand { System.out.println(mTelecomService.getDefaultDialerPackage()); } + private PhoneAccountHandle getPhoneAccountHandleFromArgs() { + final ComponentName component = parseComponentName(nextArgRequired()); + final String accountId = nextArgRequired(); + return new PhoneAccountHandle(component, accountId); + } + private ComponentName parseComponentName(String component) { ComponentName cn = ComponentName.unflattenFromString(component); if (cn == null) { diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 073fefc..90567c7 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -38,6 +38,7 @@ import com.android.internal.app.ToolbarActionBar; import android.annotation.SystemApi; import android.app.admin.DevicePolicyManager; +import android.app.assist.AssistContent; import android.content.ComponentCallbacks2; import android.content.ComponentName; import android.content.ContentResolver; diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index e4def1e..b6cec60 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -17,6 +17,8 @@ package android.app; import android.app.ActivityManager.StackInfo; +import android.app.assist.AssistContent; +import android.app.assist.AssistStructure; import android.content.ComponentName; import android.content.IIntentReceiver; import android.content.IIntentSender; diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 2a98b6c..3224d41 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -16,6 +16,8 @@ package android.app; +import android.app.assist.AssistContent; +import android.app.assist.AssistStructure; import android.app.backup.BackupAgent; import android.content.BroadcastReceiver; import android.content.ComponentCallbacks2; diff --git a/core/java/android/app/AssistContent.java b/core/java/android/app/AssistContent.java index f271af1..4cb89a8 100644 --- a/core/java/android/app/AssistContent.java +++ b/core/java/android/app/AssistContent.java @@ -26,9 +26,11 @@ import android.os.Parcelable; /** * Holds information about the content an application is viewing, to hand to an * assistant at the user's request. This is filled in by - * {@link Activity#onProvideAssistContent Activity.onProvideAssistContent}. + * {@link android.app.Activity#onProvideAssistContent Activity.onProvideAssistContent}. + * @deprecated use {@link android.app.assist.AssistContent}. */ -public class AssistContent implements Parcelable { +@Deprecated +public class AssistContent { private Intent mIntent; private ClipData mClipData; private Uri mUri; @@ -36,16 +38,16 @@ public class AssistContent implements Parcelable { /** * @hide * Key name this data structure is stored in the Bundle generated by - * {@link Activity#onProvideAssistData}. + * {@link android.app.Activity#onProvideAssistData}. */ public static final String ASSIST_KEY = "android:assist_content"; /** * @hide * Retrieve the framework-generated AssistContent that is stored within - * the Bundle filled in by {@link Activity#onProvideAssistContent}. + * the Bundle filled in by {@link android.app.Activity#onProvideAssistContent}. */ - public static AssistContent getAssistContent(Bundle assistBundle) { + public static android.app.assist.AssistContent getAssistContent(Bundle assistBundle) { return assistBundle.getParcelable(ASSIST_KEY); } @@ -71,6 +73,7 @@ public class AssistContent implements Parcelable { /** * Return the current {@link #setIntent}, which you can modify in-place. + * @hide */ public Intent getIntent() { return mIntent; @@ -116,7 +119,8 @@ public class AssistContent implements Parcelable { return mUri; } - AssistContent(Parcel in) { + /** @hide */ + public AssistContent(Parcel in) { if (in.readInt() != 0) { mIntent = Intent.CREATOR.createFromParcel(in); } @@ -128,13 +132,8 @@ public class AssistContent implements Parcelable { } } - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { if (mIntent != null) { dest.writeInt(1); mIntent.writeToParcel(dest, flags); @@ -154,15 +153,4 @@ public class AssistContent implements Parcelable { dest.writeInt(0); } } - - public static final Parcelable.Creator<AssistContent> CREATOR - = new Parcelable.Creator<AssistContent>() { - public AssistContent createFromParcel(Parcel in) { - return new AssistContent(in); - } - - public AssistContent[] newArray(int size) { - return new AssistContent[size]; - } - }; } diff --git a/core/java/android/app/AssistStructure.java b/core/java/android/app/AssistStructure.java index ca47a5e..ef7fde4 100644 --- a/core/java/android/app/AssistStructure.java +++ b/core/java/android/app/AssistStructure.java @@ -17,9 +17,7 @@ package android.app; import android.content.ComponentName; -import android.graphics.Paint; import android.graphics.Rect; -import android.graphics.Typeface; import android.os.Binder; import android.os.Bundle; import android.os.IBinder; @@ -29,7 +27,6 @@ import android.os.PooledStringReader; import android.os.PooledStringWriter; import android.os.RemoteException; import android.os.SystemClock; -import android.text.TextPaint; import android.text.TextUtils; import android.util.Log; import android.view.View; @@ -42,19 +39,22 @@ import java.util.ArrayList; /** * Assist data automatically created by the platform's implementation - * of {@link Activity#onProvideAssistData}. + * of {@link android.app.Activity#onProvideAssistData}. + * @deprecated use {@link android.app.assist.AssistStructure}. */ -final public class AssistStructure implements Parcelable { +@Deprecated +public class AssistStructure { static final String TAG = "AssistStructure"; /** * @hide * Key name this data structure is stored in the Bundle generated by - * {@link Activity#onProvideAssistData}. + * {@link android.app.Activity#onProvideAssistData}. */ public static final String ASSIST_KEY = "android:assist_structure"; - boolean mHaveData; + /** @hide */ + public boolean mHaveData; ComponentName mActivityComponent; @@ -62,15 +62,18 @@ final public class AssistStructure implements Parcelable { final ArrayList<ViewNodeBuilder> mPendingAsyncChildren = new ArrayList<>(); - SendChannel mSendChannel; - IBinder mReceiveChannel; + /** @hide */ + public SendChannel mSendChannel; + /** @hide */ + public IBinder mReceiveChannel; Rect mTmpRect = new Rect(); static final int TRANSACTION_XFER = Binder.FIRST_CALL_TRANSACTION+1; static final String DESCRIPTOR = "android.app.AssistStructure"; - final class SendChannel extends Binder { + /** @hide */ + public final class SendChannel extends Binder { @Override protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { if (code == TRANSACTION_XFER) { @@ -702,7 +705,8 @@ final public class AssistStructure implements Parcelable { } } - AssistStructure(Activity activity) { + /** @hide */ + public AssistStructure(Activity activity) { mHaveData = true; mActivityComponent = activity.getComponentName(); ArrayList<ViewRootImpl> views = WindowManagerGlobal.getInstance().getRootViews( @@ -713,12 +717,13 @@ final public class AssistStructure implements Parcelable { } } - AssistStructure() { + public AssistStructure() { mHaveData = true; mActivityComponent = null; } - AssistStructure(Parcel in) { + /** @hide */ + public AssistStructure(Parcel in) { mReceiveChannel = in.readStrongBinder(); } @@ -792,7 +797,7 @@ final public class AssistStructure implements Parcelable { * Retrieve the framework-generated AssistStructure that is stored within * the Bundle filled in by {@link Activity#onProvideAssistData}. */ - public static AssistStructure getAssistStructure(Bundle assistBundle) { + public static android.app.assist.AssistStructure getAssistStructure(Bundle assistBundle) { return assistBundle.getParcelable(ASSIST_KEY); } @@ -812,16 +817,13 @@ final public class AssistStructure implements Parcelable { /** * Return one of the windows in the assist data. * @param index Which window to retrieve, may be 0 to {@link #getWindowNodeCount()}-1. + * @hide */ public WindowNode getWindowNodeAt(int index) { ensureData(); return mWindowNodes.get(index); } - public int describeContents() { - return 0; - } - /** @hide */ public void ensureData() { if (mHaveData) { @@ -880,29 +882,4 @@ final public class AssistStructure implements Parcelable { } //dump(); } - - public void writeToParcel(Parcel out, int flags) { - if (mHaveData) { - // This object holds its data. We want to write a send channel that the - // other side can use to retrieve that data. - if (mSendChannel == null) { - mSendChannel = new SendChannel(); - } - out.writeStrongBinder(mSendChannel); - } else { - // This object doesn't hold its data, so just propagate along its receive channel. - out.writeStrongBinder(mReceiveChannel); - } - } - - public static final Parcelable.Creator<AssistStructure> CREATOR - = new Parcelable.Creator<AssistStructure>() { - public AssistStructure createFromParcel(Parcel in) { - return new AssistStructure(in); - } - - public AssistStructure[] newArray(int size) { - return new AssistStructure[size]; - } - }; } diff --git a/core/java/android/app/Fragment.java b/core/java/android/app/Fragment.java index 40c5c64..26d4fd4 100644 --- a/core/java/android/app/Fragment.java +++ b/core/java/android/app/Fragment.java @@ -1223,6 +1223,33 @@ public class Fragment implements ComponentCallbacks2, OnCreateContextMenuListene } /** + * Gets whether you should show UI with rationale for requesting a permission. + * You should do this only if you do not have the permission and the context in + * which the permission is requested does not clearly communicate to the user + * what would be the benefit from granting this permission. + * <p> + * For example, if you write a camera app, requesting the camera permission + * would be expected by the user and no rationale for why it is requested is + * needed. If however, the app needs location for tagging photos then a non-tech + * savvy user may wonder how location is related to taking photos. In this case + * you may choose to show UI with rationale of requesting this permission. + * </p> + * + * @param permission A permission your app wants to request. + * @return Whether you can show permission rationale UI. + * + * @see Context#checkSelfPermission(String) + * @see #requestPermissions(String[], int) + * @see #onRequestPermissionsResult(int, String[], int[]) + */ + public boolean shouldShowRequestPermissionRationale(@NonNull String permission) { + if (mHost != null) { + mHost.getContext().getPackageManager().shouldShowRequestPermissionRationale(permission); + } + return false; + } + + /** * @hide Hack so that DialogFragment can make its Dialog before creating * its views, and the view construction can use the dialog's context for * inflation. Maybe this should become a public API. Note sure. diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index 0a425ae..249cdb2 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -19,6 +19,8 @@ package android.app; import android.app.ActivityManager.RunningTaskInfo; import android.app.ActivityManager.RunningServiceInfo; import android.app.ActivityManager.StackInfo; +import android.app.assist.AssistContent; +import android.app.assist.AssistStructure; import android.content.ComponentName; import android.content.ContentProviderNative; import android.content.IContentProvider; diff --git a/core/java/android/app/AssistContent.aidl b/core/java/android/app/assist/AssistContent.aidl index a6321bf..24379bb 100644 --- a/core/java/android/app/AssistContent.aidl +++ b/core/java/android/app/assist/AssistContent.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.app; +package android.app.assist; parcelable AssistContent; diff --git a/core/java/android/app/assist/AssistContent.java b/core/java/android/app/assist/AssistContent.java new file mode 100644 index 0000000..c7e7330 --- /dev/null +++ b/core/java/android/app/assist/AssistContent.java @@ -0,0 +1,44 @@ +package android.app.assist; + +import android.content.Intent; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * New home for AssistContent. + */ +public final class AssistContent extends android.app.AssistContent implements Parcelable { + + /** @hide */ + public AssistContent() { + } + + public AssistContent(Parcel in) { + super(in); + } + + public Intent getIntent() { + return super.getIntent(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + public static final Parcelable.Creator<AssistContent> CREATOR + = new Parcelable.Creator<AssistContent>() { + public AssistContent createFromParcel(Parcel in) { + return new AssistContent(in); + } + + public AssistContent[] newArray(int size) { + return new AssistContent[size]; + } + }; +} diff --git a/core/java/android/app/AssistStructure.aidl b/core/java/android/app/assist/AssistStructure.aidl index 07fb2453..ae0a34c 100644 --- a/core/java/android/app/AssistStructure.aidl +++ b/core/java/android/app/assist/AssistStructure.aidl @@ -14,6 +14,6 @@ * limitations under the License. */ -package android.app; +package android.app.assist; parcelable AssistStructure; diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java new file mode 100644 index 0000000..1677e95 --- /dev/null +++ b/core/java/android/app/assist/AssistStructure.java @@ -0,0 +1,56 @@ +package android.app.assist; + +import android.app.Activity; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * New home for AssistStructure. + */ +public final class AssistStructure extends android.app.AssistStructure implements Parcelable { + + public AssistStructure() { + } + + /** @hide */ + public AssistStructure(Activity activity) { + super(activity); + } + + AssistStructure(Parcel in) { + super(in); + } + + public WindowNode getWindowNodeAt(int index) { + return super.getWindowNodeAt(index); + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel out, int flags) { + if (mHaveData) { + // This object holds its data. We want to write a send channel that the + // other side can use to retrieve that data. + if (mSendChannel == null) { + mSendChannel = new SendChannel(); + } + out.writeStrongBinder(mSendChannel); + } else { + // This object doesn't hold its data, so just propagate along its receive channel. + out.writeStrongBinder(mReceiveChannel); + } + } + + public static final Parcelable.Creator<AssistStructure> CREATOR + = new Parcelable.Creator<AssistStructure>() { + public AssistStructure createFromParcel(Parcel in) { + return new AssistStructure(in); + } + + public AssistStructure[] newArray(int size) { + return new AssistStructure[size]; + } + }; +} diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java index c22ee5f..82d40d3 100644 --- a/core/java/android/hardware/camera2/CameraCaptureSession.java +++ b/core/java/android/hardware/camera2/CameraCaptureSession.java @@ -471,6 +471,17 @@ public abstract class CameraCaptureSession implements AutoCloseable { public abstract boolean isReprocessable(); /** + * Return if this capture session is constrained high speed session that is created by + * {@link CameraDevice#createConstrainedHighSpeedCaptureSession}. + * + * @return {@code true} if this session is constrained high speed capture session, + * {@code false} otherwise. + * + * @see CameraDevice#createConstrainedHighSpeedCaptureSession + */ + public abstract boolean isConstrainedHighSpeed(); + + /** * Get the input Surface associated with a reprocessable capture session. * * <p>Each reprocessable capture session has an input {@link Surface} where the reprocess diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java index d5867a9..85e8827 100644 --- a/core/java/android/hardware/camera2/CameraCharacteristics.java +++ b/core/java/android/hardware/camera2/CameraCharacteristics.java @@ -626,35 +626,54 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri new Key<Integer>("android.control.maxRegionsAf", int.class); /** - * <p>List of available high speed video size and fps range configurations - * supported by the camera device, in the format of (width, height, fps_min, fps_max).</p> - * <p>When HIGH_SPEED_VIDEO is supported in {@link CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES android.control.availableSceneModes}, this metadata - * will list the supported high speed video size and fps range configurations. All the sizes - * listed in this configuration will be a subset of the sizes reported by {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } for processed - * non-stalling formats.</p> - * <p>For the high speed video use case, where the application will set - * {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} to HIGH_SPEED_VIDEO in capture requests, the application must + * <p>List of available high speed video size, fps range and max batch size configurations + * supported by the camera device, in the format of (width, height, fps_min, fps_max, batch_size_max).</p> + * <p>When CONSTRAINED_HIGH_SPEED_VIDEO is supported in android.control.availableCapabilities, + * this metadata will list the supported high speed video size, fps range and max batch size + * configurations. All the sizes listed in this configuration will be a subset of the sizes + * reported by {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } + * for processed non-stalling formats.</p> + * <p>For the high speed video use case, the application must * select the video size and fps range from this metadata to configure the recording and * preview streams and setup the recording requests. For example, if the application intends * to do high speed recording, it can select the maximum size reported by this metadata to * configure output streams. Once the size is selected, application can filter this metadata * by selected size and get the supported fps ranges, and use these fps ranges to setup the * recording requests. Note that for the use case of multiple output streams, application - * must select one unique size from this metadata to use. Otherwise a request error might - * occur.</p> - * <p>For normal video recording use case, where some application will NOT set - * {@link CaptureRequest#CONTROL_SCENE_MODE android.control.sceneMode} to HIGH_SPEED_VIDEO in capture requests, the fps ranges - * reported in this metadata must not be used to setup capture requests, or it will cause - * request error.</p> + * must select one unique size from this metadata to use (e.g., preview and recording streams + * must have the same size). Otherwise, the high speed capture session creation will fail.</p> + * <p>The min and max fps will be multiple times of 30fps.</p> + * <p>High speed video streaming extends significant performance pressue to camera hardware, + * to achieve efficient high speed streaming, the camera device may have to aggregate + * multiple frames together and send to camera device for processing where the request + * controls are same for all the frames in this batch. Max batch size indicates + * the max possible number of frames the camera device will group together for this high + * speed stream configuration. This max batch size will be used to generate a high speed + * recording request list by + * {@link android.hardware.camera2.CameraDevice#createConstrainedHighSpeedRequestList }. + * The max batch size for each configuration will satisfy below conditions:</p> + * <ul> + * <li>Each max batch size will be a divisor of its corresponding fps_max / 30. For example, + * if max_fps is 300, max batch size will only be 1, 2, 5, or 10.</li> + * <li>The camera device may choose smaller internal batch size for each configuration, but + * the actual batch size will be a divisor of max batch size. For example, if the max batch + * size is 8, the actual batch size used by camera device will only be 1, 2, 4, or 8.</li> + * <li>The max batch size in each configuration entry must be no larger than 32.</li> + * </ul> + * <p>The camera device doesn't have to support batch mode to achieve high speed video recording, + * in such case, batch_size_max will be reported as 1 in each configuration entry.</p> + * <p>This fps ranges in this configuration list can only be used to create requests + * that are submitted to a high speed camera capture session created by + * {@link android.hardware.camera2.CameraDevice#createConstrainedHighSpeedCaptureSession }. + * The fps ranges reported in this metadata must not be used to setup capture requests for + * normal capture session, or it will cause request error.</p> * <p><b>Range of valid values:</b><br></p> - * <p>For each configuration, the fps_max >= 60fps.</p> + * <p>For each configuration, the fps_max >= 120fps.</p> * <p><b>Optional</b> - This value may be {@code null} on some devices.</p> * <p><b>Limited capability</b> - * Present on all camera devices that report being at least {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LIMITED HARDWARE_LEVEL_LIMITED} devices in the * {@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL android.info.supportedHardwareLevel} key</p> * - * @see CameraCharacteristics#CONTROL_AVAILABLE_SCENE_MODES - * @see CaptureRequest#CONTROL_SCENE_MODE * @see CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL * @hide */ @@ -1308,7 +1327,8 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * the max pipeline depth.</p> * <p>A pipeline depth of X stages is equivalent to a pipeline latency of * X frame intervals.</p> - * <p>This value will be 8 or less.</p> + * <p>This value will normally be 8 or less, however, for high speed capture session, + * the max pipeline depth will be up to 8 x size of high speed capture request list.</p> * <p>This key is available on all devices.</p> * * @see CaptureResult#REQUEST_PIPELINE_DEPTH @@ -1371,6 +1391,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE BURST_CAPTURE}</li> * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING YUV_REPROCESSING}</li> * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT DEPTH_OUTPUT}</li> + * <li>{@link #REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO CONSTRAINED_HIGH_SPEED_VIDEO}</li> * </ul></p> * <p>This key is available on all devices.</p> * @@ -1384,6 +1405,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri * @see #REQUEST_AVAILABLE_CAPABILITIES_BURST_CAPTURE * @see #REQUEST_AVAILABLE_CAPABILITIES_YUV_REPROCESSING * @see #REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT + * @see #REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO */ @PublicKey public static final Key<int[]> REQUEST_AVAILABLE_CAPABILITIES = diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java index d02f349..006030c 100644 --- a/core/java/android/hardware/camera2/CameraDevice.java +++ b/core/java/android/hardware/camera2/CameraDevice.java @@ -583,6 +583,147 @@ public abstract class CameraDevice implements AutoCloseable { throws CameraAccessException; /** + * <p>Create a new constrained high speed capture session.</p> + * + * <p>The application can use normal capture session (created via {@link #createCaptureSession}) + * for high speed capture if the desired high speed FPS ranges are advertised by + * {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES}, in which case all API + * semantics associated with normal capture sessions applies.</p> + * + * <p>The method creates a specialized capture session that is only targeted at high speed + * video recording (>=120fps) use case if the camera device supports high speed video + * capability (i.e., {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES} contains + * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO}). + * Therefore, it has special characteristics compared with a normal capture session:</p> + * + * <ul> + * + * <li>In addition to the output target Surface requirements specified by the + * {@link #createCaptureSession} method, an active high speed capture session will support up + * to 2 output Surfaces, though the application might choose to configure just one Surface + * (e.g., preview only). All Surfaces must be either video encoder surfaces (acquired by + * {@link android.media.MediaRecorder#getSurface} or + * {@link android.media.MediaCodec#createInputSurface}) or preview surfaces (obtained from + * {@link android.view.SurfaceView}, {@link android.graphics.SurfaceTexture} via + * {@link android.view.Surface#Surface(android.graphics.SurfaceTexture)}). The Surface sizes + * must be one of the sizes reported by {@link StreamConfigurationMap#getHighSpeedVideoSizes}. + * When multiple Surfaces are configured, their size must be same.</li> + * + * <li>An active high speed capture session only accepts request lists created via + * {@link #createConstrainedHighSpeedRequestList}, and the request list can only be submitted + * to this session via {@link CameraCaptureSession#captureBurst captureBurst}, or + * {@link CameraCaptureSession#setRepeatingBurst setRepeatingBurst}.</li> + * + * <li>The FPS ranges being requested to this session must be selected from + * {@link StreamConfigurationMap#getHighSpeedVideoFpsRangesFor}. The application can still use + * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE} to control the desired FPS range. + * Switching to an FPS range that has different + * {@link android.util.Range#getUpper() maximum FPS} may trigger some camera device + * reconfigurations, which may introduce extra latency. It is recommended that the + * application avoids unnecessary maximum target FPS changes as much as possible during high + * speed streaming.</li> + * + * <li>For the request lists submitted to this session, the camera device will override the + * {@link CaptureRequest#CONTROL_MODE control mode}, auto-exposure (AE), auto-white balance + * (AWB) and auto-focus (AF) to {@link CameraMetadata#CONTROL_MODE_AUTO}, + * {@link CameraMetadata#CONTROL_AE_MODE_ON}, {@link CameraMetadata#CONTROL_AWB_MODE_AUTO} + * and {@link CameraMetadata#CONTROL_AF_MODE_CONTINUOUS_VIDEO}, respectively. All + * post-processing block mode controls will be overridden to be FAST. Therefore, no manual + * control of capture and post-processing parameters is possible. Beside these, only a subset + * of controls will work, see + * {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO} for + * more details.</li> + * + * </ul> + * + * @param outputs The new set of Surfaces that should be made available as + * targets for captured high speed image data. + * @param callback The callback to notify about the status of the new capture session. + * @param handler The handler on which the callback should be invoked, or {@code null} to use + * the current thread's {@link android.os.Looper looper}. + * + * @throws IllegalArgumentException if the set of output Surfaces do not meet the requirements, + * the callback is null, or the handler is null but the current + * thread has no looper, or the camera device doesn't support + * high speed video capability. + * @throws CameraAccessException if the camera device is no longer connected or has + * encountered a fatal error + * @throws IllegalStateException if the camera device has been closed + * + * @see #createCaptureSession + * @see CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE + * @see StreamConfigurationMap#getHighSpeedVideoSizes + * @see StreamConfigurationMap#getHighSpeedVideoFpsRangesFor + * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES + * @see CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO + * @see CameraCaptureSession#captureBurst + * @see CameraCaptureSession#setRepeatingBurst + * @see #createConstrainedHighSpeedRequestList + */ + public abstract void createConstrainedHighSpeedCaptureSession(@NonNull List<Surface> outputs, + @NonNull CameraCaptureSession.StateCallback callback, + @Nullable Handler handler) + throws CameraAccessException; + + + /** + * <p>Create a unmodifiable list of requests that is suitable for constrained high speed capture + * session streaming.</p> + * + * <p>High speed video streaming creates significant performance pressue on the camera device, + * so to achieve efficient high speed streaming, the camera device may have to aggregate + * multiple frames together. This means requests must be sent in batched groups, with all + * requests sharing the same settings. This method takes the list of output target + * Surfaces (subject to the output Surface requirements specified by the contrained high speed + * session) and a {@link CaptureRequest request}, and generates a request list that has the same + * controls for each request. The input {@link CaptureRequest request} must contain the target + * output Surfaces and target high speed FPS range that is one of the + * {@link StreamConfigurationMap#getHighSpeedVideoFpsRangesFor} for the Surface size.</p> + * + * <p>If both preview and recording Surfaces are specified in the {@code request}, the + * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE target FPS range} in the input + * {@link CaptureRequest request} must be a fixed framerate FPS range, where the + * {@link android.util.Range#getLower minimal FPS} == + * {@link android.util.Range#getUpper() maximum FPS}. The created request list will contain + * a interleaved request pattern such that the preview output FPS is at least 30fps, the + * recording output FPS is {@link android.util.Range#getUpper() maximum FPS} of the requested + * FPS range. The application can submit this request list directly to an active high speed + * capture session to achieve high speed video recording. When only preview or recording + * Surface is specified, this method will return a list of request that have the same controls + * and output targets for all requests.</p> + * + * <p>Submitting a request list created by this method to a normal capture session will result + * in an {@link IllegalArgumentException} if the high speed + * {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE FPS range} is not supported by + * {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES}.</p> + * + * @param request The high speed capture request that will be used to generate the high speed + * request list. + * @return A unmodifiable CaptureRequest list that is suitable for constrained high speed + * capture. + * + * @throws IllegalArgumentException if the set of output Surfaces in the request do not meet the + * high speed video capability requirements, or the camera + * device doesn't support high speed video capability, or the + * request doesn't meet the high speed video capability + * requirements, or the request doesn't contain the required + * controls for high speed capture. + * @throws CameraAccessException if the camera device is no longer connected or has + * encountered a fatal error + * @throws IllegalStateException if the camera device has been closed + * + * @see #createConstrainedHighSpeedCaptureSession + * @see CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE + * @see StreamConfigurationMap#getHighSpeedVideoSizes + * @see StreamConfigurationMap#getHighSpeedVideoFpsRangesFor + * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES + * @see CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO + */ + @NonNull + public abstract List<CaptureRequest> createConstrainedHighSpeedRequestList( + @NonNull CaptureRequest request)throws CameraAccessException; + + /** * <p>Create a {@link CaptureRequest.Builder} for new capture requests, * initialized with template for a target use case. The settings are chosen * to be the best options for the specific camera device, so it is not diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index ac29f80..f8db6d9 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -648,6 +648,100 @@ public abstract class CameraMetadata<TKey> { */ public static final int REQUEST_AVAILABLE_CAPABILITIES_DEPTH_OUTPUT = 8; + /** + * <p>The device supports constrained high speed video recording (frame rate >=120fps) + * use case. The camera device will support high speed capture session created by + * {@link android.hardware.camera2.CameraDevice#createConstrainedHighSpeedCaptureSession }, which + * only accepts high speed request list created by + * {@link android.hardware.camera2.CameraDevice#createConstrainedHighSpeedRequestList }.</p> + * <p>A camera device can still support high speed video streaming by advertising the high speed + * FPS ranges in {@link CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES android.control.aeAvailableTargetFpsRanges}. For this case, all normal + * capture request per frame control and synchronization requirements will apply to + * the high speed fps ranges, the same as all other fps ranges. This capability describes + * the capability of a specialized operating mode with many limitations (see below), which + * is only targeted at high speed video recording.</p> + * <p>The supported high speed video sizes and fps ranges are specified in + * {@link android.hardware.camera2.params.StreamConfigurationMap#getHighSpeedVideoFpsRanges }. + * To get desired output frame rates, the application is only allowed to select video size + * and FPS range combinations provided by + * {@link android.hardware.camera2.params.StreamConfigurationMap#getHighSpeedVideoSizes }. + * The fps range can be controlled via {@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange}.</p> + * <p>In this capability, the camera device will override aeMode, awbMode, and afMode to + * ON, ON, and CONTINUOUS_VIDEO, respectively. All post-processing block mode + * controls will be overridden to be FAST. Therefore, no manual control of capture + * and post-processing parameters is possible. All other controls operate the + * same as when {@link CaptureRequest#CONTROL_MODE android.control.mode} == AUTO. This means that all other + * android.control.* fields continue to work, such as</p> + * <ul> + * <li>{@link CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE android.control.aeTargetFpsRange}</li> + * <li>{@link CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION android.control.aeExposureCompensation}</li> + * <li>{@link CaptureRequest#CONTROL_AE_LOCK android.control.aeLock}</li> + * <li>{@link CaptureRequest#CONTROL_AWB_LOCK android.control.awbLock}</li> + * <li>{@link CaptureRequest#CONTROL_EFFECT_MODE android.control.effectMode}</li> + * <li>{@link CaptureRequest#CONTROL_AE_REGIONS android.control.aeRegions}</li> + * <li>{@link CaptureRequest#CONTROL_AF_REGIONS android.control.afRegions}</li> + * <li>{@link CaptureRequest#CONTROL_AWB_REGIONS android.control.awbRegions}</li> + * <li>{@link CaptureRequest#CONTROL_AF_TRIGGER android.control.afTrigger}</li> + * <li>{@link CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER android.control.aePrecaptureTrigger}</li> + * </ul> + * <p>Outside of android.control.*, the following controls will work:</p> + * <ul> + * <li>{@link CaptureRequest#FLASH_MODE android.flash.mode} (TORCH mode only, automatic flash for still capture will not + * work since aeMode is ON)</li> + * <li>{@link CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE android.lens.opticalStabilizationMode} (if it is supported)</li> + * <li>{@link CaptureRequest#SCALER_CROP_REGION android.scaler.cropRegion}</li> + * <li>{@link CaptureRequest#STATISTICS_FACE_DETECT_MODE android.statistics.faceDetectMode} (if it is supported)</li> + * </ul> + * <p>For high speed recording use case, the actual maximum supported frame rate may + * be lower than what camera can output, depending on the destination Surfaces for + * the image data. For example, if the destination surface is from video encoder, + * the application need check if the video encoder is capable of supporting the + * high frame rate for a given video size, or it will end up with lower recording + * frame rate. If the destination surface is from preview window, the actual preview frame + * rate will be bounded by the screen refresh rate.</p> + * <p>The camera device will only support up to 2 high speed simultaneous output surfaces + * (preview and recording surfaces) + * in this mode. Above controls will be effective only if all of below conditions are true:</p> + * <ul> + * <li>The application creates a camera capture session with no more than 2 surfaces via + * {@link android.hardware.camera2.CameraDevice#createConstrainedHighSpeedCaptureSession }. The + * targeted surfaces must be preview surface (either from + * {@link android.view.SurfaceView } or {@link android.graphics.SurfaceTexture }) or + * recording surface(either from {@link android.media.MediaRecorder#getSurface } or + * {@link android.media.MediaCodec#createInputSurface }).</li> + * <li>The stream sizes are selected from the sizes reported by + * {@link android.hardware.camera2.params.StreamConfigurationMap#getHighSpeedVideoSizes }.</li> + * <li>The FPS ranges are selected from + * {@link android.hardware.camera2.params.StreamConfigurationMap#getHighSpeedVideoFpsRanges }.</li> + * </ul> + * <p>When above conditions are NOT satistied, the + * {@link android.hardware.camera2.CameraDevice#createConstrainedHighSpeedCaptureSession } + * and {@link android.hardware.camera2.CameraDevice#createConstrainedHighSpeedRequestList } will fail.</p> + * <p>Switching to a FPS range that has different maximum FPS may trigger some camera device + * reconfigurations, which may introduce extra latency. It is recommended that + * the application avoids unnecessary maximum target FPS changes as much as possible + * during high speed streaming.</p> + * + * @see CameraCharacteristics#CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES + * @see CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION + * @see CaptureRequest#CONTROL_AE_LOCK + * @see CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER + * @see CaptureRequest#CONTROL_AE_REGIONS + * @see CaptureRequest#CONTROL_AE_TARGET_FPS_RANGE + * @see CaptureRequest#CONTROL_AF_REGIONS + * @see CaptureRequest#CONTROL_AF_TRIGGER + * @see CaptureRequest#CONTROL_AWB_LOCK + * @see CaptureRequest#CONTROL_AWB_REGIONS + * @see CaptureRequest#CONTROL_EFFECT_MODE + * @see CaptureRequest#CONTROL_MODE + * @see CaptureRequest#FLASH_MODE + * @see CaptureRequest#LENS_OPTICAL_STABILIZATION_MODE + * @see CaptureRequest#SCALER_CROP_REGION + * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE + * @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES + */ + public static final int REQUEST_AVAILABLE_CAPABILITIES_CONSTRAINED_HIGH_SPEED_VIDEO = 9; + // // Enumeration values for CameraCharacteristics#SCALER_CROPPING_TYPE // @@ -1725,6 +1819,10 @@ public abstract class CameraMetadata<TKey> { public static final int CONTROL_SCENE_MODE_BARCODE = 16; /** + * <p>This is deprecated, please use + * {@link android.hardware.camera2.CameraDevice#createConstrainedHighSpeedCaptureSession } + * and {@link android.hardware.camera2.CameraDevice#createConstrainedHighSpeedRequestList } + * for high speed video recording.</p> * <p>Optimized for high speed video recording (frame rate >=60fps) use case.</p> * <p>The supported high speed video sizes and fps ranges are specified in * android.control.availableHighSpeedVideoConfigurations. To get desired @@ -1799,6 +1897,7 @@ public abstract class CameraMetadata<TKey> { * @see CaptureRequest#SCALER_CROP_REGION * @see CaptureRequest#STATISTICS_FACE_DETECT_MODE * @see CaptureRequest#CONTROL_SCENE_MODE + * @deprecated Please refer to this API documentation to find the alternatives */ public static final int CONTROL_SCENE_MODE_HIGH_SPEED_VIDEO = 17; diff --git a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java index 7a39dd5..ab0f607 100644 --- a/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraCaptureSessionImpl.java @@ -721,4 +721,10 @@ public class CameraCaptureSessionImpl extends CameraCaptureSession { } } + @Override + public boolean isConstrainedHighSpeed() { + // TODO: to be implemented + return false; + } + } diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index e60e266..16701e5 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -1906,4 +1906,18 @@ public class CameraDeviceImpl extends CameraDevice { private CameraCharacteristics getCharacteristics() { return mCharacteristics; } + + @Override + public void createConstrainedHighSpeedCaptureSession(List<Surface> outputs, + android.hardware.camera2.CameraCaptureSession.StateCallback callback, Handler handler) + throws CameraAccessException { + // TODO: to be implemented + throw new UnsupportedOperationException("To be implemented!!!!"); + } + + @Override + public List<CaptureRequest> createConstrainedHighSpeedRequestList(CaptureRequest request) + throws CameraAccessException { + throw new UnsupportedOperationException("To be implemented!!!!"); + } } diff --git a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableHighSpeedVideoConfiguration.java b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableHighSpeedVideoConfiguration.java index c03144b..2449abe 100644 --- a/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableHighSpeedVideoConfiguration.java +++ b/core/java/android/hardware/camera2/marshal/impl/MarshalQueryableHighSpeedVideoConfiguration.java @@ -33,7 +33,7 @@ import java.nio.ByteBuffer; */ public class MarshalQueryableHighSpeedVideoConfiguration implements MarshalQueryable<HighSpeedVideoConfiguration> { - private static final int SIZE = SIZEOF_INT32 * 4; + private static final int SIZE = SIZEOF_INT32 * 5; private class MarshalerHighSpeedVideoConfiguration extends Marshaler<HighSpeedVideoConfiguration> { @@ -49,6 +49,7 @@ public class MarshalQueryableHighSpeedVideoConfiguration buffer.putInt(value.getHeight()); buffer.putInt(value.getFpsMin()); buffer.putInt(value.getFpsMax()); + buffer.putInt(value.getBatchSizeMax()); } @Override @@ -57,8 +58,9 @@ public class MarshalQueryableHighSpeedVideoConfiguration int height = buffer.getInt(); int fpsMin = buffer.getInt(); int fpsMax = buffer.getInt(); + int batchSizeMax = buffer.getInt(); - return new HighSpeedVideoConfiguration(width, height, fpsMin, fpsMax); + return new HighSpeedVideoConfiguration(width, height, fpsMin, fpsMax, batchSizeMax); } @Override diff --git a/core/java/android/hardware/camera2/params/HighSpeedVideoConfiguration.java b/core/java/android/hardware/camera2/params/HighSpeedVideoConfiguration.java index 088049f..b469126 100644 --- a/core/java/android/hardware/camera2/params/HighSpeedVideoConfiguration.java +++ b/core/java/android/hardware/camera2/params/HighSpeedVideoConfiguration.java @@ -33,6 +33,7 @@ import android.util.Size; * @hide */ public final class HighSpeedVideoConfiguration { + static final private int HIGH_SPEED_MAX_MINIMAL_FPS = 120; /** * Create a new {@link HighSpeedVideoConfiguration}. @@ -48,15 +49,18 @@ public final class HighSpeedVideoConfiguration { * @hide */ public HighSpeedVideoConfiguration( - final int width, final int height, final int fpsMin, final int fpsMax) { - if (fpsMax < 60) { - throw new IllegalArgumentException("fpsMax must be at least 60"); + final int width, final int height, final int fpsMin, final int fpsMax, + final int batchSizeMax) { + if (fpsMax < HIGH_SPEED_MAX_MINIMAL_FPS) { + throw new IllegalArgumentException("fpsMax must be at least " + + HIGH_SPEED_MAX_MINIMAL_FPS); } mFpsMax = fpsMax; mWidth = checkArgumentPositive(width, "width must be positive"); mHeight = checkArgumentPositive(height, "height must be positive"); mFpsMin = checkArgumentPositive(fpsMin, "fpsMin must be positive"); mSize = new Size(mWidth, mHeight); + mBatchSizeMax = checkArgumentPositive(batchSizeMax, "batchSizeMax must be positive"); mFpsRange = new Range<Integer>(mFpsMin, mFpsMax); } @@ -106,9 +110,18 @@ public final class HighSpeedVideoConfiguration { } /** + * Convenience method to return the max batch size of this high speed video configuration. + * + * @return the maximal batch size for this high speed video configuration + */ + public int getBatchSizeMax() { + return mBatchSizeMax; + } + + /** * Convenience method to return the FPS range of this high speed video configuration. * - * @return a Range with high bound >= 60 + * @return a Range with high bound >= {@value #HIGH_SPEED_MAX_MINIMAL_FPS} */ public Range<Integer> getFpsRange() { return mFpsRange; @@ -135,7 +148,8 @@ public final class HighSpeedVideoConfiguration { return mWidth == other.mWidth && mHeight == other.mHeight && mFpsMin == other.mFpsMin && - mFpsMax == other.mFpsMax; + mFpsMax == other.mFpsMax && + mBatchSizeMax == other.mBatchSizeMax; } return false; } @@ -152,6 +166,7 @@ public final class HighSpeedVideoConfiguration { private final int mHeight; private final int mFpsMin; private final int mFpsMax; + private final int mBatchSizeMax; private final Size mSize; private final Range<Integer> mFpsRange; } diff --git a/core/java/android/service/carrier/CarrierService.java b/core/java/android/service/carrier/CarrierService.java index 15ccc25..4a4a375 100644 --- a/core/java/android/service/carrier/CarrierService.java +++ b/core/java/android/service/carrier/CarrierService.java @@ -86,11 +86,13 @@ public abstract class CarrierService extends Service { /** @hide */ @Override public final IBinder onBind(Intent intent) { - if (!CONFIG_SERVICE_INTERFACE.equals(intent.getAction()) - || !BIND_SERVICE_INTERFACE.equals(intent.getAction())) { - return null; + switch (intent.getAction()) { + case CONFIG_SERVICE_INTERFACE: + case BIND_SERVICE_INTERFACE: + return mStubWrapper; + default: + return null; } - return mStubWrapper; } /** diff --git a/core/java/android/service/voice/IVoiceInteractionSession.aidl b/core/java/android/service/voice/IVoiceInteractionSession.aidl index 894edac..8fe84e1 100644 --- a/core/java/android/service/voice/IVoiceInteractionSession.aidl +++ b/core/java/android/service/voice/IVoiceInteractionSession.aidl @@ -16,8 +16,8 @@ package android.service.voice; -import android.app.AssistContent; -import android.app.AssistStructure; +import android.app.assist.AssistContent; +import android.app.assist.AssistStructure; import android.content.Intent; import android.graphics.Bitmap; import android.os.Bundle; diff --git a/core/java/android/service/voice/VoiceInteractionSession.java b/core/java/android/service/voice/VoiceInteractionSession.java index 48ad5a8..33fef62 100644 --- a/core/java/android/service/voice/VoiceInteractionSession.java +++ b/core/java/android/service/voice/VoiceInteractionSession.java @@ -16,11 +16,11 @@ package android.service.voice; -import android.app.AssistContent; -import android.app.AssistStructure; import android.app.Dialog; import android.app.Instrumentation; import android.app.VoiceInteractor; +import android.app.assist.AssistContent; +import android.app.assist.AssistStructure; import android.content.ComponentCallbacks2; import android.content.Context; import android.content.Intent; @@ -386,7 +386,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } /** - * ASk the app to cancel this current request. + * ASk the app to cancelLocked this current request. */ public void cancel() { try { @@ -878,14 +878,34 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall show(null, 0); } - public void show(Bundle args, int showFlags) { + /** + * Show the UI for this session. This asks the system to go through the process of showing + * your UI, which will eventually culminate in {@link #onShow}. This is similar to calling + * {@link VoiceInteractionService#showSession VoiceInteractionService.showSession}. + * @param args Arbitrary arguments that will be propagated {@link #onShow}. + * @param flags Indicates additional optional behavior that should be performed. May + * be {@link VoiceInteractionSession#SHOW_WITH_ASSIST VoiceInteractionSession.SHOW_WITH_ASSIST} + * to request that the system generate and deliver assist data on the current foreground + * app as part of showing the session UI. + */ + public void show(Bundle args, int flags) { + if (mToken == null) { + throw new IllegalStateException("Can't call before onCreate()"); + } try { - mSystemService.showSessionFromSession(mToken, null, 0); + mSystemService.showSessionFromSession(mToken, args, flags); } catch (RemoteException e) { } } + /** + * Hide the session's UI, if currently shown. Call this when you are done with your + * user interaction. + */ public void hide() { + if (mToken == null) { + throw new IllegalStateException("Can't call before onCreate()"); + } try { mSystemService.hideSessionFromSession(mToken); } catch (RemoteException e) { @@ -964,6 +984,9 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * {@link #startVoiceActivity}.</p> */ public void setKeepAwake(boolean keepAwake) { + if (mToken == null) { + throw new IllegalStateException("Can't call before onCreate()"); + } try { mSystemService.setKeepAwake(mToken, keepAwake); } catch (RemoteException e) { @@ -985,7 +1008,9 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } /** - * Finish the session. + * Finish the session. This completely destroys the session -- the next time it is shown, + * an entirely new one will be created. You do not normally call this function; instead, + * use {@link #hide} and allow the system to destroy your session if it needs its RAM. */ public void finish() { if (mToken == null) { @@ -1114,7 +1139,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall * Called when the user presses the back button while focus is in the session UI. Note * that this will only happen if the session UI has requested input focus in its window; * otherwise, the back key will go to whatever window has focus and do whatever behavior - * it normally has there. + * it normally has there. The default implementation simply calls {@link #hide}. */ public void onBackPressed() { hide(); @@ -1123,7 +1148,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall /** * Sessions automatically watch for requests that all system UI be closed (such as when * the user presses HOME), which will appear here. The default implementation always - * calls {@link #finish}. + * calls {@link #hide}. */ public void onCloseSystemDialogs() { hide(); @@ -1287,7 +1312,7 @@ public class VoiceInteractionSession implements KeyEvent.Callback, ComponentCall } /** - * Called when the {@link android.app.VoiceInteractor} has asked to cancel a {@link Request} + * Called when the {@link android.app.VoiceInteractor} has asked to cancelLocked a {@link Request} * that was previously delivered to {@link #onRequestConfirmation}, * {@link #onRequestPickOption}, {@link #onRequestCompleteVoice}, {@link #onRequestAbortVoice}, * or {@link #onRequestCommand}. diff --git a/core/java/android/text/Annotation.java b/core/java/android/text/Annotation.java index dbc290b..bb5d3ea 100644 --- a/core/java/android/text/Annotation.java +++ b/core/java/android/text/Annotation.java @@ -38,6 +38,11 @@ public class Annotation implements ParcelableSpan { } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.ANNOTATION; } @@ -46,6 +51,11 @@ public class Annotation implements ParcelableSpan { } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeString(mKey); dest.writeString(mValue); } diff --git a/core/java/android/text/DynamicLayout.java b/core/java/android/text/DynamicLayout.java index e99a960..5b5cdd2 100644 --- a/core/java/android/text/DynamicLayout.java +++ b/core/java/android/text/DynamicLayout.java @@ -291,7 +291,7 @@ public class DynamicLayout extends Layout b.setText(text, where, where + after) .setPaint(getPaint()) .setWidth(getWidth()) - .setTextDir(getTextDirectionHeuristic()) + .setTextDirection(getTextDirectionHeuristic()) .setLineSpacing(getSpacingAdd(), getSpacingMultiplier()) .setEllipsizedWidth(mEllipsizedWidth) .setEllipsize(mEllipsizeAt) diff --git a/core/java/android/text/ParcelableSpan.java b/core/java/android/text/ParcelableSpan.java index 224511a..d7c1a4b 100644 --- a/core/java/android/text/ParcelableSpan.java +++ b/core/java/android/text/ParcelableSpan.java @@ -16,6 +16,7 @@ package android.text; +import android.os.Parcel; import android.os.Parcelable; /** @@ -27,5 +28,21 @@ public interface ParcelableSpan extends Parcelable { /** * Return a special type identifier for this span class. */ - public abstract int getSpanTypeId(); + int getSpanTypeId(); + + /** + * Internal implementation of {@link #getSpanTypeId()} that is not meant to + * be overridden outside of the framework. + * + * @hide + */ + int getSpanTypeIdInternal(); + + /** + * Internal implementation of {@link Parcelable#writeToParcel(Parcel, int)} + * that is not meant to be overridden outside of the framework. + * + * @hide + */ + void writeToParcelInternal(Parcel dest, int flags); } diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java index d6d046b..464710b 100644 --- a/core/java/android/text/StaticLayout.java +++ b/core/java/android/text/StaticLayout.java @@ -184,7 +184,7 @@ public class StaticLayout extends Layout { * @param textDir text direction heuristic for resolving BiDi behavior. * @return this builder, useful for chaining */ - public Builder setTextDir(TextDirectionHeuristic textDir) { + public Builder setTextDirection(TextDirectionHeuristic textDir) { mTextDir = textDir; return this; } @@ -473,7 +473,7 @@ public class StaticLayout extends Layout { Builder b = Builder.obtain(source, bufstart, bufend, paint, outerwidth) .setAlignment(align) - .setTextDir(textDir) + .setTextDirection(textDir) .setLineSpacing(spacingadd, spacingmult) .setIncludePad(includepad) .setEllipsizedWidth(ellipsizedWidth) diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java index 676986d..6c4d8fd 100644 --- a/core/java/android/text/TextUtils.java +++ b/core/java/android/text/TextUtils.java @@ -622,8 +622,7 @@ public class TextUtils { * Flatten a CharSequence and whatever styles can be copied across processes * into the parcel. */ - public static void writeToParcel(CharSequence cs, Parcel p, - int parcelableFlags) { + public static void writeToParcel(CharSequence cs, Parcel p, int parcelableFlags) { if (cs instanceof Spanned) { p.writeInt(0); p.writeString(cs.toString()); @@ -645,15 +644,15 @@ public class TextUtils { } if (prop instanceof ParcelableSpan) { - ParcelableSpan ps = (ParcelableSpan)prop; - int spanTypeId = ps.getSpanTypeId(); + final ParcelableSpan ps = (ParcelableSpan) prop; + final int spanTypeId = ps.getSpanTypeIdInternal(); if (spanTypeId < FIRST_SPAN || spanTypeId > LAST_SPAN) { - Log.e(TAG, "external class \"" + ps.getClass().getSimpleName() + Log.e(TAG, "External class \"" + ps.getClass().getSimpleName() + "\" is attempting to use the frameworks-only ParcelableSpan" + " interface"); } else { p.writeInt(spanTypeId); - ps.writeToParcel(p, parcelableFlags); + ps.writeToParcelInternal(p, parcelableFlags); writeWhere(p, sp, o); } } diff --git a/core/java/android/text/style/AbsoluteSizeSpan.java b/core/java/android/text/style/AbsoluteSizeSpan.java index 1214040..908ef55 100644 --- a/core/java/android/text/style/AbsoluteSizeSpan.java +++ b/core/java/android/text/style/AbsoluteSizeSpan.java @@ -49,6 +49,11 @@ public class AbsoluteSizeSpan extends MetricAffectingSpan implements ParcelableS } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.ABSOLUTE_SIZE_SPAN; } @@ -57,6 +62,11 @@ public class AbsoluteSizeSpan extends MetricAffectingSpan implements ParcelableS } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeInt(mSize); dest.writeInt(mDip ? 1 : 0); } diff --git a/core/java/android/text/style/AlignmentSpan.java b/core/java/android/text/style/AlignmentSpan.java index b8a37da..6158309 100644 --- a/core/java/android/text/style/AlignmentSpan.java +++ b/core/java/android/text/style/AlignmentSpan.java @@ -22,10 +22,9 @@ import android.text.ParcelableSpan; import android.text.TextUtils; public interface AlignmentSpan extends ParagraphStyle { - public Layout.Alignment getAlignment(); + Layout.Alignment getAlignment(); - public static class Standard - implements AlignmentSpan, ParcelableSpan { + class Standard implements AlignmentSpan, ParcelableSpan { public Standard(Layout.Alignment align) { mAlignment = align; } @@ -35,6 +34,11 @@ public interface AlignmentSpan extends ParagraphStyle { } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.ALIGNMENT_SPAN; } @@ -43,6 +47,11 @@ public interface AlignmentSpan extends ParagraphStyle { } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeString(mAlignment.name()); } diff --git a/core/java/android/text/style/BackgroundColorSpan.java b/core/java/android/text/style/BackgroundColorSpan.java index cda8015..de05f50 100644 --- a/core/java/android/text/style/BackgroundColorSpan.java +++ b/core/java/android/text/style/BackgroundColorSpan.java @@ -35,6 +35,11 @@ public class BackgroundColorSpan extends CharacterStyle } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.BACKGROUND_COLOR_SPAN; } @@ -43,6 +48,11 @@ public class BackgroundColorSpan extends CharacterStyle } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeInt(mColor); } diff --git a/core/java/android/text/style/BulletSpan.java b/core/java/android/text/style/BulletSpan.java index 3f86b08..7408415 100644 --- a/core/java/android/text/style/BulletSpan.java +++ b/core/java/android/text/style/BulletSpan.java @@ -60,6 +60,11 @@ public class BulletSpan implements LeadingMarginSpan, ParcelableSpan { } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.BULLET_SPAN; } @@ -68,6 +73,11 @@ public class BulletSpan implements LeadingMarginSpan, ParcelableSpan { } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeInt(mGapWidth); dest.writeInt(mWantColor ? 1 : 0); dest.writeInt(mColor); diff --git a/core/java/android/text/style/EasyEditSpan.java b/core/java/android/text/style/EasyEditSpan.java index 03b4f60..7af1c2c 100644 --- a/core/java/android/text/style/EasyEditSpan.java +++ b/core/java/android/text/style/EasyEditSpan.java @@ -91,12 +91,22 @@ public class EasyEditSpan implements ParcelableSpan { @Override public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeParcelable(mPendingIntent, 0); dest.writeByte((byte) (mDeleteEnabled ? 1 : 0)); } @Override public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.EASY_EDIT_SPAN; } diff --git a/core/java/android/text/style/ForegroundColorSpan.java b/core/java/android/text/style/ForegroundColorSpan.java index f167aab..2bc6d54 100644 --- a/core/java/android/text/style/ForegroundColorSpan.java +++ b/core/java/android/text/style/ForegroundColorSpan.java @@ -36,14 +36,24 @@ public class ForegroundColorSpan extends CharacterStyle } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.FOREGROUND_COLOR_SPAN; } - + public int describeContents() { return 0; } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeInt(mColor); } diff --git a/core/java/android/text/style/LeadingMarginSpan.java b/core/java/android/text/style/LeadingMarginSpan.java index 96a7cd9..339d885 100644 --- a/core/java/android/text/style/LeadingMarginSpan.java +++ b/core/java/android/text/style/LeadingMarginSpan.java @@ -125,6 +125,11 @@ extends ParagraphStyle } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.LEADING_MARGIN_SPAN; } @@ -133,6 +138,11 @@ extends ParagraphStyle } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeInt(mFirst); dest.writeInt(mRest); } diff --git a/core/java/android/text/style/LocaleSpan.java b/core/java/android/text/style/LocaleSpan.java index a12c42f..d286231 100644 --- a/core/java/android/text/style/LocaleSpan.java +++ b/core/java/android/text/style/LocaleSpan.java @@ -44,6 +44,11 @@ public class LocaleSpan extends MetricAffectingSpan implements ParcelableSpan { @Override public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.LOCALE_SPAN; } @@ -54,6 +59,11 @@ public class LocaleSpan extends MetricAffectingSpan implements ParcelableSpan { @Override public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeString(mLocale.getLanguage()); dest.writeString(mLocale.getCountry()); dest.writeString(mLocale.getVariant()); diff --git a/core/java/android/text/style/QuoteSpan.java b/core/java/android/text/style/QuoteSpan.java index 17748ca..0b0a82c 100644 --- a/core/java/android/text/style/QuoteSpan.java +++ b/core/java/android/text/style/QuoteSpan.java @@ -45,6 +45,11 @@ public class QuoteSpan implements LeadingMarginSpan, ParcelableSpan { } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.QUOTE_SPAN; } @@ -53,6 +58,11 @@ public class QuoteSpan implements LeadingMarginSpan, ParcelableSpan { } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeInt(mColor); } diff --git a/core/java/android/text/style/RelativeSizeSpan.java b/core/java/android/text/style/RelativeSizeSpan.java index 632dbd4..95f048a 100644 --- a/core/java/android/text/style/RelativeSizeSpan.java +++ b/core/java/android/text/style/RelativeSizeSpan.java @@ -34,6 +34,11 @@ public class RelativeSizeSpan extends MetricAffectingSpan implements ParcelableS } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.RELATIVE_SIZE_SPAN; } @@ -42,6 +47,11 @@ public class RelativeSizeSpan extends MetricAffectingSpan implements ParcelableS } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeFloat(mProportion); } diff --git a/core/java/android/text/style/ScaleXSpan.java b/core/java/android/text/style/ScaleXSpan.java index a22a5a1..d085018 100644 --- a/core/java/android/text/style/ScaleXSpan.java +++ b/core/java/android/text/style/ScaleXSpan.java @@ -34,6 +34,11 @@ public class ScaleXSpan extends MetricAffectingSpan implements ParcelableSpan { } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.SCALE_X_SPAN; } @@ -42,6 +47,11 @@ public class ScaleXSpan extends MetricAffectingSpan implements ParcelableSpan { } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeFloat(mProportion); } diff --git a/core/java/android/text/style/SpellCheckSpan.java b/core/java/android/text/style/SpellCheckSpan.java index 0d8a103..10275c2 100644 --- a/core/java/android/text/style/SpellCheckSpan.java +++ b/core/java/android/text/style/SpellCheckSpan.java @@ -54,11 +54,21 @@ public class SpellCheckSpan implements ParcelableSpan { @Override public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeInt(mSpellCheckInProgress ? 1 : 0); } @Override public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.SPELL_CHECK_SPAN; } } diff --git a/core/java/android/text/style/StrikethroughSpan.java b/core/java/android/text/style/StrikethroughSpan.java index 303e415..1389704 100644 --- a/core/java/android/text/style/StrikethroughSpan.java +++ b/core/java/android/text/style/StrikethroughSpan.java @@ -30,6 +30,11 @@ public class StrikethroughSpan extends CharacterStyle } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.STRIKETHROUGH_SPAN; } @@ -38,6 +43,11 @@ public class StrikethroughSpan extends CharacterStyle } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { } @Override diff --git a/core/java/android/text/style/StyleSpan.java b/core/java/android/text/style/StyleSpan.java index b08f70e..f900db5 100644 --- a/core/java/android/text/style/StyleSpan.java +++ b/core/java/android/text/style/StyleSpan.java @@ -50,6 +50,11 @@ public class StyleSpan extends MetricAffectingSpan implements ParcelableSpan { } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.STYLE_SPAN; } @@ -58,6 +63,11 @@ public class StyleSpan extends MetricAffectingSpan implements ParcelableSpan { } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeInt(mStyle); } diff --git a/core/java/android/text/style/SubscriptSpan.java b/core/java/android/text/style/SubscriptSpan.java index de1d8b2..f1b0d38 100644 --- a/core/java/android/text/style/SubscriptSpan.java +++ b/core/java/android/text/style/SubscriptSpan.java @@ -29,6 +29,11 @@ public class SubscriptSpan extends MetricAffectingSpan implements ParcelableSpan } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.SUBSCRIPT_SPAN; } @@ -37,6 +42,11 @@ public class SubscriptSpan extends MetricAffectingSpan implements ParcelableSpan } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { } @Override diff --git a/core/java/android/text/style/SuggestionRangeSpan.java b/core/java/android/text/style/SuggestionRangeSpan.java index 2dbfc72..c1943d5 100644 --- a/core/java/android/text/style/SuggestionRangeSpan.java +++ b/core/java/android/text/style/SuggestionRangeSpan.java @@ -46,11 +46,21 @@ public class SuggestionRangeSpan extends CharacterStyle implements ParcelableSpa @Override public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeInt(mBackgroundColor); } @Override public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.SUGGESTION_RANGE_SPAN; } diff --git a/core/java/android/text/style/SuggestionSpan.java b/core/java/android/text/style/SuggestionSpan.java index 8b40953..6b449f9 100644 --- a/core/java/android/text/style/SuggestionSpan.java +++ b/core/java/android/text/style/SuggestionSpan.java @@ -248,6 +248,11 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan { @Override public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeStringArray(mSuggestions); dest.writeInt(mFlags); dest.writeString(mLocaleString); @@ -264,6 +269,11 @@ public class SuggestionSpan extends CharacterStyle implements ParcelableSpan { @Override public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.SUGGESTION_SPAN; } diff --git a/core/java/android/text/style/SuperscriptSpan.java b/core/java/android/text/style/SuperscriptSpan.java index 285fe84..abcf688 100644 --- a/core/java/android/text/style/SuperscriptSpan.java +++ b/core/java/android/text/style/SuperscriptSpan.java @@ -29,6 +29,11 @@ public class SuperscriptSpan extends MetricAffectingSpan implements ParcelableSp } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.SUPERSCRIPT_SPAN; } @@ -37,6 +42,11 @@ public class SuperscriptSpan extends MetricAffectingSpan implements ParcelableSp } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { } @Override diff --git a/core/java/android/text/style/TextAppearanceSpan.java b/core/java/android/text/style/TextAppearanceSpan.java index ecbf4bc..abbd793 100644 --- a/core/java/android/text/style/TextAppearanceSpan.java +++ b/core/java/android/text/style/TextAppearanceSpan.java @@ -136,6 +136,11 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.TEXT_APPEARANCE_SPAN; } @@ -144,6 +149,11 @@ public class TextAppearanceSpan extends MetricAffectingSpan implements Parcelabl } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeString(mTypeface); dest.writeInt(mStyle); dest.writeInt(mTextSize); diff --git a/core/java/android/text/style/TtsSpan.java b/core/java/android/text/style/TtsSpan.java index 342a183..c40f11f 100644 --- a/core/java/android/text/style/TtsSpan.java +++ b/core/java/android/text/style/TtsSpan.java @@ -495,12 +495,22 @@ public class TtsSpan implements ParcelableSpan { @Override public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeString(mType); dest.writePersistableBundle(mArgs); } @Override public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.TTS_SPAN; } diff --git a/core/java/android/text/style/TypefaceSpan.java b/core/java/android/text/style/TypefaceSpan.java index f194060..aa622d8 100644 --- a/core/java/android/text/style/TypefaceSpan.java +++ b/core/java/android/text/style/TypefaceSpan.java @@ -42,6 +42,11 @@ public class TypefaceSpan extends MetricAffectingSpan implements ParcelableSpan } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.TYPEFACE_SPAN; } @@ -50,6 +55,11 @@ public class TypefaceSpan extends MetricAffectingSpan implements ParcelableSpan } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeString(mFamily); } diff --git a/core/java/android/text/style/URLSpan.java b/core/java/android/text/style/URLSpan.java index 0669b6f..58239ef 100644 --- a/core/java/android/text/style/URLSpan.java +++ b/core/java/android/text/style/URLSpan.java @@ -40,6 +40,11 @@ public class URLSpan extends ClickableSpan implements ParcelableSpan { } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.URL_SPAN; } @@ -48,6 +53,11 @@ public class URLSpan extends ClickableSpan implements ParcelableSpan { } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { dest.writeString(mURL); } diff --git a/core/java/android/text/style/UnderlineSpan.java b/core/java/android/text/style/UnderlineSpan.java index 80b2427..9024dcd 100644 --- a/core/java/android/text/style/UnderlineSpan.java +++ b/core/java/android/text/style/UnderlineSpan.java @@ -30,6 +30,11 @@ public class UnderlineSpan extends CharacterStyle } public int getSpanTypeId() { + return getSpanTypeIdInternal(); + } + + /** @hide */ + public int getSpanTypeIdInternal() { return TextUtils.UNDERLINE_SPAN; } @@ -38,6 +43,11 @@ public class UnderlineSpan extends CharacterStyle } public void writeToParcel(Parcel dest, int flags) { + writeToParcelInternal(dest, flags); + } + + /** @hide */ + public void writeToParcelInternal(Parcel dest, int flags) { } @Override diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java index 6e2d110..664c02a 100644 --- a/core/java/android/view/AccessibilityInteractionController.java +++ b/core/java/android/view/AccessibilityInteractionController.java @@ -19,6 +19,7 @@ package android.view; import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; +import android.os.Binder; import android.os.Bundle; import android.os.Handler; import android.os.Looper; @@ -158,7 +159,9 @@ final class AccessibilityInteractionController { try { mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0; applyAppScaleAndMagnificationSpecIfNeeded(infos, spec); - if (spec != null) { + // Recycle if called from another process. Specs are cached in the + // system process and obtained from a pool when read from parcel. + if (spec != null && android.os.Process.myPid() != Binder.getCallingPid()) { spec.recycle(); } adjustIsVisibleToUserIfNeeded(infos, interactiveRegion); @@ -167,6 +170,12 @@ final class AccessibilityInteractionController { } catch (RemoteException re) { /* ignore - the other side will time out */ } + + // Recycle if called from the same process. Regions are obtained in + // the system process and instantiated when read from parcel. + if (interactiveRegion != null && android.os.Process.myPid() == Binder.getCallingPid()) { + interactiveRegion.recycle(); + } } } @@ -244,7 +253,9 @@ final class AccessibilityInteractionController { try { mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0; applyAppScaleAndMagnificationSpecIfNeeded(infos, spec); - if (spec != null) { + // Recycle if called from another process. Specs are cached in the + // system process and obtained from a pool when read from parcel. + if (spec != null && android.os.Process.myPid() != Binder.getCallingPid()) { spec.recycle(); } adjustIsVisibleToUserIfNeeded(infos, interactiveRegion); @@ -252,6 +263,12 @@ final class AccessibilityInteractionController { } catch (RemoteException re) { /* ignore - the other side will time out */ } + + // Recycle if called from the same process. Regions are obtained in + // the system process and instantiated when read from parcel. + if (interactiveRegion != null && android.os.Process.myPid() == Binder.getCallingPid()) { + interactiveRegion.recycle(); + } } } @@ -354,7 +371,9 @@ final class AccessibilityInteractionController { try { mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0; applyAppScaleAndMagnificationSpecIfNeeded(infos, spec); - if (spec != null) { + // Recycle if called from another process. Specs are cached in the + // system process and obtained from a pool when read from parcel. + if (spec != null && android.os.Process.myPid() != Binder.getCallingPid()) { spec.recycle(); } adjustIsVisibleToUserIfNeeded(infos, interactiveRegion); @@ -362,6 +381,12 @@ final class AccessibilityInteractionController { } catch (RemoteException re) { /* ignore - the other side will time out */ } + + // Recycle if called from the same process. Regions are obtained in + // the system process and instantiated when read from parcel. + if (interactiveRegion != null && android.os.Process.myPid() == Binder.getCallingPid()) { + interactiveRegion.recycle(); + } } } @@ -468,7 +493,9 @@ final class AccessibilityInteractionController { try { mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0; applyAppScaleAndMagnificationSpecIfNeeded(focused, spec); - if (spec != null) { + // Recycle if called from another process. Specs are cached in the + // system process and obtained from a pool when read from parcel. + if (spec != null && android.os.Process.myPid() != Binder.getCallingPid()) { spec.recycle(); } adjustIsVisibleToUserIfNeeded(focused, interactiveRegion); @@ -476,6 +503,12 @@ final class AccessibilityInteractionController { } catch (RemoteException re) { /* ignore - the other side will time out */ } + + // Recycle if called from the same process. Regions are obtained in + // the system process and instantiated when read from parcel. + if (interactiveRegion != null && android.os.Process.myPid() == Binder.getCallingPid()) { + interactiveRegion.recycle(); + } } } @@ -545,7 +578,9 @@ final class AccessibilityInteractionController { try { mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0; applyAppScaleAndMagnificationSpecIfNeeded(next, spec); - if (spec != null) { + // Recycle if called from another process. Specs are cached in the + // system process and obtained from a pool when read from parcel. + if (spec != null && android.os.Process.myPid() != Binder.getCallingPid()) { spec.recycle(); } adjustIsVisibleToUserIfNeeded(next, interactiveRegion); @@ -553,6 +588,12 @@ final class AccessibilityInteractionController { } catch (RemoteException re) { /* ignore - the other side will time out */ } + + // Recycle if called from the same process. Regions are obtained in + // the system process and instantiated when read from parcel. + if (interactiveRegion != null && android.os.Process.myPid() == Binder.getCallingPid()) { + interactiveRegion.recycle(); + } } } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 37c8100..126540f 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -7366,7 +7366,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @hide */ public void getOutsets(Rect outOutsetRect) { - outOutsetRect.set(mAttachInfo.mOutsets); + if (mAttachInfo != null) { + outOutsetRect.set(mAttachInfo.mOutsets); + } else { + outOutsetRect.setEmpty(); + } } /** @@ -17111,6 +17115,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * Also calls {@link StateListAnimator#jumpToCurrentState()} if there is a StateListAnimator * attached to this view. */ + @CallSuper public void jumpDrawablesToCurrentState() { if (mBackground != null) { mBackground.jumpToCurrentState(); @@ -17560,13 +17565,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see Drawable#setTintMode(PorterDuff.Mode) */ public void setForegroundTintMode(@Nullable PorterDuff.Mode tintMode) { - if (mBackgroundTint == null) { - mBackgroundTint = new TintInfo(); + if (mForegroundInfo == null) { + mForegroundInfo = new ForegroundInfo(); } - mBackgroundTint.mTintMode = tintMode; - mBackgroundTint.mHasTintMode = true; + if (mForegroundInfo.mTintInfo == null) { + mForegroundInfo.mTintInfo = new TintInfo(); + } + mForegroundInfo.mTintInfo.mTintMode = tintMode; + mForegroundInfo.mTintInfo.mHasTintMode = true; - applyBackgroundTint(); + applyForegroundTint(); } /** @@ -17576,7 +17584,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @return the blending mode used to apply the tint to the foreground * drawable * @attr ref android.R.styleable#View_foregroundTintMode - * @see #setBackgroundTintMode(PorterDuff.Mode) + * @see #setForegroundTintMode(PorterDuff.Mode) */ @Nullable public PorterDuff.Mode getForegroundTintMode() { @@ -18286,7 +18294,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback, if (accessibilityId < 0) { return null; } - return findViewByAccessibilityIdTraversal(accessibilityId); + View view = findViewByAccessibilityIdTraversal(accessibilityId); + if (view != null) { + return view.includeForAccessibility() ? view : null; + } + return null; } /** diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index e015c04..dd32f85 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -1173,6 +1173,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (foundView != null) { return foundView; } + + if (getAccessibilityNodeProvider() != null) { + return null; + } + final int childrenCount = mChildrenCount; final View[] children = mChildren; for (int i = 0; i < childrenCount; i++) { @@ -1182,6 +1187,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager return foundView; } } + return null; } diff --git a/core/java/android/view/ViewStructure.java b/core/java/android/view/ViewStructure.java index 886547a..e525474 100644 --- a/core/java/android/view/ViewStructure.java +++ b/core/java/android/view/ViewStructure.java @@ -18,7 +18,6 @@ package android.view; import android.graphics.Rect; import android.os.Bundle; -import android.text.TextPaint; /** * Container for storing additional per-view data generated by {@link View#onProvideStructure diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index f7b6405..ca5f5ad 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -1058,6 +1058,13 @@ public interface WindowManagerPolicy { public boolean isKeyguardSecure(); /** + * Return whether the keyguard is on. + * + * @return true if in keyguard is on. + */ + public boolean isKeyguardShowingOrOccluded(); + + /** * inKeyguardRestrictedKeyInputMode * * if keyguard screen is showing or in restricted key input mode (i.e. in diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java index c2f3777..4ee155c 100644 --- a/core/java/android/view/inputmethod/InputMethodSubtype.java +++ b/core/java/android/view/inputmethod/InputMethodSubtype.java @@ -16,6 +16,7 @@ package android.view.inputmethod; +import android.annotation.Nullable; import android.content.Context; import android.content.pm.ApplicationInfo; import android.os.Parcel; @@ -323,6 +324,19 @@ public final class InputMethodSubtype implements Parcelable { } /** + * @return The normalized {@link Locale} object of the subtype. The returned locale may or may + * not equal to "locale" string parameter passed to the constructor. + * + * <p>TODO: Consider to make this a public API.</p> + * @hide + */ + @Nullable + public Locale getLocaleObject() { + // TODO: Move the following method from InputMethodUtils to InputMethodSubtype. + return InputMethodUtils.constructLocaleFromString(mSubtypeLocale); + } + + /** * @return The mode of the subtype. */ public String getMode() { @@ -381,7 +395,7 @@ public final class InputMethodSubtype implements Parcelable { */ public CharSequence getDisplayName( Context context, String packageName, ApplicationInfo appInfo) { - final Locale locale = InputMethodUtils.constructLocaleFromString(mSubtypeLocale); + final Locale locale = getLocaleObject(); final String localeStr = locale != null ? locale.getDisplayName() : mSubtypeLocale; if (mSubtypeNameResId == 0) { return localeStr; diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index a3332fa..a0d1930 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -2345,8 +2345,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } - // Scrap view implies temporary detachment. isScrap[0] = true; + + // Finish the temporary detach started in addScrapView(). + transientView.dispatchFinishTemporaryDetach(); return transientView; } @@ -2359,6 +2361,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } else { isScrap[0] = true; + // Finish the temporary detach started in addScrapView(). child.dispatchFinishTemporaryDetach(); } } diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java index 260854f..027f6d6 100644 --- a/core/java/android/widget/ArrayAdapter.java +++ b/core/java/android/widget/ArrayAdapter.java @@ -52,12 +52,6 @@ import java.util.List; */ public class ArrayAdapter<T> extends BaseAdapter implements Filterable, ThemedSpinnerAdapter { /** - * Contains the list of objects that represent the data of this ArrayAdapter. - * The content of this list is referred to as "the array" in the documentation. - */ - private List<T> mObjects; - - /** * Lock used to modify the content of {@link #mObjects}. Any write operation * performed on the array should be synchronized on this lock. This lock is also * used by the filter (see {@link #getFilter()} to make a synchronized copy of @@ -65,6 +59,14 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable, ThemedSp */ private final Object mLock = new Object(); + private final LayoutInflater mInflater; + + /** + * Contains the list of objects that represent the data of this ArrayAdapter. + * The content of this list is referred to as "the array" in the documentation. + */ + private List<T> mObjects; + /** * The resource indicating what views to inflate to display the content of this * array adapter. @@ -97,8 +99,6 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable, ThemedSp private ArrayList<T> mOriginalValues; private ArrayFilter mFilter; - private LayoutInflater mInflater; - /** Layout inflater used for {@link #getDropDownView(int, View, ViewGroup)}. */ private LayoutInflater mDropDownInflater; @@ -442,9 +442,6 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable, ThemedSp return mDropDownInflater == null ? null : mDropDownInflater.getContext().getTheme(); } - /** - * {@inheritDoc} - */ @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { final LayoutInflater inflater = mDropDownInflater == null ? mInflater : mDropDownInflater; diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 0cac529..56f9b5c 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -1004,14 +1004,14 @@ public class Editor { stopSelectionActionMode(); } else { stopSelectionActionMode(); - startSelectionActionModeWithSelectionAndStartDrag(); + selectCurrentWordAndStartDrag(); } handled = true; } // Start a new selection if (!handled) { - handled = startSelectionActionModeWithSelectionAndStartDrag(); + handled = selectCurrentWordAndStartDrag(); } return handled; @@ -1724,22 +1724,9 @@ public class Editor { } /** - * Starts a Selection Action Mode with the current selection and enters drag mode. This should - * be used whenever the mode is started from a touch event. - * - * @return true if the selection mode was actually started. - */ - private boolean startSelectionActionModeWithSelectionAndStartDrag() { - boolean selectionStarted = startSelectionActionModeWithSelectionInternal(); - if (selectionStarted) { - getSelectionController().enterDrag(); - } - return selectionStarted; - } - - /** * Starts a Selection Action Mode with the current selection and ensures the selection handles - * are shown. This should be used when the mode is started from a non-touch event. + * are shown if there is a selection, otherwise the insertion handle is shown. This should be + * used when the mode is started from a non-touch event. * * @return true if the selection mode was actually started. */ @@ -1747,38 +1734,65 @@ public class Editor { boolean selectionStarted = startSelectionActionModeWithSelectionInternal(); if (selectionStarted) { getSelectionController().show(); + } else if (getInsertionController() != null) { + getInsertionController().show(); } return selectionStarted; } - private boolean startSelectionActionModeWithSelectionInternal() { + /** + * If the TextView allows text selection, selects the current word when no existing selection + * was available and starts a drag. + * + * @return true if the drag was started. + */ + private boolean selectCurrentWordAndStartDrag() { if (extractedTextModeWillBeStarted()) { // Cancel the single tap delayed runnable. if (mSelectionModeWithoutSelectionRunnable != null) { mTextView.removeCallbacks(mSelectionModeWithoutSelectionRunnable); } - return false; } - if (mSelectionActionMode != null) { - // Selection action mode is already started - mSelectionActionMode.invalidate(); + mSelectionActionMode.finish(); + } + if (!checkFieldAndSelectCurrentWord()) { return false; } + getSelectionController().enterDrag(); + return true; + } + /** + * Checks whether a selection can be performed on the current TextView and if so selects + * the current word. + * + * @return true if there already was a selection or if the current word was selected. + */ + private boolean checkFieldAndSelectCurrentWord() { if (!mTextView.canSelectText() || !mTextView.requestFocus()) { Log.w(TextView.LOG_TAG, - "TextView does not support text selection. Action mode cancelled."); + "TextView does not support text selection. Selection cancelled."); return false; } if (!mTextView.hasSelection()) { // There may already be a selection on device rotation - if (!selectCurrentWord()) { - // No word found under cursor or text selection not permitted. - return false; - } + return selectCurrentWord(); + } + return true; + } + + private boolean startSelectionActionModeWithSelectionInternal() { + if (mSelectionActionMode != null) { + // Selection action mode is already started + mSelectionActionMode.invalidate(); + return false; + } + + if (!checkFieldAndSelectCurrentWord()) { + return false; } boolean willExtract = extractedTextModeWillBeStarted(); @@ -1829,12 +1843,18 @@ public class Editor { } if (selectionStart == selectionEnd) { // Spans overlap the cursor. - return true; + for (int i = 0; i < suggestionSpans.length; i++) { + if (suggestionSpans[i].getSuggestions().length > 0) { + return true; + } + } + return false; } int minSpanStart = mTextView.getText().length(); int maxSpanEnd = 0; int unionOfSpansCoveringSelectionStartStart = mTextView.getText().length(); int unionOfSpansCoveringSelectionStartEnd = 0; + boolean hasValidSuggestions = false; for (int i = 0; i < suggestionSpans.length; i++) { final int spanStart = spannable.getSpanStart(suggestionSpans[i]); final int spanEnd = spannable.getSpanEnd(suggestionSpans[i]); @@ -1844,11 +1864,16 @@ public class Editor { // The span doesn't cover the current selection start point. continue; } + hasValidSuggestions = + hasValidSuggestions || suggestionSpans[i].getSuggestions().length > 0; unionOfSpansCoveringSelectionStartStart = Math.min(unionOfSpansCoveringSelectionStartStart, spanStart); unionOfSpansCoveringSelectionStartEnd = Math.max(unionOfSpansCoveringSelectionStartEnd, spanEnd); } + if (!hasValidSuggestions) { + return false; + } if (unionOfSpansCoveringSelectionStartStart >= unionOfSpansCoveringSelectionStartEnd) { // No spans cover the selection start point. return false; @@ -4071,12 +4096,17 @@ public class Editor { offset = getNextCursorOffset(selectionEnd, false); mTouchWordDelta = 0.0f; } - mInWord = !getWordIteratorWithText().isBoundary(offset); positionAtCursorOffset(offset, false); } } @Override + protected void positionAtCursorOffset(int offset, boolean parentScrolled) { + super.positionAtCursorOffset(offset, parentScrolled); + mInWord = !getWordIteratorWithText().isBoundary(offset); + } + + @Override public boolean onTouchEvent(MotionEvent event) { boolean superResult = super.onTouchEvent(event); if (event.getActionMasked() == MotionEvent.ACTION_UP) { @@ -4193,12 +4223,17 @@ public class Editor { offset = getNextCursorOffset(selectionStart, true); mTouchWordDelta = 0.0f; } - mInWord = !getWordIteratorWithText().isBoundary(offset); positionAtCursorOffset(offset, false); } } @Override + protected void positionAtCursorOffset(int offset, boolean parentScrolled) { + super.positionAtCursorOffset(offset, parentScrolled); + mInWord = !getWordIteratorWithText().isBoundary(offset); + } + + @Override public boolean onTouchEvent(MotionEvent event) { boolean superResult = super.onTouchEvent(event); if (event.getActionMasked() == MotionEvent.ACTION_UP) { @@ -4377,7 +4412,7 @@ public class Editor { boolean stayedInArea = distanceSquared < doubleTapSlop * doubleTapSlop; if (stayedInArea && isPositionOnText(eventX, eventY)) { - startSelectionActionModeWithSelectionAndStartDrag(); + selectCurrentWordAndStartDrag(); mDiscardNextActionUp = true; } } @@ -4480,6 +4515,7 @@ public class Editor { mEndHandle.showAtLocation(endOffset); // No longer the first dragging motion, reset. + startSelectionActionModeWithSelection(); mDragAcceleratorActive = false; mStartOffset = -1; } diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java index cf67905..ebc7eb3 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -1505,11 +1505,9 @@ public class HorizontalScrollView extends FrameLayout { final int scrollRange = Math.max(0, childWidth - (r - l - mPaddingLeft - mPaddingRight)); if (mSavedState != null) { - if (isLayoutRtl() == mSavedState.isLayoutRtl) { - mScrollX = mSavedState.scrollPosition; - } else { - mScrollX = scrollRange - mSavedState.scrollPosition; - } + mScrollX = isLayoutRtl() + ? scrollRange - mSavedState.scrollOffsetFromStart + : mSavedState.scrollOffsetFromStart; mSavedState = null; } else { if (isLayoutRtl()) { @@ -1692,8 +1690,7 @@ public class HorizontalScrollView extends FrameLayout { } Parcelable superState = super.onSaveInstanceState(); SavedState ss = new SavedState(superState); - ss.scrollPosition = mScrollX; - ss.isLayoutRtl = isLayoutRtl(); + ss.scrollOffsetFromStart = isLayoutRtl() ? -mScrollX : mScrollX; return ss; } @@ -1705,8 +1702,7 @@ public class HorizontalScrollView extends FrameLayout { } static class SavedState extends BaseSavedState { - public int scrollPosition; - public boolean isLayoutRtl; + public int scrollOffsetFromStart; SavedState(Parcelable superState) { super(superState); @@ -1714,23 +1710,21 @@ public class HorizontalScrollView extends FrameLayout { public SavedState(Parcel source) { super(source); - scrollPosition = source.readInt(); - isLayoutRtl = (source.readInt() == 0) ? true : false; + scrollOffsetFromStart = source.readInt(); } @Override public void writeToParcel(Parcel dest, int flags) { super.writeToParcel(dest, flags); - dest.writeInt(scrollPosition); - dest.writeInt(isLayoutRtl ? 1 : 0); + dest.writeInt(scrollOffsetFromStart); } @Override public String toString() { return "HorizontalScrollView.SavedState{" + Integer.toHexString(System.identityHashCode(this)) - + " scrollPosition=" + scrollPosition - + " isLayoutRtl=" + isLayoutRtl + "}"; + + " scrollPosition=" + scrollOffsetFromStart + + "}"; } public static final Parcelable.Creator<SavedState> CREATOR diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java index 16dc26d..e7d9226 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -16,6 +16,7 @@ package android.widget; +import android.annotation.CallSuper; import android.annotation.IntDef; import android.annotation.Widget; import android.content.Context; @@ -608,7 +609,16 @@ public class NumberPicker extends LinearLayout { mSolidColor = attributesArray.getColor(R.styleable.NumberPicker_solidColor, 0); - mSelectionDivider = attributesArray.getDrawable(R.styleable.NumberPicker_selectionDivider); + final Drawable selectionDivider = attributesArray.getDrawable( + R.styleable.NumberPicker_selectionDivider); + if (selectionDivider != null) { + selectionDivider.setCallback(this); + selectionDivider.setLayoutDirection(getLayoutDirection()); + if (selectionDivider.isStateful()) { + selectionDivider.setState(getDrawableState()); + } + } + mSelectionDivider = selectionDivider; final int defSelectionDividerHeight = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT, @@ -1499,6 +1509,38 @@ public class NumberPicker extends LinearLayout { removeAllCallbacks(); } + @CallSuper + @Override + protected void drawableStateChanged() { + super.drawableStateChanged(); + + final int[] state = getDrawableState(); + + if (mSelectionDivider != null && mSelectionDivider.isStateful()) { + mSelectionDivider.setState(state); + } + } + + @CallSuper + @Override + public void jumpDrawablesToCurrentState() { + super.jumpDrawablesToCurrentState(); + + if (mSelectionDivider != null) { + mSelectionDivider.jumpToCurrentState(); + } + } + + /** @hide */ + @Override + public void onResolveDrawables(@ResolvedLayoutDir int layoutDirection) { + super.onResolveDrawables(layoutDirection); + + if (mSelectionDivider != null) { + mSelectionDivider.setLayoutDirection(layoutDirection); + } + } + @Override protected void onDraw(Canvas canvas) { if (!mHasSelectorWheel) { diff --git a/core/java/android/widget/SimpleAdapter.java b/core/java/android/widget/SimpleAdapter.java index e7760ee..3bf9485 100644 --- a/core/java/android/widget/SimpleAdapter.java +++ b/core/java/android/widget/SimpleAdapter.java @@ -52,6 +52,8 @@ import java.util.Map; * If no appropriate binding can be found, an {@link IllegalStateException} is thrown. */ public class SimpleAdapter extends BaseAdapter implements Filterable, ThemedSpinnerAdapter { + private final LayoutInflater mInflater; + private int[] mTo; private String[] mFrom; private ViewBinder mViewBinder; @@ -60,7 +62,6 @@ public class SimpleAdapter extends BaseAdapter implements Filterable, ThemedSpin private int mResource; private int mDropDownResource; - private LayoutInflater mInflater; /** Layout inflater used for {@link #getDropDownView(int, View, ViewGroup)}. */ private LayoutInflater mDropDownInflater; @@ -174,8 +175,8 @@ public class SimpleAdapter extends BaseAdapter implements Filterable, ThemedSpin @Override public View getDropDownView(int position, View convertView, ViewGroup parent) { - return createViewFromResource( - mDropDownInflater, position, convertView, parent, mDropDownResource); + final LayoutInflater inflater = mDropDownInflater == null ? mInflater : mDropDownInflater; + return createViewFromResource(inflater, position, convertView, parent, mDropDownResource); } private void bindView(int position, View view) { diff --git a/core/java/android/widget/TabHost.java b/core/java/android/widget/TabHost.java index c521f72..27fa3b9 100644 --- a/core/java/android/widget/TabHost.java +++ b/core/java/android/widget/TabHost.java @@ -188,32 +188,9 @@ mTabHost.addTab(TAB_TAG_1, "Hello, world!", "Tab 1"); mLocalActivityManager = activityGroup; } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - final ViewTreeObserver treeObserver = getViewTreeObserver(); - treeObserver.addOnTouchModeChangeListener(this); - } - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - final ViewTreeObserver treeObserver = getViewTreeObserver(); - treeObserver.removeOnTouchModeChangeListener(this); - } - - /** - * {@inheritDoc} - */ public void onTouchModeChanged(boolean isInTouchMode) { - if (!isInTouchMode) { - // leaving touch mode.. if nothing has focus, let's give it to - // the indicator of the current tab - if (mCurrentView != null && (!mCurrentView.hasFocus() || mCurrentView.isFocused())) { - mTabWidget.getChildTabViewAt(mCurrentTab).requestFocus(); - } - } + // No longer used, but kept to maintain API compatibility. } /** diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index e14e39c..3a85476 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -6680,7 +6680,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener StaticLayout.Builder builder = StaticLayout.Builder.obtain(mHint, 0, mHint.length(), mTextPaint, hintWidth) .setAlignment(alignment) - .setTextDir(mTextDir) + .setTextDirection(mTextDir) .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy) @@ -6771,7 +6771,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener StaticLayout.Builder builder = StaticLayout.Builder.obtain(mTransformed, 0, mTransformed.length(), mTextPaint, wantWidth) .setAlignment(alignment) - .setTextDir(mTextDir) + .setTextDirection(mTextDir) .setLineSpacing(mSpacingAdd, mSpacingMult) .setIncludePad(mIncludePad) .setBreakStrategy(mBreakStrategy) diff --git a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java index ce94727..e607a3f 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java +++ b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.pm.PackageManager; import android.text.TextUtils; import android.util.Log; +import android.util.Printer; import android.util.Slog; import android.view.inputmethod.InputMethodInfo; import android.view.inputmethod.InputMethodSubtype; @@ -314,6 +315,15 @@ public class InputMethodSubtypeSwitchingController { } return null; } + + protected void dump(final Printer pw, final String prefix) { + final int N = mImeSubtypeList.size(); + for (int i = 0; i < N; ++i) { + final int rank = i; + final ImeSubtypeListItem item = mImeSubtypeList.get(i); + pw.println(prefix + "rank=" + rank + " item=" + item); + } + } } private static class DynamicRotationList { @@ -388,6 +398,14 @@ public class InputMethodSubtypeSwitchingController { } return null; } + + protected void dump(final Printer pw, final String prefix) { + for (int i = 0; i < mUsageHistoryOfSubtypeListItemIndex.length; ++i) { + final int rank = mUsageHistoryOfSubtypeListItemIndex[i]; + final ImeSubtypeListItem item = mImeSubtypeList.get(i); + pw.println(prefix + "rank=" + rank + " item=" + item); + } + } } @VisibleForTesting @@ -478,6 +496,13 @@ public class InputMethodSubtypeSwitchingController { } return result; } + + protected void dump(final Printer pw) { + pw.println(" mSwitchingAwareRotationList:"); + mSwitchingAwareRotationList.dump(pw, " "); + pw.println(" mSwitchingUnawareRotationList:"); + mSwitchingUnawareRotationList.dump(pw, " "); + } } private final InputMethodSettings mSettings; @@ -526,4 +551,12 @@ public class InputMethodSubtypeSwitchingController { return mSubtypeList.getSortedInputMethodAndSubtypeList( showSubtypes, includingAuxiliarySubtypes, isScreenLocked); } + + public void dump(final Printer pw) { + if (mController != null) { + mController.dump(pw); + } else { + pw.println(" mController=null"); + } + } } diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java index 06bdb24..042db71 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java +++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java @@ -379,6 +379,14 @@ public class InputMethodUtils { // The length of localeStr is guaranteed to always return a 1 <= value <= 3 // because localeStr is not empty. if (localeParams.length == 1) { + if (localeParams.length >= 1 && "tl".equals(localeParams[0])) { + // Convert a locale whose language is "tl" to one whose language is "fil". + // For example, "tl_PH" will get converted to "fil_PH". + // Versions of Android earlier than Lollipop did not support three letter language + // codes, and used "tl" (Tagalog) as the language string for "fil" (Filipino). + // On Lollipop and above, the current three letter version must be used. + localeParams[0] = "fil"; + } return new Locale(localeParams[0]); } else if (localeParams.length == 2) { return new Locale(localeParams[0], localeParams[1]); @@ -397,7 +405,7 @@ public class InputMethodUtils { for (int i = 0; i < N; ++i) { final InputMethodSubtype subtype = imi.getSubtypeAt(i); if (checkCountry) { - final Locale subtypeLocale = constructLocaleFromString(subtype.getLocale()); + final Locale subtypeLocale = subtype.getLocaleObject(); if (subtypeLocale == null || !TextUtils.equals(subtypeLocale.getLanguage(), locale.getLanguage()) || !TextUtils.equals(subtypeLocale.getCountry(), locale.getCountry())) { diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java index 1fc0ac3..c77d614 100644 --- a/core/java/com/android/internal/widget/FloatingToolbar.java +++ b/core/java/com/android/internal/widget/FloatingToolbar.java @@ -37,6 +37,7 @@ import android.view.View.MeasureSpec; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.Window; +import android.view.WindowInsets; import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.AnimationSet; @@ -83,7 +84,7 @@ public final class FloatingToolbar { private final Rect mContentRect = new Rect(); private Menu mMenu; - private List<CharSequence> mShowingTitles = new ArrayList<CharSequence>(); + private List<Object> mShowingMenuItems = new ArrayList<Object>(); private MenuItem.OnMenuItemClickListener mMenuItemClickListener = NO_OP_MENUITEM_CLICK_LISTENER; private int mSuggestedWidth; @@ -155,7 +156,7 @@ public final class FloatingToolbar { if (!isCurrentlyShowing(menuItems) || mWidthChanged) { mPopup.dismiss(); mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth); - mShowingTitles = getMenuItemTitles(menuItems); + mShowingMenuItems = getShowingMenuItemsReferences(menuItems); } mPopup.updateCoordinates(mContentRect); if (!mPopup.isShowing()) { @@ -210,7 +211,7 @@ public final class FloatingToolbar { * Returns true if this floating toolbar is currently showing the specified menu items. */ private boolean isCurrentlyShowing(List<MenuItem> menuItems) { - return mShowingTitles.equals(getMenuItemTitles(menuItems)); + return mShowingMenuItems.equals(getShowingMenuItemsReferences(menuItems)); } /** @@ -233,12 +234,16 @@ public final class FloatingToolbar { return menuItems; } - private List<CharSequence> getMenuItemTitles(List<MenuItem> menuItems) { - List<CharSequence> titles = new ArrayList<CharSequence>(); + private List<Object> getShowingMenuItemsReferences(List<MenuItem> menuItems) { + List<Object> references = new ArrayList<Object>(); for (MenuItem menuItem : menuItems) { - titles.add(menuItem.getTitle()); + if (isIconOnlyMenuItem(menuItem)) { + references.add(menuItem.getIcon()); + } else { + references.add(menuItem.getTitle()); + } } - return titles; + return references; } @@ -289,7 +294,6 @@ public final class FloatingToolbar { public void onAnimationRepeat(Animation animation) { } }; - private final AnimatorSet mShowAnimation; private final AnimatorSet mDismissAnimation; private final AnimatorSet mHideAnimation; private final AnimationSet mOpenOverflowAnimation = new AnimationSet(true) { @@ -324,6 +328,7 @@ public final class FloatingToolbar { } }; + private final Rect mViewPort = new Rect(); private final Point mCoords = new Point(); private final Region mTouchableRegion = new Region(); @@ -353,14 +358,9 @@ public final class FloatingToolbar { * from. */ public FloatingToolbarPopup(View parent) { - mMarginHorizontal = parent.getResources() - .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin); - mMarginVertical = parent.getResources() - .getDimensionPixelSize(R.dimen.floating_toolbar_vertical_margin); mParent = Preconditions.checkNotNull(parent); mContentContainer = createContentContainer(parent.getContext()); mPopupWindow = createPopupWindow(mContentContainer); - mShowAnimation = createGrowFadeInFromBottom(mContentContainer, mMarginHorizontal); mDismissAnimation = createShrinkFadeOutFromBottomAnimation( mContentContainer, 150, // startDelay @@ -380,6 +380,10 @@ public final class FloatingToolbar { mPopupWindow.dismiss(); } }); + mMarginHorizontal = parent.getResources() + .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin); + mMarginVertical = parent.getResources() + .getDimensionPixelSize(R.dimen.floating_toolbar_vertical_margin); } /** @@ -396,7 +400,7 @@ public final class FloatingToolbar { mMainPanel = new FloatingToolbarMainPanel(mParent.getContext(), mOpenOverflow); } List<MenuItem> overflowMenuItems = - mMainPanel.layoutMenuItems(menuItems, suggestedWidth); + mMainPanel.layoutMenuItems(menuItems, getToolbarWidth(suggestedWidth)); mMainPanel.setOnMenuItemClickListener(menuItemClickListener); if (!overflowMenuItems.isEmpty()) { if (mOverflowPanel == null) { @@ -432,7 +436,8 @@ public final class FloatingToolbar { // The "show" animation will make this visible. mContentContainer.setAlpha(0); } - updateOverflowHeight(contentRect.top - (mMarginVertical * 2)); + refreshViewPort(); + updateOverflowHeight(contentRect.top - (mMarginVertical * 2) - mViewPort.top); refreshCoordinatesAndOverflowDirection(contentRect); preparePopupContent(); mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, mCoords.x, mCoords.y); @@ -496,6 +501,7 @@ public final class FloatingToolbar { } cancelOverflowAnimations(); + refreshViewPort(); refreshCoordinatesAndOverflowDirection(contentRect); preparePopupContent(); mPopupWindow.update(mCoords.x, mCoords.y, getWidth(), getHeight()); @@ -523,18 +529,24 @@ public final class FloatingToolbar { } private void refreshCoordinatesAndOverflowDirection(Rect contentRect) { + // NOTE: Ensure that mViewPort has been refreshed before this. + int x = contentRect.centerX() - getWidth() / 2; int y; - if (contentRect.top > getHeight()) { + if (contentRect.top - getHeight() > mViewPort.top) { y = contentRect.top - getHeight(); mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_UP; - } else if (contentRect.top > getToolbarHeightWithVerticalMargin()) { + } else if (contentRect.top - getToolbarHeightWithVerticalMargin() > mViewPort.top) { y = contentRect.top - getToolbarHeightWithVerticalMargin(); mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_DOWN; } else { y = contentRect.bottom; mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_DOWN; } + + // Update x so that the toolbar isn't rendered behind the nav bar in landscape. + x = Math.max(0, Math.min(x, mViewPort.right - getWidth())); + mCoords.set(x, y); if (mOverflowPanel != null) { mOverflowPanel.setOverflowDirection(mOverflowDirection); @@ -549,7 +561,7 @@ public final class FloatingToolbar { * Performs the "show" animation on the floating popup. */ private void runShowAnimation() { - mShowAnimation.start(); + createGrowFadeInFromBottom(mContentContainer).start(); } /** @@ -597,7 +609,6 @@ public final class FloatingToolbar { final float startY = mContentContainer.getY(); final float left = mContentContainer.getX(); final float right = left + mContentContainer.getWidth(); - final boolean rtl = mContentContainer.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; Animation widthAnimation = new Animation() { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { @@ -605,7 +616,7 @@ public final class FloatingToolbar { int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth)); params.width = startWidth + deltaWidth; mContentContainer.setLayoutParams(params); - if (rtl) { + if (isRTL()) { mContentContainer.setX(left); } else { mContentContainer.setX(right - mContentContainer.getWidth()); @@ -656,7 +667,6 @@ public final class FloatingToolbar { final boolean morphedUpwards = (mOverflowDirection == OVERFLOW_DIRECTION_UP); final float left = mContentContainer.getX(); final float right = left + mContentContainer.getWidth(); - final boolean rtl = mContentContainer.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; Animation widthAnimation = new Animation() { @Override protected void applyTransformation(float interpolatedTime, Transformation t) { @@ -664,7 +674,7 @@ public final class FloatingToolbar { int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth)); params.width = startWidth + deltaWidth; mContentContainer.setLayoutParams(params); - if (rtl) { + if (isRTL()) { mContentContainer.setX(left); } else { mContentContainer.setX(right - mContentContainer.getWidth()); @@ -777,8 +787,13 @@ public final class FloatingToolbar { */ private void positionOverflowPanel() { Preconditions.checkNotNull(mOverflowPanel); - float x = mPopupWindow.getWidth() + float x; + if (isRTL()) { + x = mMarginHorizontal; + } else { + x = mPopupWindow.getWidth() - (mOverflowPanel.getView().getMeasuredWidth() + mMarginHorizontal); + } mContentContainer.setX(x); mContentContainer.setY(mMarginVertical); setContentAreaAsTouchableSurface(); @@ -820,6 +835,29 @@ public final class FloatingToolbar { mPopupWindow.setHeight(height + mMarginVertical * 2); } + + private void refreshViewPort() { + mParent.getGlobalVisibleRect(mViewPort); + WindowInsets windowInsets = mParent.getRootWindowInsets(); + mViewPort.set( + mViewPort.left + windowInsets.getStableInsetLeft(), + mViewPort.top + windowInsets.getStableInsetTop(), + mViewPort.right - windowInsets.getStableInsetRight(), + mViewPort.bottom - windowInsets.getStableInsetBottom()); + } + + private int getToolbarWidth(int suggestedWidth) { + int width = suggestedWidth; + refreshViewPort(); + int maximumWidth = mViewPort.width() - 2 * mParent.getResources() + .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin); + if (width <= 0) { + width = mParent.getResources() + .getDimensionPixelSize(R.dimen.floating_toolbar_preferred_width); + } + return Math.min(width, maximumWidth); + } + /** * Sets the touchable region of this popup to be zero. This means that all touch events on * this popup will go through to the surface behind it. @@ -856,6 +894,10 @@ public final class FloatingToolbar { viewTreeObserver.removeOnComputeInternalInsetsListener(mInsetsComputer); viewTreeObserver.addOnComputeInternalInsetsListener(mInsetsComputer); } + + private boolean isRTL() { + return mContentContainer.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; + } } /** @@ -901,12 +943,11 @@ public final class FloatingToolbar { * * @return The menu items that are not included in this main panel. */ - public List<MenuItem> layoutMenuItems(List<MenuItem> menuItems, int suggestedWidth) { + public List<MenuItem> layoutMenuItems(List<MenuItem> menuItems, int width) { Preconditions.checkNotNull(menuItems); - final int toolbarWidth = getAdjustedToolbarWidth(mContext, suggestedWidth) - // Reserve space for the "open overflow" button. - - getEstimatedOpenOverflowButtonWidth(mContext); + // Reserve space for the "open overflow" button. + final int toolbarWidth = width - getEstimatedOpenOverflowButtonWidth(mContext); int availableWidth = toolbarWidth; final LinkedList<MenuItem> remainingMenuItems = new LinkedList<MenuItem>(menuItems); @@ -1332,14 +1373,14 @@ public final class FloatingToolbar { * * @param view The view to animate */ - private static AnimatorSet createGrowFadeInFromBottom(View view, int x) { + private static AnimatorSet createGrowFadeInFromBottom(View view) { AnimatorSet growFadeInFromBottomAnimation = new AnimatorSet(); growFadeInFromBottomAnimation.playTogether( ObjectAnimator.ofFloat(view, View.SCALE_X, 0.5f, 1).setDuration(125), ObjectAnimator.ofFloat(view, View.SCALE_Y, 0.5f, 1).setDuration(125), ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(75), // Make sure that view.x is always fixed throughout the duration of this animation. - ObjectAnimator.ofFloat(view, View.X, x, x)); + ObjectAnimator.ofFloat(view, View.X, view.getX(), view.getX())); growFadeInFromBottomAnimation.setStartDelay(50); return growFadeInFromBottomAnimation; } diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp index 63395ed..d14fc0f 100644 --- a/core/jni/android/graphics/Paint.cpp +++ b/core/jni/android/graphics/Paint.cpp @@ -1055,7 +1055,8 @@ public: // TODO performance: optimize JNI array access jchar* textArray = env->GetCharArrayElements(text, NULL); jfloat result = doRunAdvance(paint, typeface, textArray + contextStart, - start - contextStart, end - start, contextEnd - contextStart, isRtl, offset); + start - contextStart, end - start, contextEnd - contextStart, isRtl, + offset - contextStart); env->ReleaseCharArrayElements(text, textArray, JNI_ABORT); return result; } diff --git a/core/jni/android_os_Trace.cpp b/core/jni/android_os_Trace.cpp index 52fd111..3fd3b3c 100644 --- a/core/jni/android_os_Trace.cpp +++ b/core/jni/android_os_Trace.cpp @@ -111,19 +111,19 @@ static JNINativeMethod gTraceMethods[] = { "()J", (void*)android_os_Trace_nativeGetEnabledTags }, { "nativeTraceCounter", - "(JLjava/lang/String;I)V", + "!(JLjava/lang/String;I)V", (void*)android_os_Trace_nativeTraceCounter }, { "nativeTraceBegin", - "(JLjava/lang/String;)V", + "!(JLjava/lang/String;)V", (void*)android_os_Trace_nativeTraceBegin }, { "nativeTraceEnd", - "(J)V", + "!(J)V", (void*)android_os_Trace_nativeTraceEnd }, { "nativeAsyncTraceBegin", - "(JLjava/lang/String;I)V", + "!(JLjava/lang/String;I)V", (void*)android_os_Trace_nativeAsyncTraceBegin }, { "nativeAsyncTraceEnd", - "(JLjava/lang/String;I)V", + "!(JLjava/lang/String;I)V", (void*)android_os_Trace_nativeAsyncTraceEnd }, { "nativeSetAppTracingAllowed", "(Z)V", diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 3fa92a8..abd2409 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -499,7 +499,7 @@ static void draw(JNIEnv* env, jclass clazz, jlong rendererPtr) { nsecs_t vsync = systemTime(CLOCK_MONOTONIC); UiFrameInfoBuilder(proxy->frameInfo()) .setVsync(vsync, vsync) - .addFlag(FrameInfoFlags::kSurfaceCanvas); + .addFlag(FrameInfoFlags::SurfaceCanvas); proxy->syncAndDrawFrame(); } diff --git a/core/res/res/drawable/number_picker_divider_material.xml b/core/res/res/drawable/number_picker_divider_material.xml new file mode 100644 index 0000000..2474be0 --- /dev/null +++ b/core/res/res/drawable/number_picker_divider_material.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2015 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<shape xmlns:android="http://schemas.android.com/apk/res/android" + android:tint="?attr/colorControlNormal" + android:shape="rectangle"> + <solid android:color="@color/black" /> +</shape> diff --git a/core/res/res/layout/number_picker_material.xml b/core/res/res/layout/number_picker_material.xml new file mode 100644 index 0000000..47edec4 --- /dev/null +++ b/core/res/res/layout/number_picker_material.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2015 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. +--> + +<view xmlns:android="http://schemas.android.com/apk/res/android" + class="android.widget.NumberPicker$CustomEditText" + android:id="@+id/numberpicker_input" + android:layout_width="fill_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:singleLine="true" + android:background="@null" + android:textAppearance="@style/TextAppearance.Material.Caption" /> diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 5f1eb41..189ebcb 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -1100,7 +1100,7 @@ <string name="permdesc_route_media_output" msgid="4932818749547244346">"Laat \'n program toe om media-uitvoere na ander eksterne toestelle te roeteer."</string> <string name="permlab_readInstallSessions" msgid="6165432407628065939">"Lees installasiesessies"</string> <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"Laat \'n program toe om installasiesessies te lees. Dit laat dit toe om besonderhede van aktiewe pakketinstallasies te sien."</string> - <string name="permlab_requestInstallPackages" msgid="1772330282283082214">"Versoek dat pakkette geïnstalleer word"</string> + <string name="permlab_requestInstallPackages" msgid="1772330282283082214">"Versoek installeer-pakette"</string> <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Laat \'n program toe om te versoek dat pakkette geïnstalleer word."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Raak twee keer vir zoembeheer"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Kon nie legstuk byvoeg nie."</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Totdat jy dit afskakel"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Vou in"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Moenie steur nie"</string> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index c2f1bb1..2a97a75 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"እስከ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ድረስ"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"ይህን እስኪያጠፉት ድረስ"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"ሰብስብ"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"አትረብሽ"</string> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 809e71b..f73662b 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -1574,6 +1574,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"حتى <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"لحين تعطيل هذا الإعداد"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"تصغير"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"الرجاء عدم الإزعاج"</string> diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml index 147599e..552ec70 100644 --- a/core/res/res/values-az-rAZ/strings.xml +++ b/core/res/res/values-az-rAZ/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Saat <xliff:g id="FORMATTEDTIME">%1$s</xliff:g> qədər"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Bunu söndürənə kimi"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Dağıt"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Narahat etməyin"</string> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index e25a614..ca9922e 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Докато не изключите това"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Свиване"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Не безпокойте"</string> diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml index dae8e38..d12d908 100644 --- a/core/res/res/values-bn-rBD/strings.xml +++ b/core/res/res/values-bn-rBD/strings.xml @@ -699,8 +699,8 @@ <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_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">"আপনি আপনার পাসওয়ার্ড <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="tv" msgid="5316664559603394684">"আপনি <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> @@ -1320,8 +1320,8 @@ <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_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_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> <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"আপনি <xliff:g id="NUMBER_0">%d</xliff:g> বার ভুল করে টিভি আনলক করার চেষ্টা করেছেন৷ <xliff:g id="NUMBER_1">%d</xliff:g>টি অসফল প্রচেষ্টার পরে, আপনার টিভি ফ্যাক্টরি ডিফল্টে পুনঃসেট হবে এবং সমস্ত ব্যবহারকারীর ডেটা মুছে যাবে৷"</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> পর্যন্ত"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"আপনার দ্বারা এটি বন্ধ করা পর্যন্ত"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"সঙ্কুচিত করুন"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"বিরক্ত করবেন না"</string> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index c0cbf3a..d4af979 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -243,8 +243,8 @@ <string name="permgroupdesc_phone" msgid="6234224354060641055">"fer i gestionar les trucades telefòniques"</string> <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensors"</string> <string name="permgroupdesc_sensors" msgid="6376772456799240169">"accedir a les dades dels sensors i dels dispositius connectats"</string> - <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contingut de les finestres"</string> - <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contingut d\'una finestra amb la qual estàs interaccionant."</string> + <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Recuperar el contingut de la finestra"</string> + <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspecciona el contingut d\'una finestra amb què estàs interaccionant."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Activar Exploració tàctil"</string> <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Els elements que toquis es diran en veu alta i la pantalla es podrà explorar mitjançant gestos."</string> <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Activar l\'accessibilitat web millorada"</string> @@ -701,9 +701,9 @@ <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"Has dibuixat el patró de desbloqueig de manera incorrecta <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string> <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string> <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"Has escrit malament la contrasenya <xliff:g id="NUMBER_0">%d</xliff:g> vegades. \n\nTorna-ho a provar d\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> segons."</string> - <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="tablet" msgid="9191611984625460820">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string> <string name="lockscreen_failed_attempts_almost_glogin" product="tv" msgid="5316664559603394684">"Has dibuixat el patró de desbloqueig incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%d</xliff:g> intents més abans no hagis de desbloquejar el televisor amb les dades d\'inici de sessió de Google.\n\n Torna a provar-ho d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string> - <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string> + <string name="lockscreen_failed_attempts_almost_glogin" product="default" msgid="2590227559763762751">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb l\'inici de sessió de Google.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="tablet" msgid="6128106399745755604">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades incorrectament. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"Has provat de desbloquejar el televisor incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%d</xliff:g> intents més abans no es restableixin els valors de fàbrica de l\'aparell i es perdin totes les dades d\'usuari."</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER_0">%d</xliff:g> vegades incorrectament. D\'aquí a <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, la tauleta es restablirà a la configuració predeterminada de fàbrica i es perdran totes les dades dels usuaris."</string> @@ -1329,9 +1329,9 @@ <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"Has provat de desbloquejar la tauleta <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. Ara la tauleta es restablirà a la configuració predeterminada de fàbrica."</string> <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"Has provat de desbloquejar el televisor incorrectament <xliff:g id="NUMBER">%d</xliff:g> vegades. Ara es restabliran els valors de fàbrica de l\'aparell."</string> <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. Ara el telèfon es restablirà a la configuració predeterminada de fàbrica."</string> - <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string> + <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string> <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"Has dibuixat el patró de desbloqueig incorrectament <xliff:g id="NUMBER_0">%d</xliff:g> vegades. Tens <xliff:g id="NUMBER_1">%d</xliff:g> intents més abans no hagis de desbloquejar el televisor amb un compte de correu electrònic.\n\n Torna a provar-ho d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string> - <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Després de <xliff:g id="NUMBER_1">%d</xliff:g> intents incorrectes més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string> + <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%d</xliff:g> segons."</string> <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string> <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"Elimina"</string> <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"Vols apujar el volum per sobre del nivell recomanat?\n\nSi escoltes música a un volum alt durant períodes llargs, pots danyar-te l\'oïda."</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Fins a les <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Fins que no ho desactivis"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Replega"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"No molesteu"</string> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index edf91c5..a468516 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -642,9 +642,9 @@ <string name="relationTypeAssistant" msgid="6274334825195379076">"Asistent"</string> <string name="relationTypeBrother" msgid="8757913506784067713">"Bratr"</string> <string name="relationTypeChild" msgid="1890746277276881626">"Dítě"</string> - <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Druh/družka"</string> + <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Partner(ka)"</string> <string name="relationTypeFather" msgid="5228034687082050725">"Otec"</string> - <string name="relationTypeFriend" msgid="7313106762483391262">"Známý"</string> + <string name="relationTypeFriend" msgid="7313106762483391262">"Kamarád(ka)"</string> <string name="relationTypeManager" msgid="6365677861610137895">"Vedoucí"</string> <string name="relationTypeMother" msgid="4578571352962758304">"Matka"</string> <string name="relationTypeParent" msgid="4755635567562925226">"Rodič"</string> @@ -975,7 +975,7 @@ <string name="volume_icon_description_notification" msgid="7044986546477282274">"Hlasitost oznámení"</string> <string name="ringtone_default" msgid="3789758980357696936">"Výchozí vyzváněcí tón"</string> <string name="ringtone_default_with_actual" msgid="8129563480895990372">"Výchozí tón (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string> - <string name="ringtone_silent" msgid="7937634392408977062">"Žádné"</string> + <string name="ringtone_silent" msgid="7937634392408977062">"Žádný"</string> <string name="ringtone_picker_title" msgid="3515143939175119094">"Vyzváněcí tóny"</string> <string name="ringtone_unknown" msgid="5477919988701784788">"Neznámý vyzváněcí tón"</string> <plurals name="wifi_available" formatted="false" msgid="7900333017752027322"> @@ -1540,6 +1540,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Dokud tuto funkci nevypnete"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sbalit"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Nerušit"</string> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 38c1b1a..71653c1 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Indtil <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Indtil du slår denne indstilling fra"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Skjul"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Vil ikke forstyrres"</string> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index 3ebb342..cfae0c0 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Bis <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Bis zur Deaktivierung"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Minimieren"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Nicht stören"</string> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 402399d..585e924 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -72,7 +72,7 @@ <string name="ColpMmi" msgid="3065121483740183974">"Αναγνωριστικό συνδεδεμένης γραμμής"</string> <string name="ColrMmi" msgid="4996540314421889589">"Περιορισμός αναγνωριστικού συνδεδεμένης πρόσβασης"</string> <string name="CfMmi" msgid="5123218989141573515">"Προώθηση κλήσεων"</string> - <string name="CwMmi" msgid="9129678056795016867">"Αναμ. κλήσ."</string> + <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> @@ -640,13 +640,13 @@ <string name="relationTypeAssistant" msgid="6274334825195379076">"Βοηθός"</string> <string name="relationTypeBrother" msgid="8757913506784067713">"Αδερφός"</string> <string name="relationTypeChild" msgid="1890746277276881626">"Παιδί"</string> - <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Σύντρ. ελεύθ. συμβ."</string> + <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Σύνοικος"</string> <string name="relationTypeFather" msgid="5228034687082050725">"Πατέρας"</string> <string name="relationTypeFriend" msgid="7313106762483391262">"Φίλος"</string> <string name="relationTypeManager" msgid="6365677861610137895">"Διευθυντής"</string> <string name="relationTypeMother" msgid="4578571352962758304">"Μητέρα"</string> <string name="relationTypeParent" msgid="4755635567562925226">"Γονέας"</string> - <string name="relationTypePartner" msgid="7266490285120262781">"Συνεργάτης"</string> + <string name="relationTypePartner" msgid="7266490285120262781">"Σύντροφος"</string> <string name="relationTypeReferredBy" msgid="101573059844135524">"Συστήθηκε από"</string> <string name="relationTypeRelative" msgid="1799819930085610271">"Συγγενής"</string> <string name="relationTypeSister" msgid="1735983554479076481">"Αδερφή"</string> @@ -671,7 +671,7 @@ <string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Πατήστε \"Menu\" για ξεκλείδωμα ή για κλήση έκτακτης ανάγκης."</string> <string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Πατήστε \"Μενού\" για ξεκλείδωμα."</string> <string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Σχεδιασμός μοτίβου για ξεκλείδωμα"</string> - <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Επείγοντα περιστατικά"</string> + <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Κλήση έκτακτης ανάγκης"</string> <string name="lockscreen_return_to_call" msgid="5244259785500040021">"Επιστροφή στην κλήση"</string> <string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Σωστό!"</string> <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Προσπαθήστε ξανά"</string> @@ -1062,7 +1062,7 @@ <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Όλα τα δεδομένα που υπάρχουν στην κάρτα σας θα χαθούν."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Διαμόρφωση"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string> - <string name="adb_active_notification_message" msgid="1016654627626476142">"Αγγίξτε για απενεργοποίηση του εντοπισμού σφαλμάτων USB."</string> + <string name="adb_active_notification_message" msgid="1016654627626476142">"Απεν. του εντοπ. σφαλμάτων USB."</string> <string name="select_input_method" msgid="8547250819326693584">"Αλλαγή πληκτρολογίου"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Επιλογή πληκτρολογίων"</string> <string name="show_ime" msgid="9157568568695230830">"Εμφάνιση μεθόδου εισαγ."</string> @@ -1075,7 +1075,7 @@ <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Προετοιμασία <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Έλεγχος για σφάλματα"</string> <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Εντοπίστηκε νέο μέσο αποθήκευσης <xliff:g id="NAME">%s</xliff:g>"</string> - <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Για μεταφορά φωτογραφιών και πολυμέσων"</string> + <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Για μεταφορά φωτ./πολυμέσων"</string> <string name="ext_media_unmountable_notification_title" msgid="4863279349863279603">"Κατεστραμμένος χώρος αποθήκευσης <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_unmountable_notification_message" msgid="7391672496565685690">"Ο χώρος αποθήκευσης <xliff:g id="NAME">%s</xliff:g> είναι κατεστραμμένος. Δοκιμάστε να τον διαμορφώσετε ξανά."</string> <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"Μη αναμενόμενη αφαίρεση <xliff:g id="NAME">%s</xliff:g>"</string> @@ -1295,7 +1295,7 @@ <string name="display_manager_overlay_display_title" msgid="652124517672257172">"<xliff:g id="NAME">%1$s</xliff:g>: <xliff:g id="WIDTH">%2$d</xliff:g>x<xliff:g id="HEIGHT">%3$d</xliff:g>, <xliff:g id="DPI">%4$d</xliff:g> dpi"</string> <string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ασφαλές"</string> <string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"Ξεχάσατε το μοτίβο"</string> - <string name="kg_wrong_pattern" msgid="1850806070801358830">"Εσφαλμένο μοτίβο"</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_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Δοκιμάστε ξανά σε <xliff:g id="NUMBER">%1$d</xliff:g> δευτερόλεπτα."</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Έως τις <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Μέχρι να το απενεργοποιήσετε"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Σύμπτυξη"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Μην ενοχλείτε"</string> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index 579a5ee..7eaac7e 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Collapse"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Do not disturb"</string> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index 579a5ee..7eaac7e 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Collapse"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Do not disturb"</string> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index 579a5ee..7eaac7e 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Until <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Until you turn this off"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Collapse"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Do not disturb"</string> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index 7512ff5..39ee111 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Hasta la(s) <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Hasta que lo desactives"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"No molestar"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index bdcb524..cf49ff9 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -390,7 +390,7 @@ <string name="permlab_authenticateAccounts" msgid="5265908481172736933">"crear cuentas y establecer contraseñas"</string> <string name="permdesc_authenticateAccounts" msgid="5472124296908977260">"Permite que la aplicación utilice las funciones de autenticador de cuentas del administrador de cuentas, incluida la creación de cuentas y la obtención y el establecimiento de sus contraseñas."</string> <string name="permlab_manageAccounts" msgid="4983126304757177305">"añadir o eliminar cuentas"</string> - <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Permite que la aplicación lleve a cabo operaciones como añadir y eliminar cuentas y eliminar su contraseña."</string> + <string name="permdesc_manageAccounts" msgid="8698295625488292506">"Permite que la aplicación lleve a cabo operaciones como añadir y quitar cuentas, así como quitar su contraseña."</string> <string name="permlab_useCredentials" msgid="235481396163877642">"usar cuentas del dispositivo"</string> <string name="permdesc_useCredentials" msgid="7984227147403346422">"Permite que la aplicación solicite tokens de autenticación."</string> <string name="permlab_accessNetworkState" msgid="4951027964348974773">"ver conexiones de red"</string> @@ -955,7 +955,7 @@ <string name="volume_music_hint_silent_ringtone_selected" msgid="8310739960973156272">"Tono de silencio establecido"</string> <string name="volume_call" msgid="3941680041282788711">"Volumen de la llamada"</string> <string name="volume_bluetooth_call" msgid="2002891926351151534">"Volumen de la llamada de Bluetooth"</string> - <string name="volume_alarm" msgid="1985191616042689100">"Volumen de alarma"</string> + <string name="volume_alarm" msgid="1985191616042689100">"Volumen de la alarma"</string> <string name="volume_notification" msgid="2422265656744276715">"Volumen de notificaciones"</string> <string name="volume_unknown" msgid="1400219669770445902">"Volumen"</string> <string name="volume_icon_description_bluetooth" msgid="6538894177255964340">"Volumen de Bluetooth"</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Hasta las <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Hasta apagar el dispositivo"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"No molestar"</string> diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml index a2042ed..a75ce68 100644 --- a/core/res/res/values-et-rEE/strings.xml +++ b/core/res/res/values-et-rEE/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Kuni <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Kuni lülitate selle välja"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Ahendamine"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Mitte segada"</string> diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml index b7f047e..2ccc65e 100644 --- a/core/res/res/values-eu-rES/strings.xml +++ b/core/res/res/values-eu-rES/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> arte"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Zuk desaktibatu arte"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Tolestu"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Ez molestatu"</string> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 92c508c..4f9d399 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"تا <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"تا وقتی آن را خاموش کنید"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"کوچک کردن"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"مزاحم نشوید"</string> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index f9da2ca..97390a6 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -243,13 +243,13 @@ <string name="permgroupdesc_phone" msgid="6234224354060641055">"soittaa ja hallinnoida puheluita"</string> <string name="permgrouplab_sensors" msgid="7416703484233940260">"Anturit"</string> <string name="permgroupdesc_sensors" msgid="6376772456799240169">"käyttää antureiden ja puettavien laitteiden tietoja"</string> - <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Nouda ikkunan sisältöä"</string> - <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tarkista käyttämäsi ikkunan sisältö."</string> - <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ota kosketuksella tutkiminen käyttöön"</string> + <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Noutaa ikkunan sisältöä"</string> + <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Tarkistaa käyttämäsi ikkunan sisältö."</string> + <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Ottaa kosketuksella tutkiminen käyttöön"</string> <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Kosketetut kohteet sanotaan ääneen ja ruudulla voi liikkua eleiden avulla."</string> - <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Ota parannettu verkon esteettömyys käyttöön"</string> + <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Ottaa parannettu verkon esteettömyys käyttöön"</string> <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Sovellus voi asentaa ohjelmia tehdäkseen sisällöstään esteettömämmän."</string> - <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Tarkkaile kirjoittamaasi tekstiä"</string> + <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Tarkkailla kirjoittamaasi tekstiä"</string> <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Sisältää henkilökohtaisia tietoja, kuten luottokortin numeroita ja salasanoja."</string> <string name="permlab_statusBar" msgid="7417192629601890791">"poista tilapalkki käytöstä tai muokkaa tilapalkkia"</string> <string name="permdesc_statusBar" msgid="8434669549504290975">"Antaa sovelluksen poistaa tilapalkin käytöstä ja lisätä tai poistaa järjestelmäkuvakkeita."</string> @@ -425,7 +425,7 @@ <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Antaa sovelluksen tarkastella puhelimen Bluetooth-asetuksia sekä muodostaa ja hyväksyä laitepariyhteyksiä muihin laitteisiin."</string> <string name="permlab_nfc" msgid="4423351274757876953">"hallitse Near Field Communication -tunnistusta"</string> <string name="permdesc_nfc" msgid="7120611819401789907">"Antaa sovelluksen kommunikoida NFC (Near Field Communication) -tagien, -korttien ja -lukijoiden kanssa."</string> - <string name="permlab_disableKeyguard" msgid="3598496301486439258">"poista ruudun lukitus käytöstä"</string> + <string name="permlab_disableKeyguard" msgid="3598496301486439258">"poista näytön lukitus käytöstä"</string> <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Antaa sovelluksen ottaa näppäinlukon ja siihen liittyvän salasanasuojauksen pois käytöstä. Esimerkki: puhelin poistaa näppäinlukon käytöstä puhelun saapuessa ja asettaa lukon takaisin käyttöön puhelun päättyessä."</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"sormenjälkilaitteiston hallinnointi"</string> <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Sallii sovelluksen käyttää menetelmiä, joilla voidaan lisätä tai poistaa sormenjälkimalleja."</string> @@ -520,14 +520,14 @@ <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Valvo väärien salasanojen määrää ruudun lukitusta avattaessa ja lukitse tabletti tai poista kaikki tämän käyttäjän tiedot, jos salasana kirjoitetaan väärin liian monta kertaa."</string> <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Valvo väärien salasanojen määrää ruudun lukitusta avattaessa ja lukitse televisio tai poista kaikki tämän käyttäjän tiedot, jos salasana kirjoitetaan väärin liian monta kertaa."</string> <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Valvo väärien salasanojen määrää ruudun lukitusta avattaessa ja lukitse puhelin tai poista kaikki tämän käyttäjän tiedot, jos salasana kirjoitetaan väärin liian monta kertaa."</string> - <string name="policylab_resetPassword" msgid="4934707632423915395">"Muuta ruudun lukitus"</string> - <string name="policydesc_resetPassword" msgid="1278323891710619128">"Muuta ruudun lukitus."</string> - <string name="policylab_forceLock" msgid="2274085384704248431">"Lukitse ruutu"</string> - <string name="policydesc_forceLock" msgid="1141797588403827138">"Hallinnoi, milloin ja miten ruutu lukittuu."</string> - <string name="policylab_wipeData" msgid="3910545446758639713">"Pyyhi kaikki tiedot"</string> + <string name="policylab_resetPassword" msgid="4934707632423915395">"Muuta näytön lukitus"</string> + <string name="policydesc_resetPassword" msgid="1278323891710619128">"Muuta näytön lukitus."</string> + <string name="policylab_forceLock" msgid="2274085384704248431">"Lukita ruutu"</string> + <string name="policydesc_forceLock" msgid="1141797588403827138">"Hallinnoida, milloin ja miten ruutu lukittuu."</string> + <string name="policylab_wipeData" msgid="3910545446758639713">"Pyyhkiä kaikki tiedot"</string> <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Tyhjennä tablet-laitteen tiedot varoituksetta palauttamalla tehdasasetukset."</string> <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Palauta tehdasasetukset ja poista television tiedot ilman varoitusta."</string> - <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Tyhjennä puhelimen tiedot varoituksetta palauttamalla tehdasasetukset."</string> + <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Tyhjentää puhelimen tiedot varoituksetta palauttamalla tehdasasetukset."</string> <string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"Pyyhi käyttäjän tiedot"</string> <string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"Pyyhi tämän käyttäjän tiedot tabletista ilman varoitusta."</string> <string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"Pyyhi tämän käyttäjän tiedot televisiosta ilman varoitusta."</string> @@ -543,7 +543,7 @@ <string name="policylab_disableKeyguardFeatures" msgid="3565888260412415862">"Poista ruudun lukituksen ominaisuudet"</string> <string name="policydesc_disableKeyguardFeatures" msgid="3980868516629887575">"Estä joidenkin ruudun lukituksen ominaisuuksien käyttö."</string> <string-array name="phoneTypes"> - <item msgid="8901098336658710359">"Puhelinnumero (koti)"</item> + <item msgid="8901098336658710359">"Koti"</item> <item msgid="869923650527136615">"Mobiili"</item> <item msgid="7897544654242874543">"Työ"</item> <item msgid="1103601433382158155">"Faksi (työ)"</item> @@ -559,7 +559,7 @@ <item msgid="2374913952870110618">"Muokattu"</item> </string-array> <string-array name="postalAddressTypes"> - <item msgid="6880257626740047286">"Osoite (koti)"</item> + <item msgid="6880257626740047286">"Koti"</item> <item msgid="5629153956045109251">"Työ"</item> <item msgid="4966604264500343469">"Muu"</item> <item msgid="4932682847595299369">"Muokattu"</item> @@ -586,7 +586,7 @@ <item msgid="1648797903785279353">"Jabber"</item> </string-array> <string name="phoneTypeCustom" msgid="1644738059053355820">"Muokattu"</string> - <string name="phoneTypeHome" msgid="2570923463033985887">"Puhelinnumero (koti)"</string> + <string name="phoneTypeHome" msgid="2570923463033985887">"Koti"</string> <string name="phoneTypeMobile" msgid="6501463557754751037">"Mobiili"</string> <string name="phoneTypeWork" msgid="8863939667059911633">"Työ"</string> <string name="phoneTypeFaxWork" msgid="3517792160008890912">"Faksi (työ)"</string> @@ -616,7 +616,7 @@ <string name="emailTypeOther" msgid="2923008695272639549">"Muu"</string> <string name="emailTypeMobile" msgid="119919005321166205">"Mobiili"</string> <string name="postalTypeCustom" msgid="8903206903060479902">"Muokattu"</string> - <string name="postalTypeHome" msgid="8165756977184483097">"Osoite (koti)"</string> + <string name="postalTypeHome" msgid="8165756977184483097">"Koti"</string> <string name="postalTypeWork" msgid="5268172772387694495">"Työ"</string> <string name="postalTypeOther" msgid="2726111966623584341">"Muu"</string> <string name="imTypeCustom" msgid="2074028755527826046">"Muokattu"</string> @@ -643,7 +643,7 @@ <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Avopuoliso"</string> <string name="relationTypeFather" msgid="5228034687082050725">"Isä"</string> <string name="relationTypeFriend" msgid="7313106762483391262">"Ystävä"</string> - <string name="relationTypeManager" msgid="6365677861610137895">"Johtaja"</string> + <string name="relationTypeManager" msgid="6365677861610137895">"Pomo"</string> <string name="relationTypeMother" msgid="4578571352962758304">"Äiti"</string> <string name="relationTypeParent" msgid="4755635567562925226">"Vanhempi"</string> <string name="relationTypePartner" msgid="7266490285120262781">"Kumppani"</string> @@ -1062,7 +1062,7 @@ <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Kaikki kortilla olevat tiedot menetetään."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Muoto"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string> - <string name="adb_active_notification_message" msgid="1016654627626476142">"Poista USB-vianetsintä käytöstä koskettamalla tätä."</string> + <string name="adb_active_notification_message" msgid="1016654627626476142">"Sulje USB-vianetsintä koskettamalla tätä."</string> <string name="select_input_method" msgid="8547250819326693584">"Vaihda näppäimistö"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Valitse näppäimistöt"</string> <string name="show_ime" msgid="9157568568695230830">"Näytä syöttötapa"</string> @@ -1075,7 +1075,7 @@ <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Valmistellaan kohdetta <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Tarkistetaan virheiden varalta."</string> <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Uusi <xliff:g id="NAME">%s</xliff:g> on havaittu."</string> - <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Kuvien ja mediatiedostojen siirtämiseen"</string> + <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Kuvien ja median siirtämiseen"</string> <string name="ext_media_unmountable_notification_title" msgid="4863279349863279603">"<xliff:g id="NAME">%s</xliff:g> on vahingoittunut"</string> <string name="ext_media_unmountable_notification_message" msgid="7391672496565685690">"<xliff:g id="NAME">%s</xliff:g> on vahingoittunut. Kokeile alustaa se uudelleen."</string> <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> poistettiin yllättäen"</string> @@ -1143,7 +1143,7 @@ <string name="submit" msgid="1602335572089911941">"Lähetä"</string> <string name="car_mode_disable_notification_title" msgid="3164768212003864316">"Autotila käytössä"</string> <string name="car_mode_disable_notification_message" msgid="8035230537563503262">"Poistu autotilasta koskettamalla tätä."</string> - <string name="tethered_notification_title" msgid="3146694234398202601">"Internetyhteyden jakaminen tai yhteyspiste käytössä"</string> + <string name="tethered_notification_title" msgid="3146694234398202601">"Internetin jakaminen tai yhteyspiste käytössä"</string> <string name="tethered_notification_message" msgid="6857031760103062982">"Määritä asetukset koskettamalla."</string> <string name="back_button_label" msgid="2300470004503343439">"Takaisin"</string> <string name="next_button_label" msgid="1080555104677992408">"Seuraava"</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Kunnes kello on <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Kunnes poistat tämän käytöstä"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Kutista"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Älä häiritse"</string> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 00db000..7eef639 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Jusqu\'à la désactivation"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Réduire"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne pas déranger"</string> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 5037192..c2415d9 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Jusqu\'à <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Jusqu\'à la désactivation"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Réduire"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne pas déranger"</string> diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml index 8b51592..a89fd4b 100644 --- a/core/res/res/values-gl-rES/strings.xml +++ b/core/res/res/values-gl-rES/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Ata as <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Ata que desactives isto"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Contraer"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Non molestar"</string> diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml index 1e635f3..b9eab47 100644 --- a/core/res/res/values-gu-rIN/strings.xml +++ b/core/res/res/values-gu-rIN/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> સુધી"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"તમે આ બંધ ન કરો ત્યાં સુધી"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"સંકુચિત કરો"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"ખલેલ પાડશો નહીં"</string> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 0e5bb03..376deef 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> तक"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"जब तक आप इसे बंद नहीं कर देते"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त करें"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"परेशान ना करें"</string> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index 8e93bf5..84a709d 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -1523,6 +1523,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Dok ne isključite"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sažmi"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne ometaj"</string> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 1b2eaba..537644c 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -1075,7 +1075,7 @@ <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> előkészítése"</string> <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Hibák keresése"</string> <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Új <xliff:g id="NAME">%s</xliff:g> észlelve"</string> - <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Fotók és más médiatartalmak átviteléhez"</string> + <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Fotók és más tartalmak átviteléhez"</string> <string name="ext_media_unmountable_notification_title" msgid="4863279349863279603">"A(z) <xliff:g id="NAME">%s</xliff:g> sérült"</string> <string name="ext_media_unmountable_notification_message" msgid="7391672496565685690">"A(z) <xliff:g id="NAME">%s</xliff:g> sérült, próbálja meg újraformázni"</string> <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"A(z) <xliff:g id="NAME">%s</xliff:g> váratlanul eltávolítva"</string> @@ -1321,7 +1321,7 @@ <string name="kg_login_account_recovery_hint" msgid="5690709132841752974">"Elfelejtette a felhasználónevét vagy jelszavát?\nKeresse fel a "<b>"google.com/accounts/recovery"</b>" webhelyet."</string> <string name="kg_login_checking_password" msgid="1052685197710252395">"Fiók ellenőrzése..."</string> <string name="kg_too_many_failed_pin_attempts_dialog_message" msgid="8276745642049502550">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg PIN kódját. \n\nPróbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string> - <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg a jelszót. \n\n Próbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string> + <string name="kg_too_many_failed_password_attempts_dialog_message" msgid="7813713389422226531">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal helytelenül adta meg a jelszót. \n\nPróbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string> <string name="kg_too_many_failed_pattern_attempts_dialog_message" msgid="74089475965050805">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal rosszul rajzolta le feloldási mintát. \n\nPróbálja újra <xliff:g id="NUMBER_1">%d</xliff:g> másodperc múlva."</string> <string name="kg_failed_attempts_almost_at_wipe" product="tablet" msgid="1575557200627128949">"A táblagépet <xliff:g id="NUMBER_0">%d</xliff:g> alkalommal próbálta meg sikertelenül feloldani. <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen próbálkozás után a rendszer visszaállítja a táblagép gyári alapértelmezett beállításait, és minden felhasználói adat elvész."</string> <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"<xliff:g id="NUMBER_0">%d</xliff:g> alkalommal sikertelenül próbálta feloldani a tévét. A tévé <xliff:g id="NUMBER_1">%d</xliff:g> további sikertelen kísérlet esetén visszaáll a gyári alapbeállításokra, és minden felhasználói adat elvész."</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Eddig: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Amíg ki nem kapcsolja ezt"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Összecsukás"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne zavarjanak"</string> diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml index f97003e..c84a15a 100644 --- a/core/res/res/values-hy-rAM/strings.xml +++ b/core/res/res/values-hy-rAM/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Մինչև <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Քանի դեռ չեք անջատել"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Թաքցնել"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Չանհանգստացնել"</string> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 0c046fe..af4f248 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -205,7 +205,7 @@ <string name="global_action_power_off" msgid="4471879440839879722">"Matikan daya"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"Laporan bug"</string> <string name="bugreport_title" msgid="2667494803742548533">"Ambil laporan bug"</string> - <string name="bugreport_message" msgid="398447048750350456">"Ini akan mengumpulkan informasi tentang status perangkat Anda saat ini, untuk dikirimkan sebagai pesan email. Akan memakan sedikit waktu dari memulai laporan bug hingga siap untuk dikirim; bersabarlah."</string> + <string name="bugreport_message" msgid="398447048750350456">"Ini akan mengumpulkan informasi status perangkat Anda saat ini, untuk dikirimkan sebagai pesan email. Harap bersabar, mungkin perlu waktu untuk memulai laporan bug hingga siap dikirim."</string> <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Mode senyap"</string> <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Suara MATI"</string> <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Suara AKTIF"</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Hingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Hingga Anda menonaktifkan ini"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Ciutkan"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Jangan ganggu"</string> diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml index 84872fb..cfa8a7b 100644 --- a/core/res/res/values-is-rIS/strings.xml +++ b/core/res/res/values-is-rIS/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Þar til þú slekkur á þessu"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Minnka"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Ónáðið ekki"</string> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index fc5baac..1332e24 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -1075,7 +1075,7 @@ <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"Preparazione della <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Ricerca errori"</string> <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Nuova <xliff:g id="NAME">%s</xliff:g> rilevata"</string> - <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Per il trasferimento di foto e contenuti multimediali"</string> + <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Per trasferire foto e altri file"</string> <string name="ext_media_unmountable_notification_title" msgid="4863279349863279603">"<xliff:g id="NAME">%s</xliff:g> danneggiata"</string> <string name="ext_media_unmountable_notification_message" msgid="7391672496565685690">"La <xliff:g id="NAME">%s</xliff:g> è danneggiata. Prova a riformattarla."</string> <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"Rimozione imprevista della <xliff:g id="NAME">%s</xliff:g>"</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Fino alle ore <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Fino alla disattivazione"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Comprimi"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Non disturbare"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index bdd2c0c..f11fa27 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -207,7 +207,7 @@ <string name="global_action_power_off" msgid="4471879440839879722">"כיבוי"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"דיווח על באג"</string> <string name="bugreport_title" msgid="2667494803742548533">"שלח דיווח על באג"</string> - <string name="bugreport_message" msgid="398447048750350456">"פעולה זו תאסוף מידע על מצב המכשיר הנוכחי שלך על מנת לשלוח אותו כהודעת אימייל. היא תימשך זמן קצר מרגע פתיחת דיווח הבאג ועד שיהיה ניתן לבצע שליחה. התאזר בסבלנות."</string> + <string name="bugreport_message" msgid="398447048750350456">"פעולה זו תאסוף מידע על מצב המכשיר הנוכחי שלך על מנת לשלוח אותו כהודעת אימייל. היא תימשך זמן קצר מרגע פתיחת דיווח הבאג ועד שיהיה ניתן לבצע שליחה. אנא המתן בסבלנות."</string> <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"מצב שקט"</string> <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"הקול כבוי"</string> <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"קול מופעל"</string> @@ -524,9 +524,9 @@ <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"מעקב אחר מספר הסיסמאות השגויות שהוזנו בעת ביטול נעילת המסך, כמו גם נעילת הטלפון או מחיקה של כל נתוני המשתמש הזה אם הוזנו יותר מדי סיסמאות שגויות."</string> <string name="policylab_resetPassword" msgid="4934707632423915395">"שינוי נעילת המסך"</string> <string name="policydesc_resetPassword" msgid="1278323891710619128">"שינוי של נעילת המסך."</string> - <string name="policylab_forceLock" msgid="2274085384704248431">"נעל את המסך"</string> + <string name="policylab_forceLock" msgid="2274085384704248431">"לנעול את המסך"</string> <string name="policydesc_forceLock" msgid="1141797588403827138">"שלוט באופן ובתזמון של נעילת המסך"</string> - <string name="policylab_wipeData" msgid="3910545446758639713">"מחק את כל הנתונים"</string> + <string name="policylab_wipeData" msgid="3910545446758639713">"למחוק את כל הנתונים"</string> <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"מחק את נתוני הטאבלט ללא אזהרה על ידי ביצוע איפוס נתוני יצרן."</string> <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"מחיקה של נתוני הטלוויזיה ללא אזהרה, על ידי ביצוע איפוס לנתוני היצרן."</string> <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"מחק את נתוני הטלפון ללא אזהרה על ידי ביצוע איפוס נתוני יצרן."</string> @@ -1483,7 +1483,7 @@ <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"האפליקציה מוצמדת: ביטול ההצמדה אסור במכשיר הזה."</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">"בקש קוד אימות לפני ביטול הצמדה"</string> + <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"בקש PIN לפני ביטול הצמדה"</string> <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"בקש קו ביטול נעילה לפני ביטול הצמדה"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"בקש סיסמה לפני ביטול הצמדה"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"הותקנה על ידי מנהל המערכת שלך"</string> @@ -1540,6 +1540,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"עד <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"עד שתכבה"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"כווץ"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"נא לא להפריע"</string> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 68266cb..4fdec52 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>まで"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"ユーザーがOFFにするまで"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"折りたたむ"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"通知を非表示"</string> diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml index 9d78e16..236b4b7 100644 --- a/core/res/res/values-ka-rGE/strings.xml +++ b/core/res/res/values-ka-rGE/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>-მდე"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"სანამ ამას გამორთავდეთ"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"აკეცვა"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"არ შემაწუხოთ"</string> diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml index 0782c80..75d600f 100644 --- a/core/res/res/values-kk-rKZ/strings.xml +++ b/core/res/res/values-kk-rKZ/strings.xml @@ -187,7 +187,7 @@ <string name="silent_mode_vibrate" msgid="7072043388581551395">"Қоңырау тербелісі"</string> <string name="silent_mode_ring" msgid="8592241816194074353">"Қоңырау қосулы"</string> <string name="reboot_to_recovery_title" msgid="7851482804359554338">"Жаңартуға дайындау"</string> - <string name="reboot_to_recovery_progress" msgid="983446780859314345">"Жаңарту жиынтығы өңделуде…"</string> + <string name="reboot_to_recovery_progress" msgid="983446780859314345">"Жаңарту бумасы өңделуде…"</string> <string name="shutdown_progress" msgid="2281079257329981203">"Өшірілуде…"</string> <string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Планшет өшіріледі."</string> <string name="shutdown_confirm" product="tv" msgid="476672373995075359">"ТД өшіріледі."</string> @@ -1100,8 +1100,8 @@ <string name="permdesc_route_media_output" msgid="4932818749547244346">"Қолданбаға медиа шығысын басқа сыртқы құрылғыларға бағыттау мүмкіндігін береді."</string> <string name="permlab_readInstallSessions" msgid="6165432407628065939">"Орнату сеанстарын оқу"</string> <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"Қолданбаға орнату сеанстарын оқуға рұқсат етеді. Бұл оған белсенді бума орнатулары туралы мәліметтерді көруге рұқсат етеді."</string> - <string name="permlab_requestInstallPackages" msgid="1772330282283082214">"Жиынтықтарды орнатуды сұрау"</string> - <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Қолданбаның жиынтықтарды орнатуды сұрауына мүмкіндік береді."</string> + <string name="permlab_requestInstallPackages" msgid="1772330282283082214">"Бумаларды орнатуға рұқсат сұрау"</string> + <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Қолданбаның бумаларды орнатуға рұқсат сұрауына мүмкіндік береді."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Масштабтауды басқару үшін екі рет түртіңіз"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Виджетті қосу."</string> <string name="ime_action_go" msgid="8320845651737369027">"Өту"</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> дейін"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Сіз осыны өшіргенше"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Тасалау"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Мазаламау"</string> diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml index f74448b..314c58c 100644 --- a/core/res/res/values-km-rKH/strings.xml +++ b/core/res/res/values-km-rKH/strings.xml @@ -1508,6 +1508,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"រហូតដល់ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"រហូតដល់ពេលអ្នកបិទវា"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"បង្រួម"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"កុំរំខាន"</string> diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml index 658aa56..60dde90 100644 --- a/core/res/res/values-kn-rIN/strings.xml +++ b/core/res/res/values-kn-rIN/strings.xml @@ -243,13 +243,13 @@ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಿ ಮತ್ತು ನಿರ್ವಹಿಸಿ"</string> <string name="permgrouplab_sensors" msgid="7416703484233940260">"ಸಂವೇದಕಗಳು"</string> <string name="permgroupdesc_sensors" msgid="6376772456799240169">"ಸೆನ್ಸಾರ್ಗಳು ಹಾಗೂ ಧರಿಸುವಂತಹ ಸಾಧನಗಳಿಂದ ಡೇಟಾವನ್ನು ಪ್ರವೇಶಿಸಿ"</string> - <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ವಿಂಡೋ ವಿಷಯವನ್ನು ಹಿಂಪಡೆದುಕೊಳ್ಳಿ"</string> + <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"ವಿಂಡೋ ವಿಷಯವನ್ನು ಹಿಂಪಡೆದುಕೊಳ್ಳುತ್ತದೆ"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"ನೀವು ಸಂವಹನ ನಡೆಸುತ್ತಿರುವ ವಿಂಡೋದ ವಿಷಯವನ್ನು ಪರೀಕ್ಷಿಸಿ."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"ಸ್ಪರ್ಶಿಸುವ ಮೂಲಕ ಎಕ್ಸ್ಪ್ಲೋರ್ ಆನ್ ಮಾಡಿ"</string> <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"ಸ್ಪರ್ಶಿಸಲಾದ ಐಟಂಗಳನ್ನು ಗಟ್ಟಿಯಾಗಿ ಹೇಳಲಾಗುತ್ತದೆ ಮತ್ತು ಗೆಸ್ಚರ್ಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಪರದೆಯನ್ನು ಎಕ್ಸ್ಪ್ಲೋರ್ ಮಾಡಬಹುದಾಗಿದೆ."</string> <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"ವರ್ಧಿತ ವೆಬ್ ಪ್ರವೇಶಿಸುವಿಕೆಯನ್ನು ಆನ್ ಮಾಡಿ"</string> <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"ಅಪ್ಲಿಕೇಶನ್ ವಿಷಯವನ್ನು ಇನ್ನಷ್ಟು ಪ್ರವೇಶಿಸುವಂತೆ ಮಾಡಲು ಸ್ಕ್ರಿಪ್ಟ್ಗಳನ್ನು ಸ್ಥಾಪಿಸಬಹುದಾಗಿದೆ."</string> - <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"ನೀವು ಟೈಪ್ ಮಾಡುವ ಪಠ್ಯವನ್ನು ಗಮನಿಸಿ"</string> + <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"ನೀವು ಟೈಪ್ ಮಾಡುವ ಪಠ್ಯವನ್ನು ಗಮನಿಸುತ್ತದೆ"</string> <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"ಕ್ರೆಡಿಟ್ ಕಾರ್ಡ್ ಸಂಖ್ಯೆಗಳು ಮತ್ತು ಪಾಸ್ವರ್ಡ್ಗಳಂತಹ ವೈಯಕ್ತಿಕ ಡೇಟಾವನ್ನು ಒಳಗೊಂಡಿರುತ್ತದೆ."</string> <string name="permlab_statusBar" msgid="7417192629601890791">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ ಇಲ್ಲವೇ ಮಾರ್ಪಡಿಸಿ"</string> <string name="permdesc_statusBar" msgid="8434669549504290975">"ಸ್ಥಿತಿ ಪಟ್ಟಿಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಅಥವಾ ಸೇರಿಸಲು ಮತ್ತು ಸಿಸ್ಟಂ ಐಕಾನ್ಗಳನ್ನು ತೆಗೆದುಹಾಕಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ವರೆಗೆ"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"ನೀವಿದನ್ನು ಆಫ್ ಮಾಡುವವರೆಗೆ"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"ಸಂಕುಚಿಸು"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"ಅಡಚಣೆ ಮಾಡಬೇಡಿ"</string> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index a7d8caa..502cbda 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -547,7 +547,7 @@ <item msgid="869923650527136615">"모바일"</item> <item msgid="7897544654242874543">"회사"</item> <item msgid="1103601433382158155">"회사 팩스"</item> - <item msgid="1735177144948329370">"집(팩스)"</item> + <item msgid="1735177144948329370">"집 팩스"</item> <item msgid="603878674477207394">"호출기"</item> <item msgid="1650824275177931637">"기타"</item> <item msgid="9192514806975898961">"맞춤설정"</item> @@ -590,7 +590,7 @@ <string name="phoneTypeMobile" msgid="6501463557754751037">"휴대전화"</string> <string name="phoneTypeWork" msgid="8863939667059911633">"직장"</string> <string name="phoneTypeFaxWork" msgid="3517792160008890912">"직장 팩스"</string> - <string name="phoneTypeFaxHome" msgid="2067265972322971467">"집(팩스)"</string> + <string name="phoneTypeFaxHome" msgid="2067265972322971467">"집 팩스"</string> <string name="phoneTypePager" msgid="7582359955394921732">"호출기"</string> <string name="phoneTypeOther" msgid="1544425847868765990">"기타"</string> <string name="phoneTypeCallback" msgid="2712175203065678206">"콜백"</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>까지"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"이 기능을 사용 중지할 때까지"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"접기"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"알림 일시중지"</string> diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml index 078cf90..3887907 100644 --- a/core/res/res/values-ky-rKG/strings.xml +++ b/core/res/res/values-ky-rKG/strings.xml @@ -1452,8 +1452,8 @@ <string name="permdesc_route_media_output" msgid="4932818749547244346">"Колдонмого медиа мазмунду башка тышкы түзмөктөргө багыттоо уруксатын берет."</string> <string name="permlab_readInstallSessions" msgid="6165432407628065939">"Орнотуу сеанстарын окуу"</string> <string name="permdesc_readInstallSessions" msgid="2049771699626019849">"Колдонмого орнотуу сеанстарын окуу мүмкүнчүлүгүн берет. Ушуну менен, ал жигердүү топтом орнотууларынын чоо-жайын көрө алат."</string> - <string name="permlab_requestInstallPackages" msgid="1772330282283082214">"Топтомдорду орнотууну талап кылуу"</string> - <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Колдонмого топтомдорду орнотууну өтүнүүсүнө жол ачат."</string> + <string name="permlab_requestInstallPackages" msgid="1772330282283082214">"Топтомдорду орнотууга уруксат суроо"</string> + <string name="permdesc_requestInstallPackages" msgid="5740101072486783082">"Колдонмо топтомдорду орнотууга уруксат сурай алат."</string> <string name="tutorial_double_tap_to_zoom_message_short" msgid="4070433208160063538">"Чен өлчөмүн көзөмөлдөө үчүн эки жолу тийип коюңуз"</string> <string name="gadget_host_error_inflating" msgid="4882004314906466162">"Виджетти кошуу мүмкүн болбоду."</string> <!-- no translation found for ime_action_go (8320845651737369027) --> @@ -1923,6 +1923,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> чейин"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Бул өчүрүлгөнгө чейин"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Жыйнап коюу"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Тынчымды алба"</string> diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml index 744f0ab..c531339 100644 --- a/core/res/res/values-lo-rLA/strings.xml +++ b/core/res/res/values-lo-rLA/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"ຈົນຮອດ <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"ຈົນກວ່າທ່ານຈະປິດ"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"ຫຍໍ້"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"ຫ້າມລົບກວນ"</string> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index def941d..ccfab5a 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -509,8 +509,8 @@ <string name="permdesc_handoverStatus" msgid="4788144087245714948">"Programai leidžiama gauti informaciją apie dabartinius „Android“ perdavimo funkcijos perkėlimus"</string> <string name="permlab_removeDrmCertificates" msgid="7044888287209892751">"pašalinti DRM sertifikatus"</string> <string name="permdesc_removeDrmCertificates" msgid="7272999075113400993">"Programai leidžiama pašalinti DRM sertifikatus. Neturėtų prireikti naudojant įprastas programas."</string> - <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"susaistyti su operatoriaus susirašinėjimo žinutėmis paslauga"</string> - <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Leidžiama savininkui susisaistyti su aukščiausio lygio operatoriaus susirašinėjimo žinutėmis paslaugos sąsaja. Įprastoms programoms to neturėtų prireikti."</string> + <string name="permlab_bindCarrierMessagingService" msgid="1490229371796969158">"susaistyti su operatoriaus susirašinėjimo paslauga"</string> + <string name="permdesc_bindCarrierMessagingService" msgid="2762882888502113944">"Leidžiama savininkui susisaistyti su aukščiausio lygio operatoriaus susirašinėjimo paslaugos sąsaja. Įprastoms programoms to neturėtų prireikti."</string> <string name="permlab_bindCarrierServices" msgid="3233108656245526783">"susaistyti su operatoriaus paslaugomis"</string> <string name="permdesc_bindCarrierServices" msgid="1391552602551084192">"Savininkui leidžiama susisaistyti su operatoriaus paslaugomis. To niekada neturėtų prireikti naudojant įprastas programas."</string> <string name="policylab_limitPassword" msgid="4497420728857585791">"Nustatyti slaptažodžio taisykles"</string> @@ -523,7 +523,7 @@ <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Stebėkite atrakinant ekraną įvestų netinkamų slaptažodžių skaičių ir užrakinkite TV arba ištrinkite visus šio naudotojo duomenis, jei per daug kartų įvedamas netinkamas slaptažodis."</string> <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Stebėkite atrakinant ekraną įvestų netinkamų slaptažodžių skaičių ir užrakinkite telefoną arba ištrinkite visus šio naudotojo duomenis, jei per daug kartų įvedamas netinkamas slaptažodis."</string> <string name="policylab_resetPassword" msgid="4934707632423915395">"Ekrano užrakto pakeitimas"</string> - <string name="policydesc_resetPassword" msgid="1278323891710619128">"Pakeiskite ekrano užraktą."</string> + <string name="policydesc_resetPassword" msgid="1278323891710619128">"Pakeisti ekrano užraktą."</string> <string name="policylab_forceLock" msgid="2274085384704248431">"Užrakinti ekraną"</string> <string name="policydesc_forceLock" msgid="1141797588403827138">"Valdyti, kaip ir kada užrakinamas ekranas."</string> <string name="policylab_wipeData" msgid="3910545446758639713">"Trinti visus duomenis"</string> @@ -1489,7 +1489,7 @@ <string name="package_installed_device_owner" msgid="8420696545959087545">"Įdiegė administratorius"</string> <string name="package_updated_device_owner" msgid="8856631322440187071">"Atnaujino administratorius"</string> <string name="package_deleted_device_owner" msgid="7650577387493101353">"Ištrynė administratorius"</string> - <string name="battery_saver_description" msgid="1960431123816253034">"Kad tausotų akumuliatoriaus energiją akumuliatoriaus tausojimo priemonė sumažina įrenginio veikimą ir apriboja vibravimą, vietovės paslaugas bei daugumą foninių duomenų. El. pašto, susirašinėjimo žinutėmis ir kitos programos, kurios veikia sinchronizavimo pagrindu, gali būti neatnaujintos, nebent jas atidarysite.\n\nAkumuliatoriaus tausojimo priemonė automatiškai išjungiama, kai įrenginys įkraunamas."</string> + <string name="battery_saver_description" msgid="1960431123816253034">"Kad tausotų akumuliatoriaus energiją akumuliatoriaus tausojimo priemonė sumažina įrenginio veikimą ir apriboja vibravimą, vietovės paslaugas bei daugumą foninių duomenų. El. pašto, susirašinėjimo ir kitos programos, kurios veikia sinchronizavimo pagrindu, gali būti neatnaujintos, nebent jas atidarysite.\n\nAkumuliatoriaus tausojimo priemonė automatiškai išjungiama, kai įrenginys įkraunamas."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> <item quantity="one">%1$d minutę (iki <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> <item quantity="few">%1$d minutes (iki <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> @@ -1540,6 +1540,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Iki <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Kol išjungsite"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sutraukti"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Netrukdyti"</string> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 81b4df9..7acf277 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -1523,6 +1523,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Līdz <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Līdz brīdim, kad izslēgsiet"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Sakļaut"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Netraucēt"</string> diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml index 368ac67..ef436e3 100644 --- a/core/res/res/values-mk-rMK/strings.xml +++ b/core/res/res/values-mk-rMK/strings.xml @@ -1508,6 +1508,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Додека не го исклучите"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Собери"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Не вознемирувај"</string> diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml index 38908ec..5147aad 100644 --- a/core/res/res/values-ml-rIN/strings.xml +++ b/core/res/res/values-ml-rIN/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> വരെ"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"നിങ്ങൾ ഇത് ഓഫാക്കും വരെ"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"ചുരുക്കുക"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"ശല്യപ്പെടുത്തരുത്"</string> diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml index 937aa87..9bda828 100644 --- a/core/res/res/values-mn-rMN/strings.xml +++ b/core/res/res/values-mn-rMN/strings.xml @@ -1504,6 +1504,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> хүртэл"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Таныг унтраах хүртэл"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Хумих"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Бүү саад бол"</string> diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml index 6f8a7bd..53a8cd8 100644 --- a/core/res/res/values-mr-rIN/strings.xml +++ b/core/res/res/values-mr-rIN/strings.xml @@ -608,7 +608,7 @@ <string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string> <string name="eventTypeCustom" msgid="7837586198458073404">"सानुकूल"</string> <string name="eventTypeBirthday" msgid="2813379844211390740">"वाढदिवस"</string> - <string name="eventTypeAnniversary" msgid="3876779744518284000">"वर्धापन दिन"</string> + <string name="eventTypeAnniversary" msgid="3876779744518284000">"वर्षदिन"</string> <string name="eventTypeOther" msgid="7388178939010143077">"अन्य"</string> <string name="emailTypeCustom" msgid="8525960257804213846">"सानुकूल"</string> <string name="emailTypeHome" msgid="449227236140433919">"घर"</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> पर्यंत"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"आपण हे बंद करेपर्यंत"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त करा"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"व्यत्यय आणू नका"</string> diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml index 89372cc..eb980a5 100644 --- a/core/res/res/values-ms-rMY/strings.xml +++ b/core/res/res/values-ms-rMY/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Sehingga <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Sehingga anda matikan"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Runtuhkan"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Jangan ganggu"</string> diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml index d6fcd57..f3e39f7 100644 --- a/core/res/res/values-my-rMM/strings.xml +++ b/core/res/res/values-my-rMM/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>အထိ"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"သင်က ဒါကို ပိတ်မပစ်သည့် အထိ"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"ခေါက်ရန်"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"မနှောက်ယှက်ပါနှင့်"</string> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index f7f3b79..57f7aa0 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -1061,8 +1061,8 @@ <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Alle filer som er lagret på USB-lagringen blir slettet. Denne handlingen kan ikke angres."</string> <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Alle data på kortet fjernes."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formatér"</string> - <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-debugging tilkoblet"</string> - <string name="adb_active_notification_message" msgid="1016654627626476142">"Trykk for å deaktivere USB-feilsøking."</string> + <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-feilsøking tilkoblet"</string> + <string name="adb_active_notification_message" msgid="1016654627626476142">"Trykk for å slå av USB-feilsøking."</string> <string name="select_input_method" msgid="8547250819326693584">"Endre tastatur"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Velg tastatur"</string> <string name="show_ime" msgid="9157568568695230830">"Vis inndatametode"</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Til <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Inntil du slår av funksjonen"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Skjul"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"«Ikke forstyrr»"</string> diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml index cafb892..bcbd753 100644 --- a/core/res/res/values-ne-rNP/strings.xml +++ b/core/res/res/values-ne-rNP/strings.xml @@ -1512,6 +1512,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> सम्म"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"तपाईँले यसलाई बन्द नगरेसम्म"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"संक्षिप्त पार्नुहोस्"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"अवरोध नपुर्याउँनुहोस्"</string> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 4bbec7f..7258590 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Tot <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Totdat u dit uitschakelt"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Samenvouwen"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Niet storen"</string> diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml index a89649c..5585eb1 100644 --- a/core/res/res/values-pa-rIN/strings.xml +++ b/core/res/res/values-pa-rIN/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> ਤੱਕ"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"ਜਦੋਂ ਤੱਕ ਤੁਸੀਂ ਇਸਨੂੰ ਬੰਦ ਨਹੀਂ ਕਰਦੇ ਹੋ"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"ਨਸ਼ਟ ਕਰੋ"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"ਮੈਨੂੰ ਪਰੇਸ਼ਾਨ ਨਾ ਕਰੋ"</string> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index ce3c838..22fc364 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -522,11 +522,11 @@ <string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"Monitorowanie, ile razy wpisano błędne hasło podczas odblokowywania ekranu, oraz blokowanie tabletu albo kasowanie wszystkich danych tego użytkownika, gdy zbyt wiele razy wpisano błędne hasło."</string> <string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"Monitorowanie, ile razy wpisano błędne hasło podczas odblokowywania ekranu, oraz blokowanie telewizora albo kasowanie wszystkich danych tego użytkownika, gdy zbyt wiele razy wpisano błędne hasło."</string> <string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"Monitorowanie, ile razy wpisano błędne hasło podczas odblokowywania ekranu, oraz blokowanie telefonu albo kasowanie wszystkich danych tego użytkownika, gdy zbyt wiele razy wpisano błędne hasło."</string> - <string name="policylab_resetPassword" msgid="4934707632423915395">"Zmień blokadę ekranu"</string> - <string name="policydesc_resetPassword" msgid="1278323891710619128">"Zmiana blokady ekranu."</string> - <string name="policylab_forceLock" msgid="2274085384704248431">"Zablokuj ekran"</string> + <string name="policylab_resetPassword" msgid="4934707632423915395">"Zmiana blokady ekranu"</string> + <string name="policydesc_resetPassword" msgid="1278323891710619128">"Zmiana blokady ekranu"</string> + <string name="policylab_forceLock" msgid="2274085384704248431">"Blokowanie ekranu"</string> <string name="policydesc_forceLock" msgid="1141797588403827138">"Kontrolowanie sposobu i warunków blokowania ekranu"</string> - <string name="policylab_wipeData" msgid="3910545446758639713">"Usuń wszystkie dane"</string> + <string name="policylab_wipeData" msgid="3910545446758639713">"Usuwanie wszystkich danych"</string> <string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Wymazywanie danych z tabletu bez ostrzeżenia przez przywrócenie danych fabrycznych"</string> <string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Skasowanie danych w telewizorze bez ostrzeżenia przez przywrócenie danych fabrycznych."</string> <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Wymazywanie danych z telefonu bez ostrzeżenia przez przywrócenie danych fabrycznych"</string> @@ -1099,7 +1099,7 @@ <string name="ext_media_unmounting_notification_title" msgid="640674168454809372">"Nadal wysuwam: <xliff:g id="NAME">%s</xliff:g>…"</string> <string name="ext_media_unmounting_notification_message" msgid="4182843895023357756">"Nie wyjmuj"</string> <string name="ext_media_init_action" msgid="8317198948634872507">"Skonfiguruj"</string> - <string name="ext_media_unmount_action" msgid="1121883233103278199">"Wysuń"</string> + <string name="ext_media_unmount_action" msgid="1121883233103278199">"Odłącz"</string> <string name="ext_media_browse_action" msgid="8322172381028546087">"Przeglądaj"</string> <string name="ext_media_missing_title" msgid="620980315821543904">"Brak: <xliff:g id="NAME">%s</xliff:g>"</string> <string name="ext_media_missing_message" msgid="5761133583368750174">"Ponownie włóż urządzenie"</string> @@ -1483,7 +1483,7 @@ <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacja jest przypięta. Nie możesz jej odpiąć na tym urządzeniu."</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Ekran przypięty"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran odpięty"</string> - <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Aby odpiąć, poproś o PIN"</string> + <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Podaj PIN, aby odpiąć"</string> <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Aby odpiąć, poproś o wzór odblokowania"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Aby odpiąć, poproś o hasło"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Zainstalowany przez administratora"</string> @@ -1540,6 +1540,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Dopóki nie wyłączysz"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Zwiń"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Nie przeszkadzać"</string> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 250029e..984ee17 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Até que o utilizador desative"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Reduzir"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Não incomodar"</string> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 5f33247..b865267 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Até às <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Até você desativar"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Recolher"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Não perturbe"</string> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 4efd74c..1016f53 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -21,7 +21,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="byteShort" msgid="8340973892742019101">"O"</string> - <string name="kilobyteShort" msgid="5973789783504771878">"KO"</string> + <string name="kilobyteShort" msgid="5973789783504771878">"KB"</string> <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> <string name="gigabyteShort" msgid="3259882455212193214">"GB"</string> <string name="terabyteShort" msgid="231613018159186962">"TO"</string> @@ -228,7 +228,7 @@ <string name="permgroupdesc_location" msgid="536889867433972794">"accesează locația dvs."</string> <string name="permgrouplab_socialInfo" msgid="5799096623412043791">"Informaţiile dvs. sociale"</string> <string name="permgroupdesc_socialInfo" msgid="7129842457611643493">"Acces direct la informaţii despre persoanele de contact și conexiunile dvs. sociale."</string> - <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendarul"</string> + <string name="permgrouplab_calendar" msgid="5863508437783683902">"Calendar"</string> <string name="permgroupdesc_calendar" msgid="3889615280211184106">"accesează calendarul"</string> <string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string> <string name="permgroupdesc_sms" msgid="3714409903876407981">"vede și gestionează mesajele SMS"</string> @@ -904,7 +904,7 @@ <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Deschideți cu %1$s"</string> <string name="whichEditApplication" msgid="144727838241402655">"Editați cu"</string> <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Editați cu %1$s"</string> - <string name="whichSendApplication" msgid="6902512414057341668">"Distribuiți cu"</string> + <string name="whichSendApplication" msgid="6902512414057341668">"Trimiteți prin"</string> <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Distribuiți cu %1$s"</string> <string name="whichHomeApplication" msgid="4307587691506919691">"Selectați o aplicație de pe ecranul de pornire"</string> <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Utilizați %1$s ca ecran de pornire"</string> @@ -1523,6 +1523,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Până la <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Până la dezactivare"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Restrângeți"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Nu deranja"</string> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 1fa55d7..79748d1 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -431,7 +431,7 @@ <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Приложение сможет отключать блокировку экрана и другие функции защиты. Например, блокировка экрана будет отключаться при получении входящего вызова и включаться после завершения разговора."</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"управление сканером отпечатков"</string> <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Приложение сможет добавлять и удалять шаблоны отпечатков пальцев."</string> - <string name="permlab_useFingerprint" msgid="3150478619915124905">"использование сканера отпечатков"</string> + <string name="permlab_useFingerprint" msgid="3150478619915124905">"Использование сканера отпечатков"</string> <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Приложение сможет использовать сканер отпечатков пальцев для аутентификации."</string> <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Отсканирована только часть пальца. Повторите попытку."</string> <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Не удалось распознать отпечаток. Повторите попытку."</string> @@ -1540,6 +1540,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Пока я не отключу"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Свернуть"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Не беспокоить"</string> diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml index a2aba37..2ba76a3 100644 --- a/core/res/res/values-si-rLK/strings.xml +++ b/core/res/res/values-si-rLK/strings.xml @@ -1508,6 +1508,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> තෙක්"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"ඔබ මෙය අක්රිය කරන තුරු"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"හකුළන්න"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"බාධා නොකරන්න"</string> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 9a39eb3..efae3af 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -45,7 +45,7 @@ <string name="defaultVoiceMailAlphaTag" msgid="2660020990097733077">"Hlasová schránka"</string> <string name="defaultMsisdnAlphaTag" msgid="2850889754919584674">"MSISDN1"</string> <string name="mmiError" msgid="5154499457739052907">"Problém s pripojením alebo neplatný kód MMI."</string> - <string name="mmiFdnError" msgid="5224398216385316471">"Operácia je obmedzená len na režim čísla pevného vytáčania."</string> + <string name="mmiFdnError" msgid="5224398216385316471">"Operácia je obmedzená len na povolené čísla."</string> <string name="serviceEnabled" msgid="8147278346414714315">"Služba bola povolená."</string> <string name="serviceEnabledFor" msgid="6856228140453471041">"Služba bola povolená pre:"</string> <string name="serviceDisabled" msgid="1937553226592516411">"Služba bola vypnutá."</string> @@ -58,8 +58,8 @@ <string name="mismatchPin" msgid="609379054496863419">"Zadané kódy PIN sa nezhodujú."</string> <string name="invalidPin" msgid="3850018445187475377">"Zadajte kód PIN s dĺžkou 4 až 8 číslic."</string> <string name="invalidPuk" msgid="8761456210898036513">"Zadajte kód PUK, ktorý má 8 alebo viac čísel."</string> - <string name="needPuk" msgid="919668385956251611">"Karta SIM je uzamknutá pomocou kódu PUK. Odomknite ju zadaním kódu PUK."</string> - <string name="needPuk2" msgid="4526033371987193070">"Ak chcete odblokovať kartu SIM, zadajte kód PUK2."</string> + <string name="needPuk" msgid="919668385956251611">"SIM karta je uzamknutá pomocou kódu PUK. Odomknite ju zadaním kódu PUK."</string> + <string name="needPuk2" msgid="4526033371987193070">"Ak chcete odblokovať SIM kartu, zadajte kód PUK2."</string> <string name="enablePin" msgid="209412020907207950">"Neúspešné, povoľte uzamknutie SIM/RUIM."</string> <plurals name="pinpuk_attempts" formatted="false" msgid="1251012001539225582"> <item quantity="few">Zostávajú vám <xliff:g id="NUMBER_1">%d</xliff:g> pokusy, potom sa vaša SIM karta uzamkne.</item> @@ -278,9 +278,9 @@ <string name="permlab_sendSms" msgid="5600830612147671529">"odosielať správy SMS"</string> <string name="permdesc_sendSms" msgid="7094729298204937667">"Umožňuje aplikácii odosielať správy SMS. Môže to mať za následok účtovanie neočakávaných poplatkov. Škodlivé aplikácie vám môžu spôsobiť výdavky odosielaním správ bez vášho potvrdenia."</string> <string name="permlab_readSms" msgid="8745086572213270480">"čítať textové správy (SMS alebo MMS)"</string> - <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Umožňuje aplikácii čítať správy SMS uložené v tablete alebo na karte SIM. Toto povolenie umožňuje aplikácii čítať správy SMS bez ohľadu na ich obsah alebo dôvernosť."</string> + <string name="permdesc_readSms" product="tablet" msgid="2467981548684735522">"Umožňuje aplikácii čítať správy SMS uložené v tablete alebo na SIM karte. Toto povolenie umožňuje aplikácii čítať správy SMS bez ohľadu na ich obsah alebo dôvernosť."</string> <string name="permdesc_readSms" product="tv" msgid="5102425513647038535">"Umožňuje aplikácii čítať správy SMS uložené vo vašom televízore alebo SIM karte. Toto nastavenie umožňuje aplikácii čítať všetky správy SMS bez ohľadu na ich obsah alebo dôvernosť."</string> - <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Umožňuje aplikácii čítať správy SMS uložené v telefóne alebo na karte SIM. Toto povolenie umožňuje aplikácii čítať správy SMS bez ohľadu na ich obsah alebo dôvernosť."</string> + <string name="permdesc_readSms" product="default" msgid="3695967533457240550">"Umožňuje aplikácii čítať správy SMS uložené v telefóne alebo na SIM karte. Toto povolenie umožňuje aplikácii čítať správy SMS bez ohľadu na ich obsah alebo dôvernosť."</string> <string name="permlab_receiveWapPush" msgid="5991398711936590410">"prijímať textové správy (WAP)"</string> <string name="permdesc_receiveWapPush" msgid="748232190220583385">"Umožňuje aplikácii prijímať a spracovávať správy WAP. Toto povolenie zahŕňa možnosť sledovať vaše správy alebo ich odstrániť bez toho, aby sa vám zobrazili."</string> <string name="permlab_getTasks" msgid="6466095396623933906">"načítať spustené aplikácie"</string> @@ -355,8 +355,8 @@ <string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"Umožňuje aplikácii upraviť globálne nastavenia zvuku, ako je hlasitosť, alebo určiť, z ktorého reproduktora bude zvuk vychádzať."</string> <string name="permlab_recordAudio" msgid="3876049771427466323">"nahrávať zvuk"</string> <string name="permdesc_recordAudio" msgid="4906839301087980680">"Umožňuje aplikácii zaznamenávať zvuk pomocou mikrofónu. Toto povolenie umožňuje aplikácii zaznamenávať zvuk kedykoľvek bez vášho potvrdenia."</string> - <string name="permlab_sim_communication" msgid="1180265879464893029">"komunikácia s kartou SIM"</string> - <string name="permdesc_sim_communication" msgid="5725159654279639498">"Umožňuje aplikácii odosielať príkazy na kartu SIM. Toto je veľmi nebezpečné povolenie."</string> + <string name="permlab_sim_communication" msgid="1180265879464893029">"komunikácia so SIM kartou"</string> + <string name="permdesc_sim_communication" msgid="5725159654279639498">"Umožňuje aplikácii odosielať príkazy na SIM kartu. Toto je veľmi nebezpečné povolenie."</string> <string name="permlab_camera" msgid="3616391919559751192">"fotiť a nakrúcať videá"</string> <string name="permdesc_camera" msgid="8497216524735535009">"Umožňuje aplikácii fotografovať a nahrávať videá pomocou fotoaparátu. Toto povolenie umožňuje aplikácii používať fotoaparát kedykoľvek a bez vášho potvrdenia."</string> <string name="permlab_vibrate" msgid="7696427026057705834">"ovládať vibrovanie"</string> @@ -462,13 +462,13 @@ <string name="permlab_writeDictionary" msgid="2183110402314441106">"pridať slová do slovníka definovaného používateľom"</string> <string name="permdesc_writeDictionary" msgid="8185385716255065291">"Umožňuje aplikácii zapisovať nové slová do používateľského slovníka."</string> <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"čítať obsah úložiska USB"</string> - <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"čítať obsah karty SD"</string> + <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"čítať obsah SD karty"</string> <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Povoľuje ap. čítať obsah USB."</string> - <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Povoľuje aplikácii čítať obsah karty SD."</string> + <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Povoľuje aplikácii čítať obsah SD karty."</string> <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"upraviť alebo odstrániť obsah v úložisku USB"</string> - <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"úprava alebo odstránenie obsahu na karte SD"</string> + <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"úprava alebo odstránenie obsahu na SD karte"</string> <string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Umožňuje aplikácii zapisovať do úložiska USB."</string> - <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Umožňuje aplikácii zápis na kartu SD."</string> + <string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Umožňuje aplikácii zápis na SD kartu."</string> <string name="permlab_use_sip" msgid="2052499390128979920">"uskutočňovanie/príjem hovorov SIP"</string> <string name="permdesc_use_sip" msgid="2297804849860225257">"Umožňuje aplikácii uskutočňovať a prijímať hovory SIP."</string> <string name="permlab_register_sim_subscription" msgid="3166535485877549177">"registrácia nových pripojení telekomunikačnej siete SIM"</string> @@ -642,14 +642,14 @@ <string name="relationTypeAssistant" msgid="6274334825195379076">"Asistent"</string> <string name="relationTypeBrother" msgid="8757913506784067713">"Brat"</string> <string name="relationTypeChild" msgid="1890746277276881626">"Dieťa"</string> - <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Druh(-žka)"</string> + <string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Partner(ka)"</string> <string name="relationTypeFather" msgid="5228034687082050725">"Otec"</string> - <string name="relationTypeFriend" msgid="7313106762483391262">"Priateľ"</string> + <string name="relationTypeFriend" msgid="7313106762483391262">"Kamarát(ka)"</string> <string name="relationTypeManager" msgid="6365677861610137895">"Manažér"</string> <string name="relationTypeMother" msgid="4578571352962758304">"Matka"</string> <string name="relationTypeParent" msgid="4755635567562925226">"Rodič"</string> <string name="relationTypePartner" msgid="7266490285120262781">"Partner(ka)"</string> - <string name="relationTypeReferredBy" msgid="101573059844135524">"Odporúča"</string> + <string name="relationTypeReferredBy" msgid="101573059844135524">"Odporučenie"</string> <string name="relationTypeRelative" msgid="1799819930085610271">"Príbuzný(-á)"</string> <string name="relationTypeSister" msgid="1735983554479076481">"Sestra"</string> <string name="relationTypeSpouse" msgid="394136939428698117">"Manžel(ka)"</string> @@ -679,14 +679,14 @@ <string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Skúsiť znova"</string> <string name="lockscreen_password_wrong" msgid="5737815393253165301">"Skúsiť znova"</string> <string name="faceunlock_multiple_failures" msgid="754137583022792429">"Prekročili ste maximálny povolený počet pokusov o odomknutie tvárou"</string> - <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Nie je vložená karta SIM"</string> - <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"V tablete nie je žiadna karta SIM."</string> + <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Nie je vložená SIM karta"</string> + <string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"V tablete nie je žiadna SIM karta."</string> <string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"V televízore nie je žiadna SIM karta."</string> - <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"V telefóne nie je žiadna karta SIM."</string> - <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Vložte kartu SIM."</string> - <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"Karta SIM chýba alebo sa z nej nedá čítať. Vložte kartu SIM."</string> - <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"Karta SIM je nepoužiteľná."</string> - <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Vaša karta SIM bola natrvalo zakázaná.\nAk chcete získať inú kartu SIM, kontaktujte svojho operátora."</string> + <string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"V telefóne nie je žiadna SIM karta."</string> + <string name="lockscreen_missing_sim_instructions" msgid="5372787138023272615">"Vložte SIM kartu."</string> + <string name="lockscreen_missing_sim_instructions_long" msgid="3526573099019319472">"SIM karta chýba alebo sa z nej nedá čítať. Vložte SIM kartu."</string> + <string name="lockscreen_permanent_disabled_sim_message_short" msgid="5096149665138916184">"SIM karta je nepoužiteľná."</string> + <string name="lockscreen_permanent_disabled_sim_instructions" msgid="910904643433151371">"Vaša SIM karta bola natrvalo zakázaná.\nAk chcete získať inú SIM kartu, kontaktujte svojho operátora."</string> <string name="lockscreen_transport_prev_description" msgid="6300840251218161534">"Predchádzajúca stopa"</string> <string name="lockscreen_transport_next_description" msgid="573285210424377338">"Ďalšia stopa"</string> <string name="lockscreen_transport_pause_description" msgid="3980308465056173363">"Pozastaviť"</string> @@ -696,10 +696,10 @@ <string name="lockscreen_transport_ffw_description" msgid="42987149870928985">"Pretočiť dopredu"</string> <string name="emergency_calls_only" msgid="6733978304386365407">"Len tiesňové volania"</string> <string name="lockscreen_network_locked_message" msgid="143389224986028501">"Sieť je zablokovaná"</string> - <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"Karta SIM je uzamknutá pomocou kódu PUK."</string> + <string name="lockscreen_sim_puk_locked_message" msgid="7441797339976230">"SIM karta je uzamknutá pomocou kódu PUK."</string> <string name="lockscreen_sim_puk_locked_instructions" msgid="8127916255245181063">"Prečítajte si Príručku používateľa alebo kontaktujte podporu zákazníka."</string> - <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"Karta SIM je uzamknutá."</string> - <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Prebieha odomykanie karty SIM..."</string> + <string name="lockscreen_sim_locked_message" msgid="8066660129206001039">"SIM karta je uzamknutá."</string> + <string name="lockscreen_sim_unlock_progress_dialog_message" msgid="595323214052881264">"Prebieha odomykanie SIM karty..."</string> <string name="lockscreen_too_many_failed_attempts_dialog_message" msgid="6481623830344107222">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste použili nesprávny bezpečnostný vzor. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string> <string name="lockscreen_too_many_failed_password_attempts_dialog_message" msgid="2725973286239344555">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávne heslo. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string> <string name="lockscreen_too_many_failed_pin_attempts_dialog_message" msgid="6216672706545696955">"<xliff:g id="NUMBER_0">%d</xliff:g>-krát ste zadali nesprávny kód PIN. \n\nSkúste to znova o <xliff:g id="NUMBER_1">%d</xliff:g> s."</string> @@ -899,7 +899,7 @@ <string name="cancel" msgid="6442560571259935130">"Zrušiť"</string> <string name="yes" msgid="5362982303337969312">"OK"</string> <string name="no" msgid="5141531044935541497">"Zrušiť"</string> - <string name="dialog_alert_title" msgid="2049658708609043103">"Pozor"</string> + <string name="dialog_alert_title" msgid="2049658708609043103">"Upozornenie"</string> <string name="loading" msgid="7933681260296021180">"Prebieha načítavanie..."</string> <string name="capital_on" msgid="1544682755514494298">"I"</string> <string name="capital_off" msgid="6815870386972805832">"O"</string> @@ -909,7 +909,7 @@ <string name="whichViewApplicationNamed" msgid="2286418824011249620">"Otvoriť v aplikácii %1$s"</string> <string name="whichEditApplication" msgid="144727838241402655">"Upraviť pomocou"</string> <string name="whichEditApplicationNamed" msgid="1775815530156447790">"Upraviť v aplikácii %1$s"</string> - <string name="whichSendApplication" msgid="6902512414057341668">"Zdieľať v aplikácii"</string> + <string name="whichSendApplication" msgid="6902512414057341668">"Zdieľať"</string> <string name="whichSendApplicationNamed" msgid="2799370240005424391">"Zdieľať v aplikácii %1$s"</string> <string name="whichHomeApplication" msgid="4307587691506919691">"Výber aplikácie na plochu"</string> <string name="whichHomeApplicationNamed" msgid="4493438593214760979">"Ako plochu používať aplikáciu %1$s"</string> @@ -1029,10 +1029,10 @@ <string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"Zmena v časti Nastavenia > Aplikácie"</string> <string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"Vždy povoliť"</string> <string name="sms_short_code_confirm_never_allow" msgid="446992765774269673">"Nikdy nepovoliť"</string> - <string name="sim_removed_title" msgid="6227712319223226185">"Karta SIM bola odobraná"</string> + <string name="sim_removed_title" msgid="6227712319223226185">"SIM karta bola odobraná"</string> <string name="sim_removed_message" msgid="5450336489923274918">"Mobilná sieť nebude k dispozícii, kým nevložíte platnú SIM kartu a zariadenie nereštartujete."</string> <string name="sim_done_button" msgid="827949989369963775">"Hotovo"</string> - <string name="sim_added_title" msgid="3719670512889674693">"Bola pridaná karta SIM"</string> + <string name="sim_added_title" msgid="3719670512889674693">"Bola pridaná SIM karta"</string> <string name="sim_added_message" msgid="7797975656153714319">"Ak chcete získať prístup k mobilnej sieti, reštartujte svoje zariadenie."</string> <string name="sim_restart_button" msgid="4722407842815232347">"Reštartovať"</string> <string name="time_picker_dialog_title" msgid="8349362623068819295">"Nastaviť čas"</string> @@ -1046,17 +1046,17 @@ <string name="usb_storage_activity_title" msgid="4465055157209648641">"Veľkokapacitné úložisko USB"</string> <string name="usb_storage_title" msgid="5901459041398751495">"Zariadenie USB pripojené"</string> <string name="usb_storage_message" product="nosdcard" msgid="3308538094316477839">"Zariadenie ste pripojili k počítaču pomocou portu USB. Ak chcete kopírovať súbory z počítača do ukladacieho priestoru USB v zariadení so systémom Android alebo naopak, dotknite sa tlačidla nižšie."</string> - <string name="usb_storage_message" product="default" msgid="805351000446037811">"Zariadenie ste pripojili k počítaču pomocou USB. Ak chcete kopírovať súbory z počítača na kartu SD v zariadení so systémom Android alebo naopak, dotknite sa tlačidla nižšie."</string> + <string name="usb_storage_message" product="default" msgid="805351000446037811">"Zariadenie ste pripojili k počítaču pomocou USB. Ak chcete kopírovať súbory z počítača na SD kartu v zariadení so systémom Android alebo naopak, dotknite sa tlačidla nižšie."</string> <string name="usb_storage_button_mount" msgid="1052259930369508235">"Zapnúť ukladací priestor USB"</string> <string name="usb_storage_error_message" product="nosdcard" msgid="3017045217365540658">"Pri používaní vášho úložiska USB ako veľkokapacitného ukladacieho priestoru USB sa vyskytol problém."</string> - <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Pri používaní vašej karty SD ako veľkokapacitného ukladacieho priestoru USB sa vyskytol problém."</string> + <string name="usb_storage_error_message" product="default" msgid="2876018512716970313">"Pri používaní vašej SD karty ako veľkokapacitného ukladacieho priestoru USB sa vyskytol problém."</string> <string name="usb_storage_notification_title" msgid="8175892554757216525">"Zariadenie USB pripojené"</string> <string name="usb_storage_notification_message" msgid="939822783828183763">"Dotykom skopírujete súbory do / z počítača."</string> <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Vypnúť ukladací priestor USB"</string> <string name="usb_storage_stop_notification_message" msgid="1656852098555623822">"Dotykom vypnete ukladací priestor USB."</string> <string name="usb_storage_stop_title" msgid="660129851708775853">"Ukladací priestor USB sa používa"</string> <string name="usb_storage_stop_message" product="nosdcard" msgid="4264025280777219521">"Pred vypnutím ukladacieho priestoru USB odpojte od počítača („vysuňte“) ukladací priestor USB systému Android."</string> - <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Pred vypnutím ukladacieho priestoru USB odpojte („vysuňte“) z počítača kartu SD zariadenia Android."</string> + <string name="usb_storage_stop_message" product="default" msgid="8043969782460613114">"Pred vypnutím ukladacieho priestoru USB odpojte („vysuňte“) z počítača SD kartu zariadenia Android."</string> <string name="usb_storage_stop_button_mount" msgid="7060218034900696029">"Vypnúť ukladací priestor USB"</string> <string name="usb_storage_stop_error_message" msgid="1970374898263063836">"Pri vypínaní ukladacieho priestoru USB sa vyskytol problém. Uistite sa, či bol hostiteľ USB odpojený, a skúste to znova."</string> <string name="dlg_confirm_kill_storage_users_title" msgid="963039033470478697">"Zapnúť ukladací priestor USB"</string> @@ -1071,12 +1071,12 @@ <string name="usb_accessory_notification_title" msgid="7848236974087653666">"Pripojené k periférnemu zariadeniu USB"</string> <string name="usb_notification_message" msgid="7347368030849048437">"Ďalšie možnosti zobrazíte klepnutím."</string> <string name="extmedia_format_title" product="nosdcard" msgid="9020092196061007262">"Formátovať ukladací priestor USB?"</string> - <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formátovať kartu SD?"</string> + <string name="extmedia_format_title" product="default" msgid="3648415921526526069">"Formátovať SD kartu?"</string> <string name="extmedia_format_message" product="nosdcard" msgid="3934016853425761078">"Všetky súbory uložené v ukladacom priestore USB budú vymazané. Táto akcia sa nedá vrátiť späť!"</string> <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Všetky údaje na vašej karte budú stratené."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Formát"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez USB pripojené"</string> - <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotknutím zakážete ladenie USB."</string> + <string name="adb_active_notification_message" msgid="1016654627626476142">"Klepnutím zakážete ladenie USB"</string> <string name="select_input_method" msgid="8547250819326693584">"Zmeniť klávesnicu"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Vybrať klávesnice"</string> <string name="show_ime" msgid="9157568568695230830">"Zobraziť metódu vstupu"</string> @@ -1147,7 +1147,7 @@ <string name="vpn_title_long" msgid="6400714798049252294">"Aplikáciu <xliff:g id="APP">%s</xliff:g> aktivovala sieť VPN"</string> <string name="vpn_text" msgid="3011306607126450322">"Dotykom môžete spravovať sieť."</string> <string name="vpn_text_long" msgid="6407351006249174473">"Pripojené k relácii <xliff:g id="SESSION">%s</xliff:g>. Po dotyku môžete sieť spravovať."</string> - <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Prebieha pripájanie k vždy zapnutej sieti VPN..."</string> + <string name="vpn_lockdown_connecting" msgid="6443438964440960745">"Pripájanie k vždy zapnutej sieti VPN…"</string> <string name="vpn_lockdown_connected" msgid="8202679674819213931">"Pripojenie k vždy zapnutej sieti VPN"</string> <string name="vpn_lockdown_error" msgid="6009249814034708175">"Chyba vždy zapnutej siete VPN"</string> <string name="vpn_lockdown_config" msgid="6415899150671537970">"Dotykom spustíte konfiguráciu"</string> @@ -1172,17 +1172,17 @@ </plurals> <string name="action_mode_done" msgid="7217581640461922289">"Hotovo"</string> <string name="progress_unmounting" product="nosdcard" msgid="3923810448507612746">"Prebieha odpájanie úložiska USB..."</string> - <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Prebieha odpájanie karty SD..."</string> + <string name="progress_unmounting" product="default" msgid="1327894998409537190">"Prebieha odpájanie SD karty..."</string> <string name="progress_erasing" product="nosdcard" msgid="4521573321524340058">"Prebieha vymazávanie ukladacieho priestoru USB..."</string> - <string name="progress_erasing" product="default" msgid="6596988875507043042">"Prebieha vymazávanie karty SD..."</string> + <string name="progress_erasing" product="default" msgid="6596988875507043042">"Prebieha vymazávanie SD karty..."</string> <string name="format_error" product="nosdcard" msgid="6299769563624776948">"Nepodarilo sa vymazať ukladací priestor USB"</string> - <string name="format_error" product="default" msgid="7315248696644510935">"Nepodarilo sa vymazať kartu SD"</string> - <string name="media_bad_removal" msgid="7960864061016603281">"Karta SD nebola pred odstránením odpojená."</string> + <string name="format_error" product="default" msgid="7315248696644510935">"Nepodarilo sa vymazať SD kartu"</string> + <string name="media_bad_removal" msgid="7960864061016603281">"SD karta nebola pred odstránením odpojená."</string> <string name="media_checking" product="nosdcard" msgid="418188720009569693">"Prebieha kontrola ukladacieho priestoru USB."</string> - <string name="media_checking" product="default" msgid="7334762503904827481">"Prebieha kontrola karty SD."</string> - <string name="media_removed" msgid="7001526905057952097">"Karta SD bola odstránená."</string> + <string name="media_checking" product="default" msgid="7334762503904827481">"Prebieha kontrola SD karty."</string> + <string name="media_removed" msgid="7001526905057952097">"SD karta bola odstránená."</string> <string name="media_shared" product="nosdcard" msgid="5830814349250834225">"Ukladací priestor USB je momentálne používaný počítačom."</string> - <string name="media_shared" product="default" msgid="5706130568133540435">"Karta SD sa momentálne používa počítačom."</string> + <string name="media_shared" product="default" msgid="5706130568133540435">"SD karta sa momentálne používa počítačom."</string> <string name="media_unknown_state" msgid="729192782197290385">"Neznámy stav externého média."</string> <string name="share" msgid="1778686618230011964">"Zdieľať"</string> <string name="find" msgid="4808270900322985960">"Nájsť"</string> @@ -1211,7 +1211,7 @@ <string name="time_picker_increment_hour_button" msgid="3652056055810223139">"Pridať hodinu"</string> <string name="time_picker_decrement_hour_button" msgid="1377479863429214792">"Ubrať hodinu"</string> <string name="time_picker_increment_set_pm_button" msgid="4147590696151230863">"Nastaviť čas popoludní"</string> - <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Nastaviť čas dopoludnia"</string> + <string name="time_picker_decrement_set_am_button" msgid="8302140353539486752">"Nastaviť čas AM"</string> <string name="date_picker_increment_month_button" msgid="5369998479067934110">"Pridať mesiac"</string> <string name="date_picker_decrement_month_button" msgid="1832698995541726019">"Ubrať mesiac"</string> <string name="date_picker_increment_day_button" msgid="7130465412308173903">"Pridať deň"</string> @@ -1241,8 +1241,8 @@ <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string> <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string> <string name="storage_internal" msgid="4891916833657929263">"Interné úložisko"</string> - <string name="storage_sd_card" msgid="3282948861378286745">"Karta SD"</string> - <string name="storage_sd_card_label" msgid="6347111320774379257">"Karta SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string> + <string name="storage_sd_card" msgid="3282948861378286745">"SD karta"</string> + <string name="storage_sd_card_label" msgid="6347111320774379257">"SD karta <xliff:g id="MANUFACTURER">%s</xliff:g>"</string> <string name="storage_usb_drive" msgid="6261899683292244209">"Disk USB"</string> <string name="storage_usb_drive_label" msgid="4501418548927759953">"Disk USB <xliff:g id="MANUFACTURER">%s</xliff:g>"</string> <string name="storage_usb" msgid="3017954059538517278">"Ukladací priestor USB"</string> @@ -1316,17 +1316,17 @@ <string name="kg_wrong_pin" msgid="1131306510833563801">"Nesprávny kód PIN"</string> <string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"Skúste to znova o <xliff:g id="NUMBER">%1$d</xliff:g> s."</string> <string name="kg_pattern_instructions" msgid="398978611683075868">"Nakreslite svoj vzor"</string> - <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Zadajte kód PIN karty SIM"</string> + <string name="kg_sim_pin_instructions" msgid="2319508550934557331">"Zadajte kód PIN SIM karty"</string> <string name="kg_pin_instructions" msgid="2377242233495111557">"Zadajte kód PIN"</string> <string name="kg_password_instructions" msgid="5753646556186936819">"Zadajte heslo"</string> - <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"Karta SIM je teraz zakázaná. Ak chcete pokračovať, zadajte kód PUK. Podrobné informácie získate od operátora."</string> + <string name="kg_puk_enter_puk_hint" msgid="453227143861735537">"SIM karta je teraz zakázaná. Ak chcete pokračovať, zadajte kód PUK. Podrobné informácie získate od operátora."</string> <string name="kg_puk_enter_pin_hint" msgid="7871604527429602024">"Zadajte požadovaný kód PIN"</string> <string name="kg_enter_confirm_pin_hint" msgid="325676184762529976">"Potvrďte požadovaný kód PIN"</string> - <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Prebieha odomykanie karty SIM..."</string> + <string name="kg_sim_unlock_progress_dialog_message" msgid="8950398016976865762">"Prebieha odomykanie SIM karty..."</string> <string name="kg_password_wrong_pin_code" msgid="1139324887413846912">"Nesprávny kód PIN."</string> <string name="kg_invalid_sim_pin_hint" msgid="8795159358110620001">"Zadajte kód PIN s dĺžkou 4 až 8 číslic."</string> <string name="kg_invalid_sim_puk_hint" msgid="6025069204539532000">"Kód PUK musí obsahovať 8 číslic."</string> - <string name="kg_invalid_puk" msgid="3638289409676051243">"Znova zadajte správny kód PUK. Opakované pokusy zakážu kartu SIM natrvalo."</string> + <string name="kg_invalid_puk" msgid="3638289409676051243">"Znova zadajte správny kód PUK. Opakované pokusy zakážu SIM kartu natrvalo."</string> <string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"Kódy PIN sa nezhodujú"</string> <string name="kg_login_too_many_attempts" msgid="6486842094005698475">"Príliš veľa pokusov o nakreslenie vzoru"</string> <string name="kg_login_instructions" msgid="1100551261265506448">"Ak chcete telefón odomknúť, prihláste sa pomocou svojho účtu Google."</string> @@ -1540,6 +1540,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Dokým túto funkciu nevypnete"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Zbaliť"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Nerušiť"</string> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index bb87a01..80d2207 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -247,9 +247,9 @@ <string name="permgroupdesc_sensors" msgid="6376772456799240169">"dostop do podatkov tipal in nosljivih naprav"</string> <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Pridobiti vsebino okna"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Preverjanje vsebine okna, ki ga uporabljate."</string> - <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Vklop raziskovanja z dotikom"</string> + <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Vklopiti raziskovanje z dotikom"</string> <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Elementi, ki se jih dotaknete, bodo izrečeni naglas, zaslon pa lahko raziskujete s potezami."</string> - <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Vklop izboljšanja dostopnosti spleta za ljudi s posebnimi potrebami"</string> + <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Vklopiti izboljšano dostopnost spleta za ljudi s posebnimi potrebami"</string> <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Za boljšo dostopnost vsebine aplikacije je mogoče namestiti skripte."</string> <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Opazovati besedilo, ki ga natipkate"</string> <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Vključuje osebne podatke, kot so številke kreditnih kartic in gesla."</string> @@ -1240,7 +1240,7 @@ <string name="action_menu_overflow_description" msgid="2295659037509008453">"Več možnosti"</string> <string name="action_bar_home_description_format" msgid="7965984360903693903">"%1$s, %2$s"</string> <string name="action_bar_home_subtitle_description_format" msgid="6985546530471780727">"%1$s, %2$s, %3$s"</string> - <string name="storage_internal" msgid="4891916833657929263">"Notranji pomnilnik"</string> + <string name="storage_internal" msgid="4891916833657929263">"Notranja shramba"</string> <string name="storage_sd_card" msgid="3282948861378286745">"Kartica SD"</string> <string name="storage_sd_card_label" msgid="6347111320774379257">"Kartica SD <xliff:g id="MANUFACTURER">%s</xliff:g>"</string> <string name="storage_usb_drive" msgid="6261899683292244209">"Pogon USB"</string> @@ -1483,7 +1483,7 @@ <string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je pripeta: v tej napravi odpenjanje ni dovoljeno."</string> <string name="lock_to_app_start" msgid="6643342070839862795">"Zaslon je pripet"</string> <string name="lock_to_app_exit" msgid="8598219838213787430">"Zaslon je odpet"</string> - <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Pred odpenjanjem vprašaj za PIN"</string> + <string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Zahtevaj PIN pred odpenjanjem"</string> <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pred odpenjanjem vprašaj za vzorec za odklepanje"</string> <string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pred odpenjanjem vprašaj za geslo"</string> <string name="package_installed_device_owner" msgid="8420696545959087545">"Namestil skrbnik"</string> @@ -1540,11 +1540,13 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Do <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Dokler tega ne izklopite"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Strni"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Ne moti"</string> <string name="zen_mode_downtime_feature_name" msgid="2626974636779860146">"Čas nedelovanja"</string> - <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Večer med tednom"</string> + <string name="zen_mode_default_weeknights_name" msgid="3081318299464998143">"Noč med tednom"</string> <string name="zen_mode_default_weekends_name" msgid="2786495801019345244">"Konec tedna"</string> <string name="zen_mode_default_events_name" msgid="8158334939013085363">"Dogodek"</string> <string name="muted_by" msgid="6147073845094180001">"Izklop zvoka: <xliff:g id="THIRD_PARTY">%1$s</xliff:g>"</string> diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml index 5e1a383..3edad21 100644 --- a/core/res/res/values-sq-rAL/strings.xml +++ b/core/res/res/values-sq-rAL/strings.xml @@ -20,9 +20,9 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="byteShort" msgid="8340973892742019101">"bajt"</string> + <string name="byteShort" msgid="8340973892742019101">"B"</string> <string name="kilobyteShort" msgid="5973789783504771878">"kilobajt"</string> - <string name="megabyteShort" msgid="6355851576770428922">"megabajt"</string> + <string name="megabyteShort" msgid="6355851576770428922">"MB"</string> <string name="gigabyteShort" msgid="3259882455212193214">"gigabajt"</string> <string name="terabyteShort" msgid="231613018159186962">"terabajt"</string> <string name="petabyteShort" msgid="5637816680144990219">"petabajt"</string> @@ -205,7 +205,7 @@ <string name="global_action_power_off" msgid="4471879440839879722">"Fik"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"Raporti i defekteve në kod"</string> <string name="bugreport_title" msgid="2667494803742548533">"Merr raportin e defekteve në kod"</string> - <string name="bugreport_message" msgid="398447048750350456">"Kjo do të mbledhë informacione rreth gjendjes aktuale të pajisjes për ta dërguar si mesazh mail-i. Do të duhet pak kohë nga nisja e raportit të defektit në kod. Faleminderit për durimin."</string> + <string name="bugreport_message" msgid="398447048750350456">"Ky funksion mundëson mbledhjen e informacioneve mbi gjendjen aktuale të pajisjes për ta dërguar si mesazh mail-i. Do të duhet pak kohë nga nisja e raportit të defekteve në kod. Faleminderit për durimin."</string> <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Modaliteti \"në heshtje\""</string> <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Zëri është çaktivizuar"</string> <string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Zëri është i aktivizuar"</string> @@ -243,14 +243,14 @@ <string name="permgroupdesc_phone" msgid="6234224354060641055">"kryej dhe menaxho telefonata"</string> <string name="permgrouplab_sensors" msgid="7416703484233940260">"Sensorët"</string> <string name="permgroupdesc_sensors" msgid="6376772456799240169">"qasu te të dhënat nga sensorët dhe pajisjet që vishen"</string> - <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Gjej përmbajtjen e dritares"</string> - <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspekto përmbajtjen e dritares me të cilën po bashkëvepron."</string> + <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"nxjerrë përmbajtjen e dritares"</string> + <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Inspekton përmbajtjen e dritares me të cilën po bashkëvepron."</string> <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Aktivizo \"Eksploro me prekje\""</string> <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"Artikujt e prekur do të lexohen me zë të lartë dhe ekrani mund të eksplorohet duke përdorur gjeste."</string> <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"Aktivizo qasjen e zgjeruar në ueb"</string> <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"Skriptet mund të instalohen për ta bërë përmbajtjen e aplikacionit më të qasshme."</string> - <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"Vëzhgo tekstin që shkruan"</string> - <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Përfshin të dhëna personale si numra kartash krediti dhe fjalëkalime."</string> + <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"vëzhgojë tekstin që shkruan"</string> + <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"Përfshi të dhënat personale si numrat e kartave të kreditit si dhe fjalëkalimet."</string> <string name="permlab_statusBar" msgid="7417192629601890791">"çaktivizo ose modifiko shiritin e statusit"</string> <string name="permdesc_statusBar" msgid="8434669549504290975">"Lejon aplikacionin të çaktivizojë shiritin e statusit dhe të heqë ikonat e sistemit."</string> <string name="permlab_statusBarService" msgid="7247281911387931485">"shiriti i statusit"</string> @@ -882,7 +882,7 @@ <string name="editTextMenuTitle" msgid="4909135564941815494">"Veprimet e tekstit"</string> <string name="low_internal_storage_view_title" msgid="5576272496365684834">"Hapësira ruajtëse po mbaron"</string> <string name="low_internal_storage_view_text" msgid="6640505817617414371">"Disa funksione të sistemit mund të mos punojnë"</string> - <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nuk ka hapësirë të mjaftueshme ruajtjeje për sistemin. Sigurohu që ke 250 megabajt hapësirë të lirë dhe rifillo."</string> + <string name="low_internal_storage_view_text_no_boot" msgid="6935190099204693424">"Nuk ka hapësirë të mjaftueshme ruajtjeje për sistemin. Sigurohu që të kesh 250 MB hapësirë të lirë dhe pastaj të rifillosh."</string> <string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> është në punë."</string> <string name="app_running_notification_text" msgid="4653586947747330058">"Prek për më shumë informacion ose për të ndaluar aplikacionin."</string> <string name="ok" msgid="5970060430562524910">"Në rregull"</string> @@ -1124,7 +1124,7 @@ <string name="forward_intent_to_work" msgid="621480743856004612">"Këtë aplikacion po e përdor në profilin tënd të punës"</string> <string name="input_method_binding_label" msgid="1283557179944992649">"Metoda e hyrjeve"</string> <string name="sync_binding_label" msgid="3687969138375092423">"Sinkronizo"</string> - <string name="accessibility_binding_label" msgid="4148120742096474641">"Qasja"</string> + <string name="accessibility_binding_label" msgid="4148120742096474641">"Qasshmëria"</string> <string name="wallpaper_binding_label" msgid="1240087844304687662">"Imazhi i sfondit"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Ndrysho imazhin e sfondit"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Dëgjues njoftimesh"</string> @@ -1471,7 +1471,7 @@ <string name="package_installed_device_owner" msgid="8420696545959087545">"U instalua nga administratori yt"</string> <string name="package_updated_device_owner" msgid="8856631322440187071">"Përditësuar nga administratori"</string> <string name="package_deleted_device_owner" msgid="7650577387493101353">"U fshi nga administratori yt"</string> - <string name="battery_saver_description" msgid="1960431123816253034">"Për të përmirësuar jetëgjatësinë e baterisë, opsioni i kursimit të baterisë ul rendimentin e pajisjes tënde dhe kufizon dridhjen, shërbimet e vendndodhjes dhe shumicën e të dhënave në sfond. Mail-i, mesazhet dhe aplikacione të tjera që mbështeten në sinkronizim mund të mos përditësohen pa i hapur.\n\nKursimi i baterisë çaktivizohet automatikisht kur pajisja vihet në ngarkim."</string> + <string name="battery_saver_description" msgid="1960431123816253034">"Për të përmirësuar jetëgjatësinë e baterisë, opsioni i kursimit të baterisë ul rendimentin e pajisjes tënde si dhe kufizon dridhjet dhe shumicën e të dhënave në sfond. Mail-i, mesazhet dhe aplikacionet e tjera që sinkronizohen automatikisht mund të mos përditësohen pa i hapur.\n\nKursimi i baterisë çaktivizohet automatikisht kur pajisja vihet në ngarkim."</string> <plurals name="zen_mode_duration_minutes_summary" formatted="false" msgid="4367877408072000848"> <item quantity="other">Për %1$d minuta (deri në <xliff:g id="FORMATTEDTIME_1">%2$s</xliff:g>)</item> <item quantity="one">Për një minutë (deri në <xliff:g id="FORMATTEDTIME_0">%2$s</xliff:g>)</item> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Deri në <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Deri sa ta çaktivizosh këtë"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Shpalos"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Mos shqetëso"</string> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 8abb855..71202fe 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -1523,6 +1523,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Док не искључите"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Скупи"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Не узнемиравај"</string> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index 729c4d1..e743e5c 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Till kl. <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Tills du inaktiverar detta"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Komprimera"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Stör ej"</string> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index 9f37a05..17c2402 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -1508,6 +1508,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Hadi <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Hadi utakapozima hili"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Kunja"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Usinisumbue"</string> diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml index 91a41cd..f80548f 100644 --- a/core/res/res/values-ta-rIN/strings.xml +++ b/core/res/res/values-ta-rIN/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> வரை"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"இதை முடக்கும்வரை"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"சுருக்கு"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"தொந்தரவு செய்ய வேண்டாம்"</string> diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml index 132e53d..d5afd8f 100644 --- a/core/res/res/values-te-rIN/strings.xml +++ b/core/res/res/values-te-rIN/strings.xml @@ -204,7 +204,7 @@ <string name="global_action_lock" msgid="2844945191792119712">"స్క్రీన్ లాక్"</string> <string name="global_action_power_off" msgid="4471879440839879722">"పవర్ ఆఫ్ చేయి"</string> <string name="global_action_bug_report" msgid="7934010578922304799">"బగ్ నివేదిక"</string> - <string name="bugreport_title" msgid="2667494803742548533">"బగ్ నివేదికను తీయి"</string> + <string name="bugreport_title" msgid="2667494803742548533">"బగ్ నివేదికను సిద్ధం చేయి"</string> <string name="bugreport_message" msgid="398447048750350456">"ఇది ఇ-మెయిల్ సందేశం రూపంలో పంపడానికి మీ ప్రస్తుత పరికర స్థితి గురించి సమాచారాన్ని సేకరిస్తుంది. బగ్ నివేదికను ప్రారంభించడం మొదలుకొని పంపడానికి సిద్ధం చేసే వరకు ఇందుకు కొంత సమయం పడుతుంది; దయచేసి ఓపిక పట్టండి."</string> <string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"నిశ్శబ్ద మోడ్"</string> <string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"ధ్వని ఆఫ్లో ఉంది"</string> @@ -243,13 +243,13 @@ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ఫోన్ కాల్లను చేస్తుంది మరియు నిర్వహిస్తుంది"</string> <string name="permgrouplab_sensors" msgid="7416703484233940260">"సెన్సార్లు"</string> <string name="permgroupdesc_sensors" msgid="6376772456799240169">"సెన్సార్లు మరియు వేరబుల్ పరికరాల డేటాను ప్రాప్యత చేస్తుంది"</string> - <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"విండో కంటెంట్ను మరలా పొందండి"</string> + <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"విండో కంటెంట్ను తిరిగి పొందుతుంది"</string> <string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"మీరు పరస్పర చర్య చేస్తున్న విండో కంటెంట్ను పరిశీలించండి."</string> - <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"తాకడం ద్వారా విశ్లేషణను ప్రారంభించండి"</string> + <string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"తాకడం ద్వారా విశ్లేషణను ప్రారంభిస్తుంది"</string> <string name="capability_desc_canRequestTouchExploration" msgid="5800552516779249356">"తాకిన అంశాలు బిగ్గరగా చదివి వినిపించబడతాయి మరియు సంజ్ఞలను ఉపయోగించి స్క్రీన్ను విశ్లేషించవచ్చు."</string> - <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"మెరుగైన వెబ్ ప్రాప్యతను ప్రారంభించండి"</string> + <string name="capability_title_canRequestEnhancedWebAccessibility" msgid="1739881766522594073">"మెరుగైన వెబ్ ప్రాప్యతను ప్రారంభిస్తుంది"</string> <string name="capability_desc_canRequestEnhancedWebAccessibility" msgid="7881063961507511765">"అనువర్తన కంటెంట్కు మరింత సులభ ప్రాప్యత సౌలభ్యం అందించడానికి స్క్రిప్ట్లు ఇన్స్టాల్ చేయబడవచ్చు."</string> - <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"మీరు టైప్ చేస్తున్న వచనాన్ని పరిశీలించండి"</string> + <string name="capability_title_canRequestFilterKeyEvents" msgid="2103440391902412174">"మీరు టైప్ చేస్తున్న వచనాన్ని పరిశీలిస్తుంది"</string> <string name="capability_desc_canRequestFilterKeyEvents" msgid="7463135292204152818">"క్రెడిట్ కార్డు నంబర్లు మరియు పాస్వర్డ్ల వంటి వ్యక్తిగత డేటాను కలిగి ఉంటుంది."</string> <string name="permlab_statusBar" msgid="7417192629601890791">"స్థితి బార్ను నిలిపివేయడం లేదా సవరించడం"</string> <string name="permdesc_statusBar" msgid="8434669549504290975">"స్థితి బార్ను నిలిపివేయడానికి లేదా సిస్టమ్ చిహ్నాలను జోడించడానికి మరియు తీసివేయడానికి అనువర్తనాన్ని అనుమతిస్తుంది."</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> వరకు"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"మీరు దీన్ని ఆఫ్ చేసే వరకు"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"కుదించండి"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"అంతరాయం కలిగించవద్దు"</string> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index a656fb5..8d26b5a 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"จนถึงเวลา <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"จนกว่าคุณจะปิดฟังก์ชันนี้"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"ยุบ"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"ห้ามรบกวน"</string> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 9cf34ae..8d81e7a 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -429,7 +429,7 @@ <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Pinapayagan ang app na huwag paganahin ang keylock at anumang nauugnay na seguridad sa password. Halimbawa, hindi pinapagana ng telepono ang keylock kapag nakakatanggap ng papasok na tawag sa telepono, pagkatapos ay muling pinapagana ang keylock kapag tapos na ang tawag."</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"pamahalaan ang hardware ng fingerprint"</string> <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Pinapayagan ang app na mag-invoke ng mga paraan upang magdagdag at mag-delete ng mga template ng fingerprint na magagamit."</string> - <string name="permlab_useFingerprint" msgid="3150478619915124905">"gamitina ng hardware ng fingerprint"</string> + <string name="permlab_useFingerprint" msgid="3150478619915124905">"gamitin ang hardware ng fingerprint"</string> <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Pinapayagan ang app na gumamit ng hardware ng fingerprint para sa pagpapatotoo"</string> <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Hindi buo ang natukoy na fingerprint. Pakisubukang muli."</string> <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Hindi maproseso ang fingerprint. Pakisubukang muli."</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Hanggang <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Hanggang sa i-off mo ito"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"I-collapse"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Huwag istorbohin"</string> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index 9ec87bb..6a4b5f0 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Şu saate kadar: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Siz bunu kapatana kadar"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Daralt"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Rahatsız etmeyin"</string> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index 69f99ee..f14d62d 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -223,7 +223,7 @@ <string name="android_system_label" msgid="6577375335728551336">"Система Android"</string> <string name="user_owner_label" msgid="6465364741001216388">"Особисті додатки"</string> <string name="managed_profile_label" msgid="6260850669674791528">"Службовий профіль"</string> - <string name="permgrouplab_contacts" msgid="3657758145679177612">"Контактні дані"</string> + <string name="permgrouplab_contacts" msgid="3657758145679177612">"Контакти"</string> <string name="permgroupdesc_contacts" msgid="6951499528303668046">"отримувати доступ до контактів"</string> <string name="permgrouplab_location" msgid="7275582855722310164">"Геодані"</string> <string name="permgroupdesc_location" msgid="536889867433972794">"використовувати геодані"</string> @@ -259,7 +259,7 @@ <string name="permdesc_statusBarService" msgid="716113660795976060">"Дозволяє програмі бути рядком стану."</string> <string name="permlab_expandStatusBar" msgid="1148198785937489264">"розгорнути/згорн. рядок стану"</string> <string name="permdesc_expandStatusBar" msgid="6917549437129401132">"Дозволяє програмі розгортати чи згортати рядок стану."</string> - <string name="permlab_install_shortcut" msgid="4279070216371564234">"установлювати ярлики"</string> + <string name="permlab_install_shortcut" msgid="4279070216371564234">"створення ярликів"</string> <string name="permdesc_install_shortcut" msgid="8341295916286736996">"Дозволяє програмі самостійно додавати ярлики на головний екран."</string> <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"видаляти ярлики"</string> <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Дозволяє програмі самостійно вилучати ярлики з головного екрана."</string> @@ -293,7 +293,7 @@ <string name="permdesc_enableCarMode" msgid="4853187425751419467">"Дозволяє програмі вмикати режим автомобіля."</string> <string name="permlab_killBackgroundProcesses" msgid="3914026687420177202">"закривати інші програми"</string> <string name="permdesc_killBackgroundProcesses" msgid="4593353235959733119">"Дозволяє програмі припиняти фонові процеси інших програм. Це може зупиняти запущені програми."</string> - <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"відображатися над іншими програмами"</string> + <string name="permlab_systemAlertWindow" msgid="3543347980839518613">"відображення поверх інших вікон"</string> <string name="permdesc_systemAlertWindow" msgid="8584678381972820118">"Дозволяє програмі відображатися поверх інших програм або частин інтерфейсу користувача. Це може заважати користуватися інтерфейсом інших програм або змінювати те, що ви бачите в інших програмах."</string> <string name="permlab_persistentActivity" msgid="8841113627955563938">"заставляти програму постійно функціонувати"</string> <string name="permdesc_persistentActivity" product="tablet" msgid="8525189272329086137">"Дозволяє програмі робити свої частини сталими в пам’яті. Це може зменшувати обсяг пам’яті, доступної для інших програм, і сповільнювати роботу планшетного ПК."</string> @@ -411,7 +411,7 @@ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"Дозволяє програмі отримувати пакети, надіслані за допомогою групової адресації на всі пристрої в мережі Wi-Fi, а не лише на ваш планшетний ПК. Використовує більше заряду, ніж режим небагатоадресних пакетів."</string> <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Додаток може отримувати пакети, надіслані за допомогою групової адресації на всі пристрої в мережі Wi-Fi, а не лише на ваш телевізор. Використовує більше живлення, ніж режим небагатоадресних пакетів."</string> <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"Дозволяє програмі отримувати пакети, надіслані за допомогою групової адресації на всі пристрої в мережі Wi-Fi, а не лише на ваш телефон. Використовує більше заряду, ніж режим небагатоадресних пакетів."</string> - <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"отримувати доступ до налаштувань Bluetooth"</string> + <string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"доступ до налаштувань Bluetooth"</string> <string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"Дозволяє програмі налаштовувати планшетний ПК із локальним Bluetooth, а також знаходити віддалені пристрої та створювати з ними пару."</string> <string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"Додаток може налаштовувати локальний телевізор із Bluetooth, а також знаходити віддалені пристрої та під’єднуватися до них."</string> <string name="permdesc_bluetoothAdmin" product="default" msgid="8931682159331542137">"Дозволяє програмі налаштовувати телефон із локальним Bluetooth, а також знаходити віддалені пристрої та створювати з ними пару."</string> @@ -421,7 +421,7 @@ <string name="permdesc_changeWimaxState" product="tablet" msgid="3156456504084201805">"Дозволяє програмі під’єднувати планшетний ПК до мереж WiMAX і від’єднувати його від них."</string> <string name="permdesc_changeWimaxState" product="tv" msgid="6022307083934827718">"Додаток може під’єднувати телевізор до мереж WiMAX і від’єднувати його від них."</string> <string name="permdesc_changeWimaxState" product="default" msgid="697025043004923798">"Дозволяє програмі під’єднувати телефон до мереж WiMAX і від’єднувати його від них."</string> - <string name="permlab_bluetooth" msgid="6127769336339276828">"створювати пару з пристроями Bluetooth"</string> + <string name="permlab_bluetooth" msgid="6127769336339276828">"створення пари з пристроями Bluetooth"</string> <string name="permdesc_bluetooth" product="tablet" msgid="3480722181852438628">"Дозволяє програмі переглядати конфігурацію Bluetooth на планшетному ПК, а також створювати та приймати з’єднання зі спареними пристроями."</string> <string name="permdesc_bluetooth" product="tv" msgid="3974124940101104206">"Додаток може переглядати конфігурацію Bluetooth на телевізорі, а також створювати та приймати з’єднання з під’єднаними пристроями."</string> <string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"Дозволяє програмі переглядати конфігурацію Bluetooth на телефоні, а також створювати та приймати з’єднання зі спареними пристроями."</string> @@ -431,7 +431,7 @@ <string name="permdesc_disableKeyguard" msgid="6034203065077122992">"Дозволяє програмі вимикати блокування клавіатури та будь-який пов’язаний паролем захист. Наприклад: телефон вимикає блокування клавіатури під час отримання вхідного дзвінка, після закінчення якого блокування клавіатури відновлюється."</string> <string name="permlab_manageFingerprint" msgid="5640858826254575638">"керувати апаратним забезпеченням для цифрових відбитків"</string> <string name="permdesc_manageFingerprint" msgid="178208705828055464">"Увімкнути в додатку функції для додавання й видалення шаблонів цифрових відбитків."</string> - <string name="permlab_useFingerprint" msgid="3150478619915124905">"користуватися апаратним забезпеченням для цифрових відбитків"</string> + <string name="permlab_useFingerprint" msgid="3150478619915124905">"використання сканера цифрових відбитків"</string> <string name="permdesc_useFingerprint" msgid="9165097460730684114">"Дозволити додатку використовувати апаратне забезпечення для автентифікації"</string> <string name="fingerprint_acquired_partial" msgid="735082772341716043">"Відбиток розпізнано частково. Повторіть спробу."</string> <string name="fingerprint_acquired_insufficient" msgid="4596546021310923214">"Не вдалось обробити відбиток. Повторіть спробу."</string> @@ -455,7 +455,7 @@ <string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Дозволяє програмі змінювати налаштування синхронізації для облікового запису, наприклад, вмикати синхронізацію програми Люди з обліковим записом."</string> <string name="permlab_readSyncStats" msgid="7396577451360202448">"Перегляд статистики синхронізації"</string> <string name="permdesc_readSyncStats" msgid="1510143761757606156">"Дозволяє програмі читати статистику синхронізації облікового запису, зокрема історію синхронізацій і обсяг синхронізованих даних."</string> - <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"запис. підписані канали"</string> + <string name="permlab_subscribedFeedsWrite" msgid="9015246325408209296">"змінення даних про канали користувача"</string> <string name="permdesc_subscribedFeedsWrite" msgid="6928930188826089413">"Дозволяє програмі змінювати поточно синхронізовані канали. Шкідливі програми можуть змінювати ваші синхронізовані канали."</string> <string name="permlab_readDictionary" msgid="4107101525746035718">"читати додані в словник терміни"</string> <string name="permdesc_readDictionary" msgid="659614600338904243">"Дозволяє програмі читати всі слова, назви та фрази, які користувач міг зберегти у своєму словнику."</string> @@ -1540,6 +1540,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"До <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Доки ви не вимкнете"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Згорнути"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Не турбувати"</string> diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml index 2ac6433..654f219c 100644 --- a/core/res/res/values-ur-rPK/strings.xml +++ b/core/res/res/values-ur-rPK/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"<xliff:g id="FORMATTEDTIME">%1$s</xliff:g> تک"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"جب تک آپ اسے آف نہ کر دیں"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"سکیڑیں"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"ڈسٹرب نہ کریں"</string> diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml index 2ab2dde..04ce3d6 100644 --- a/core/res/res/values-uz-rUZ/strings.xml +++ b/core/res/res/values-uz-rUZ/strings.xml @@ -72,7 +72,7 @@ <string name="ColpMmi" msgid="3065121483740183974">"Qo‘ng‘iroq qiluvchining raqami"</string> <string name="ColrMmi" msgid="4996540314421889589">"Qo‘ng‘iroq qiluvchining raqamini cheklash"</string> <string name="CfMmi" msgid="5123218989141573515">"Boshqa raqamga yo‘naltirish"</string> - <string name="CwMmi" msgid="9129678056795016867">"Kutayotgan qo‘ng‘iroq"</string> + <string name="CwMmi" msgid="9129678056795016867">"Qo‘ng‘iroqni kutish"</string> <string name="BaMmi" msgid="455193067926770581">"Qo‘ng‘iroqlarni taqiqlash"</string> <string name="PwdMmi" msgid="7043715687905254199">"Parolni o‘zgartirish"</string> <string name="PinMmi" msgid="3113117780361190304">"PIN kodni o‘zgartirish"</string> @@ -1062,7 +1062,7 @@ <string name="extmedia_format_message" product="default" msgid="14131895027543830">"Kartadagi barcha ma`lumotlar o‘chirib tashlanadi."</string> <string name="extmedia_format_button_format" msgid="4131064560127478695">"Format"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB orqali nosozlikni tuzatish"</string> - <string name="adb_active_notification_message" msgid="1016654627626476142">"USB orqali sozlashni o‘chirib qo‘yish uchun bosing."</string> + <string name="adb_active_notification_message" msgid="1016654627626476142">"O‘chirib qo‘yish uchun bosing"</string> <string name="select_input_method" msgid="8547250819326693584">"Klaviaturani o‘zgartirish"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Klaviaturani tanlash"</string> <string name="show_ime" msgid="9157568568695230830">"Kiritish usulini ko‘rish"</string> @@ -1075,7 +1075,7 @@ <string name="ext_media_checking_notification_title" msgid="5734005953288045806">"<xliff:g id="NAME">%s</xliff:g> tayyorlanmoqda"</string> <string name="ext_media_checking_notification_message" msgid="4747432538578886744">"Xatolar tekshirilmoqda"</string> <string name="ext_media_new_notification_message" msgid="7589986898808506239">"Yangi <xliff:g id="NAME">%s</xliff:g> kartasi aniqlandi"</string> - <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Rasm va boshqa fayllarni o‘tkazish uchun"</string> + <string name="ext_media_ready_notification_message" msgid="4083398150380114462">"Rasm va boshqa fayllarni o‘tkazish"</string> <string name="ext_media_unmountable_notification_title" msgid="4863279349863279603">"“<xliff:g id="NAME">%s</xliff:g>” kartasi shikastlangan"</string> <string name="ext_media_unmountable_notification_message" msgid="7391672496565685690">"“<xliff:g id="NAME">%s</xliff:g>” kartasi shikastlangan; qayta formatlab ko‘ring"</string> <string name="ext_media_badremoval_notification_title" msgid="3206248947375505416">"<xliff:g id="NAME">%s</xliff:g> kutilmaganda chiqarib olindi"</string> @@ -1243,7 +1243,7 @@ <string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"Mob. trafik cheg-dan oshib ketdi"</string> <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi ma’lumot cheklovdan o‘tdi"</string> <string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"Chegaradan <xliff:g id="SIZE">%s</xliff:g> oshib ketdi."</string> - <string name="data_usage_restricted_title" msgid="5965157361036321914">"Orqa fon ma’lumotlari cheklangan"</string> + <string name="data_usage_restricted_title" msgid="5965157361036321914">"Fon rejimi cheklangan"</string> <string name="data_usage_restricted_body" msgid="6741521330997452990">"Cheklovni olib tashlash…"</string> <string name="ssl_certificate" msgid="6510040486049237639">"Xavfsizlik sertifikati"</string> <string name="ssl_certificate_is_valid" msgid="6825263250774569373">"Ushbu sertifikat - to‘g‘ri."</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Ushbu vaqtgacha: <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Men o‘chirmaguncha"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Yig‘ish"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Bezovta qilinmasin"</string> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 92c1e96..2be7864 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Cho đến <xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Cho đến khi bạn tắt tính năng này"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Thu gọn"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Không làm phiền"</string> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 6e12214..a689adf 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -698,12 +698,12 @@ <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_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_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">"您已经<xliff:g id="NUMBER_0">%d</xliff:g>次输错了PIN码。\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="tv" msgid="5316664559603394684">"您已经 <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_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="tv" msgid="5316664559603394684">"您已连续 <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> <string name="lockscreen_failed_attempts_almost_at_wipe" product="tv" msgid="950408382418270260">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁电视。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,电视将恢复为出厂默认设置,所有用户数据都会丢失。"</string> <string name="lockscreen_failed_attempts_almost_at_wipe" product="default" msgid="8603565142156826565">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁手机。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,手机将恢复为出厂默认设置,所有用户数据都会丢失。"</string> @@ -1321,17 +1321,17 @@ <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">"您已经<xliff:g id="NUMBER_0">%d</xliff:g>次输错了PIN码。\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_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> <string name="kg_failed_attempts_almost_at_wipe" product="tv" msgid="5621231220154419413">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁电视。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,电视将恢复为出厂默认设置,所有用户数据都会丢失。"</string> <string name="kg_failed_attempts_almost_at_wipe" product="default" msgid="4051015943038199910">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地尝试解锁手机。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,手机将恢复为出厂默认设置,所有用户数据都会丢失。"</string> <string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"您已经<xliff:g id="NUMBER">%d</xliff:g>次错误地尝试解锁平板电脑。平板电脑现在将恢复为出厂默认设置。"</string> <string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"您已经 <xliff:g id="NUMBER">%d</xliff:g> 次错误地尝试解锁电视。电视现在将恢复为出厂默认设置。"</string> <string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"您已经<xliff:g id="NUMBER">%d</xliff:g>次错误地尝试解锁手机。手机现在将恢复为出厂默认设置。"</string> - <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string> - <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用电子邮件帐户解锁电视。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string> - <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已经 <xliff:g id="NUMBER_0">%d</xliff:g> 次错误地绘制了解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string> + <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string> + <string name="kg_failed_attempts_almost_at_login" product="tv" msgid="4224651132862313471">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用电子邮件帐户解锁电视。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string> + <string name="kg_failed_attempts_almost_at_login" product="default" msgid="1437638152015574839">"您已连续 <xliff:g id="NUMBER_0">%d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐户解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%d</xliff:g> 秒后重试。"</string> <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string> <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"删除"</string> <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"要将音量调高到推荐水平以上吗?\n\n长时间保持高音量可能会损伤听力。"</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"到<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"直到您将其关闭"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"收起"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"勿扰"</string> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index f636f0a..ef6d839 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"完成時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"直至您關閉這項設定"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"收合"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"請勿干擾"</string> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index bea0cc0..2fd95a5 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -72,7 +72,7 @@ <string name="ColpMmi" msgid="3065121483740183974">"連接的線路 ID"</string> <string name="ColrMmi" msgid="4996540314421889589">"連接的線路 ID 限制"</string> <string name="CfMmi" msgid="5123218989141573515">"來電轉接"</string> - <string name="CwMmi" msgid="9129678056795016867">"來電待接"</string> + <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> @@ -1049,7 +1049,7 @@ <string name="dlg_confirm_kill_storage_users_text" msgid="5100428757107469454">"如果您開啟 USB 儲存裝置,則某些正在使用中的應用程式會停止運作,而且可能無法使用,直到關閉 USB 儲存裝置後才會恢復正常。"</string> <string name="dlg_error_title" msgid="7323658469626514207">"USB 操作失敗"</string> <string name="dlg_ok" msgid="7376953167039865701">"確定"</string> - <string name="usb_charging_notification_title" msgid="4004114449249406402">"USB 充電"</string> + <string name="usb_charging_notification_title" msgid="4004114449249406402">"正在透過 USB 充電"</string> <string name="usb_mtp_notification_title" msgid="8396264943589760855">"USB 檔案傳輸"</string> <string name="usb_ptp_notification_title" msgid="1347328437083192112">"USB 相片傳輸"</string> <string name="usb_midi_notification_title" msgid="4850904915889144654">"USB MIDI"</string> @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"結束時間:<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"手動關閉這項設定前一律啟用"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g>/<xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"收合"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"零打擾"</string> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index e83285f..e36560a 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -1506,6 +1506,8 @@ </plurals> <string name="zen_mode_until" msgid="7336308492289875088">"Kuze kube ngu-<xliff:g id="FORMATTEDTIME">%1$s</xliff:g>"</string> <string name="zen_mode_forever" msgid="7420011936770086993">"Uze uvale lokhu"</string> + <!-- no translation found for zen_mode_forever_dnd (3792132696572189081) --> + <skip /> <string name="zen_mode_rule_name_combination" msgid="191109939968076477">"<xliff:g id="FIRST">%1$s</xliff:g> / <xliff:g id="REST">%2$s</xliff:g>"</string> <string name="toolbar_collapse_description" msgid="2821479483960330739">"Goqa"</string> <string name="zen_mode_feature_name" msgid="5254089399895895004">"Ungaphazamisi"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 3c84b5e..0310bea 100755 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -423,6 +423,9 @@ point on the move. A value of 0 means no periodic scans will be used in the framework. --> <integer translatable="false" name="config_wifi_framework_scan_interval">300000</integer> + <!-- Integer indicating the framework no networks periodic scan interval in milliseconds. --> + <integer translatable="false" name="config_wifi_no_network_periodic_scan_interval">300000</integer> + <!-- Integer indicating disconnect mode short scan interval in milliseconds --> <integer translatable="false" name="config_wifi_disconnected_short_scan_interval">15000</integer> diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml index f7a42fa..7782ed7 100644 --- a/core/res/res/values/styles_material.xml +++ b/core/res/res/values/styles_material.xml @@ -630,13 +630,13 @@ please see styles_device_defaults.xml. </style> <style name="Widget.Material.NumberPicker" parent="Widget.NumberPicker"> - <item name="internalLayout">@layout/number_picker_with_selector_wheel</item> + <item name="internalLayout">@layout/number_picker_material</item> <item name="solidColor">@color/transparent</item> - <item name="selectionDivider">@drawable/numberpicker_selection_divider</item> - <item name="selectionDividerHeight">2dip</item> - <item name="selectionDividersDistance">48dip</item> - <item name="internalMinWidth">64dip</item> - <item name="internalMaxHeight">180dip</item> + <item name="selectionDivider">@drawable/number_picker_divider_material</item> + <item name="selectionDividerHeight">2dp</item> + <item name="selectionDividersDistance">48dp</item> + <item name="internalMinWidth">64dp</item> + <item name="internalMaxHeight">180dp</item> <item name="virtualButtonPressedDrawable">?attr/selectableItemBackground</item> </style> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index acb6c6a..84f3d69 100755 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -383,6 +383,7 @@ <java-symbol type="integer" name="config_shortPressOnSleepBehavior" /> <java-symbol type="integer" name="config_wifi_framework_scan_interval" /> <java-symbol type="integer" name="config_wifi_supplicant_scan_interval" /> + <java-symbol type="integer" name="config_wifi_no_network_periodic_scan_interval" /> <java-symbol type="integer" name="config_wifi_scan_interval_p2p_connected" /> <java-symbol type="bool" name="config_wifi_hal_pno_enable" /> <java-symbol type="integer" name="config_windowOutsetBottom" /> diff --git a/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeTest.java b/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeTest.java index 323a360..8feac9b 100644 --- a/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeTest.java +++ b/core/tests/inputmethodtests/src/android/os/InputMethodSubtypeTest.java @@ -56,6 +56,10 @@ public class InputMethodSubtypeTest extends InstrumentationTestCase { verifyLocale("zz"); verifyLocale("iw"); verifyLocale("he"); + verifyLocale("tl"); + verifyLocale("tl_PH"); + verifyLocale("fil"); + verifyLocale("fil_PH"); } @SmallTest diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java index d6f8cca..7aa0aef 100644 --- a/graphics/java/android/graphics/ImageFormat.java +++ b/graphics/java/android/graphics/ImageFormat.java @@ -587,10 +587,29 @@ public class ImageFormat { public static final int RAW12 = 0x26; /** - * Android dense depth image format. - * - * Each pixel is 16 bits, representing a depth ranging measurement from - * a depth camera or similar sensor. + * <p>Android dense depth image format.</p> + * + * <p>Each pixel is 16 bits, representing a depth ranging measurement from a depth camera or + * similar sensor. The 16-bit sample consists of a confidence value and the actual ranging + * measurement.</p> + * + * <p>The confidence value is an estimate of correctness for this sample. It is encoded in the + * 3 most significant bits of the sample, with a value of 0 representing 100% confidence, a + * value of 1 representing 0% confidence, a value of 2 representing 1/7, a value of 3 + * representing 2/7, and so on.</p> + * + * <p>As an example, the following sample extracts the range and confidence from the first pixel + * of a DEPTH16-format {@link android.media.Image}, and converts the confidence to a + * floating-point value between 0 and 1.f inclusive, with 1.f representing maximum confidence: + * + * <pre> + * ShortBuffer shortDepthBuffer = img.getPlanes()[0].getBuffer().asShortBuffer(); + * short depthSample = shortDepthBuffer.get() + * short depthRange = (short) (depthSample & 0x1FFF); + * short depthConfidence = (short) ((depthSample >> 13) & 0x7); + * float depthPercentage = depthConfidence == 0 ? 1.f : (depthConfidence - 1) / 7.f; + * </pre> + * </p> * * <p>This format assumes * <ul> @@ -602,19 +621,32 @@ public class ImageFormat { * * <pre> y_size = stride * height </pre> * - * When produced by a camera, the units are millimeters. + * When produced by a camera, the units for the range are millimeters. */ public static final int DEPTH16 = 0x44363159; /** * Android sparse depth point cloud format. * - * <p>A variable-length list of 3D points, with each point represented - * by a triple of floats.</p> + * <p>A variable-length list of 3D points plus a confidence value, with each point represented + * by four floats; first the X, Y, Z position coordinates, and then the confidence value.</p> + * + * <p>The number of points is {@code (size of the buffer in bytes) / 16}. + * + * <p>The coordinate system and units of the position values depend on the source of the point + * cloud data. The confidence value is between 0.f and 1.f, inclusive, with 0 representing 0% + * confidence and 1.f representing 100% confidence in the measured position values.</p> * - * <p>The number of points is {@code (size of the buffer in bytes) / 12}. + * <p>As an example, the following code extracts the first depth point in a DEPTH_POINT_CLOUD + * format {@link android.media.Image}: + * <pre> + * FloatBuffer floatDepthBuffer = img.getPlanes()[0].getBuffer().asFloatBuffer(); + * float x = floatDepthBuffer.get(); + * float y = floatDepthBuffer.get(); + * float z = floatDepthBuffer.get(); + * float confidence = floatDepthBuffer.get(); + * </pre> * - * The coordinate system and units depend on the source of the point cloud data. */ public static final int DEPTH_POINT_CLOUD = 0x101; diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java index 03be759..aa2b946 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreBCWorkaroundProvider.java @@ -43,13 +43,17 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { private static final String PACKAGE_NAME = "android.security.keystore"; private static final String KEYSTORE_SECRET_KEY_CLASS_NAME = PACKAGE_NAME + ".AndroidKeyStoreSecretKey"; + private static final String KEYSTORE_PRIVATE_KEY_CLASS_NAME = + PACKAGE_NAME + ".AndroidKeyStorePrivateKey"; + private static final String KEYSTORE_PUBLIC_KEY_CLASS_NAME = + PACKAGE_NAME + ".AndroidKeyStorePublicKey"; AndroidKeyStoreBCWorkaroundProvider() { super("AndroidKeyStoreBCWorkaround", 1.0, "Android KeyStore security provider to work around Bouncy Castle"); - // javax.crypto.Mac + // --------------------- javax.crypto.Mac putMacImpl("HmacSHA1", PACKAGE_NAME + ".AndroidKeyStoreHmacSpi$HmacSHA1"); put("Alg.Alias.Mac.1.2.840.113549.2.7", "HmacSHA1"); put("Alg.Alias.Mac.HMAC-SHA1", "HmacSHA1"); @@ -75,7 +79,7 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { put("Alg.Alias.Mac.HMAC-SHA512", "HmacSHA512"); put("Alg.Alias.Mac.HMAC/SHA512", "HmacSHA512"); - // javax.crypto.Cipher + // --------------------- javax.crypto.Cipher putSymmetricCipherImpl("AES/ECB/NoPadding", PACKAGE_NAME + ".AndroidKeyStoreUnauthenticatedAESCipherSpi$ECB$NoPadding"); putSymmetricCipherImpl("AES/ECB/PKCS7Padding", @@ -88,6 +92,36 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { putSymmetricCipherImpl("AES/CTR/NoPadding", PACKAGE_NAME + ".AndroidKeyStoreUnauthenticatedAESCipherSpi$CTR$NoPadding"); + + putAsymmetricCipherImpl("RSA/ECB/NoPadding", + PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$NoPadding"); + put("Alg.Alias.Cipher.RSA/None/NoPadding", "RSA/ECB/NoPadding"); + putAsymmetricCipherImpl("RSA/ECB/PKCS1Padding", + PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$PKCS1Padding"); + put("Alg.Alias.Cipher.RSA/None/PKCS1Padding", "RSA/ECB/PKCS1Padding"); + putAsymmetricCipherImpl("RSA/ECB/OAEPPadding", + PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA1AndMGF1Padding"); + put("Alg.Alias.Cipher.RSA/None/OAEPPadding", "RSA/ECB/OAEPPadding"); + putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-1AndMGF1Padding", + PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA1AndMGF1Padding"); + put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-1AndMGF1Padding", + "RSA/ECB/OAEPWithSHA-1AndMGF1Padding"); + putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-224AndMGF1Padding", + PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA224AndMGF1Padding"); + put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-224AndMGF1Padding", + "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); + putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-256AndMGF1Padding", + PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA256AndMGF1Padding"); + put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-256AndMGF1Padding", + "RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); + putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-384AndMGF1Padding", + PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA384AndMGF1Padding"); + put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-384AndMGF1Padding", + "RSA/ECB/OAEPWithSHA-384AndMGF1Padding"); + putAsymmetricCipherImpl("RSA/ECB/OAEPWithSHA-512AndMGF1Padding", + PACKAGE_NAME + ".AndroidKeyStoreRSACipherSpi$OAEPWithSHA512AndMGF1Padding"); + put("Alg.Alias.Cipher.RSA/None/OAEPWithSHA-512AndMGF1Padding", + "RSA/ECB/OAEPWithSHA-512AndMGF1Padding"); } private void putMacImpl(String algorithm, String implClass) { @@ -99,4 +133,10 @@ class AndroidKeyStoreBCWorkaroundProvider extends Provider { put("Cipher." + transformation, implClass); put("Cipher." + transformation + " SupportedKeyClasses", KEYSTORE_SECRET_KEY_CLASS_NAME); } + + private void putAsymmetricCipherImpl(String transformation, String implClass) { + put("Cipher." + transformation, implClass); + put("Cipher." + transformation + " SupportedKeyClasses", + KEYSTORE_PRIVATE_KEY_CLASS_NAME + "|" + KEYSTORE_PUBLIC_KEY_CLASS_NAME); + } } diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java b/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java index 3ad3c9d..fd9bdb8 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreCipherSpiBase.java @@ -66,7 +66,7 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor */ private IBinder mOperationToken; private long mOperationHandle; - private KeyStoreCryptoOperationChunkedStreamer mMainDataStreamer; + private KeyStoreCryptoOperationStreamer mMainDataStreamer; /** * Encountered exception which could not be immediately thrown because it was encountered inside @@ -210,7 +210,6 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor byte[] additionalEntropy = KeyStoreCryptoOperationUtils.getRandomBytesToMixIntoKeystoreRng( mRng, getAdditionalEntropyAmountForBegin()); - KeymasterArguments keymasterOutputArgs = new KeymasterArguments(); OperationResult opResult = mKeyStore.begin( mKey.getAlias(), mEncrypting ? KeymasterDefs.KM_PURPOSE_ENCRYPT : KeymasterDefs.KM_PURPOSE_DECRYPT, @@ -247,9 +246,21 @@ abstract class AndroidKeyStoreCipherSpiBase extends CipherSpi implements KeyStor } loadAlgorithmSpecificParametersFromBeginResult(opResult.outParams); - mMainDataStreamer = new KeyStoreCryptoOperationChunkedStreamer( + mMainDataStreamer = createMainDataStreamer(mKeyStore, opResult.token); + } + + /** + * Creates a streamer which sends plaintext/ciphertext into the provided KeyStore and receives + * the corresponding ciphertext/plaintext from the KeyStore. + * + * <p>This implementation returns a working streamer. + */ + @NonNull + protected KeyStoreCryptoOperationStreamer createMainDataStreamer( + KeyStore keyStore, IBinder operationToken) { + return new KeyStoreCryptoOperationChunkedStreamer( new KeyStoreCryptoOperationChunkedStreamer.MainDataStream( - mKeyStore, opResult.token)); + keyStore, operationToken)); } @Override diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreKey.java b/keystore/java/android/security/keystore/AndroidKeyStoreKey.java index 6098e5c..1751aa5 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreKey.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreKey.java @@ -19,7 +19,7 @@ package android.security.keystore; import java.security.Key; /** - * {@link Key} backed by AndroidKeyStore. + * {@link Key} backed by Android Keystore. * * @hide */ diff --git a/keystore/java/android/security/keystore/AndroidKeyStorePrivateKey.java b/keystore/java/android/security/keystore/AndroidKeyStorePrivateKey.java new file mode 100644 index 0000000..b586ad4 --- /dev/null +++ b/keystore/java/android/security/keystore/AndroidKeyStorePrivateKey.java @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2015 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.security.keystore; + +import java.security.PrivateKey; + +/** + * {@link PrivateKey} backed by Android Keystore. + * + * @hide + */ +public class AndroidKeyStorePrivateKey extends AndroidKeyStoreKey implements PrivateKey { + + public AndroidKeyStorePrivateKey(String alias, String algorithm) { + super(alias, algorithm); + } +} diff --git a/keystore/java/android/security/keystore/AndroidKeyStorePublicKey.java b/keystore/java/android/security/keystore/AndroidKeyStorePublicKey.java new file mode 100644 index 0000000..8133d46 --- /dev/null +++ b/keystore/java/android/security/keystore/AndroidKeyStorePublicKey.java @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2015 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.security.keystore; + +import java.security.PublicKey; + +/** + * {@link PublicKey} backed by Android Keystore. + * + * @hide + */ +public class AndroidKeyStorePublicKey extends AndroidKeyStoreKey implements PublicKey { + + private final byte[] mEncoded; + + public AndroidKeyStorePublicKey(String alias, String algorithm, byte[] x509EncodedForm) { + super(alias, algorithm); + mEncoded = ArrayUtils.cloneIfNotEmpty(x509EncodedForm); + } + + @Override + public String getFormat() { + return "X.509"; + } + + @Override + public byte[] getEncoded() { + return ArrayUtils.cloneIfNotEmpty(mEncoded); + } +} diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java b/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java new file mode 100644 index 0000000..f70c323 --- /dev/null +++ b/keystore/java/android/security/keystore/AndroidKeyStoreRSACipherSpi.java @@ -0,0 +1,487 @@ +/* + * Copyright (C) 2015 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.security.keystore; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.os.IBinder; +import android.security.KeyStore; +import android.security.KeyStoreException; +import android.security.keymaster.KeyCharacteristics; +import android.security.keymaster.KeymasterArguments; +import android.security.keymaster.KeymasterDefs; + +import libcore.util.EmptyArray; + +import java.io.ByteArrayOutputStream; +import java.security.AlgorithmParameters; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidKeyException; +import java.security.Key; +import java.security.NoSuchAlgorithmException; +import java.security.PrivateKey; +import java.security.ProviderException; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidParameterSpecException; +import java.security.spec.MGF1ParameterSpec; + +import javax.crypto.Cipher; +import javax.crypto.CipherSpi; +import javax.crypto.spec.OAEPParameterSpec; +import javax.crypto.spec.PSource; + +/** + * Base class for {@link CipherSpi} providing Android KeyStore backed RSA encryption/decryption. + * + * @hide + */ +abstract class AndroidKeyStoreRSACipherSpi extends AndroidKeyStoreCipherSpiBase { + + /** + * Raw RSA cipher without any padding. + */ + public static final class NoPadding extends AndroidKeyStoreRSACipherSpi { + public NoPadding() { + super(KeymasterDefs.KM_PAD_NONE); + } + + @Override + protected void initAlgorithmSpecificParameters() throws InvalidKeyException {} + + @Override + protected void initAlgorithmSpecificParameters(@Nullable AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException { + if (params != null) { + throw new InvalidAlgorithmParameterException( + "Unexpected parameters: " + params + ". No parameters supported"); + } + } + + @Override + protected void initAlgorithmSpecificParameters(@Nullable AlgorithmParameters params) + throws InvalidAlgorithmParameterException { + + if (params != null) { + throw new InvalidAlgorithmParameterException( + "Unexpected parameters: " + params + ". No parameters supported"); + } + } + + @Override + protected AlgorithmParameters engineGetParameters() { + return null; + } + + @Override + protected final int getAdditionalEntropyAmountForBegin() { + return 0; + } + + @Override + @NonNull + protected KeyStoreCryptoOperationStreamer createMainDataStreamer( + KeyStore keyStore, IBinder operationToken) { + if (isEncrypting()) { + // KeyStore's RSA encryption without padding expects the input to be of the same + // length as the modulus. We thus have to buffer all input to pad it with leading + // zeros. + return new ZeroPaddingEncryptionStreamer( + super.createMainDataStreamer(keyStore, operationToken), + getModulusSizeBytes()); + } else { + return super.createMainDataStreamer(keyStore, operationToken); + } + } + + /** + * Streamer which buffers all plaintext input, then pads it with leading zeros to match + * modulus size, and then sends it into KeyStore to obtain ciphertext. + */ + private static class ZeroPaddingEncryptionStreamer + implements KeyStoreCryptoOperationStreamer { + + private final KeyStoreCryptoOperationStreamer mDelegate; + private final int mModulusSizeBytes; + private final ByteArrayOutputStream mInputBuffer = new ByteArrayOutputStream(); + + private ZeroPaddingEncryptionStreamer( + KeyStoreCryptoOperationStreamer delegate, + int modulusSizeBytes) { + mDelegate = delegate; + mModulusSizeBytes = modulusSizeBytes; + } + + @Override + public byte[] update(byte[] input, int inputOffset, int inputLength) + throws KeyStoreException { + if (inputLength > 0) { + mInputBuffer.write(input, inputOffset, inputLength); + } + return EmptyArray.BYTE; + } + + @Override + public byte[] doFinal(byte[] input, int inputOffset, int inputLength) + throws KeyStoreException { + if (inputLength > 0) { + mInputBuffer.write(input, inputOffset, inputLength); + } + byte[] bufferedInput = mInputBuffer.toByteArray(); + mInputBuffer.reset(); + byte[] paddedInput; + if (bufferedInput.length < mModulusSizeBytes) { + // Pad input with leading zeros + paddedInput = new byte[mModulusSizeBytes]; + System.arraycopy( + bufferedInput, 0, + paddedInput, + paddedInput.length - bufferedInput.length, + bufferedInput.length); + } else { + // No need to pad input + paddedInput = bufferedInput; + } + return mDelegate.doFinal(paddedInput, 0, paddedInput.length); + } + } + } + + /** + * RSA cipher with PKCS#1 v1.5 encryption padding. + */ + public static final class PKCS1Padding extends AndroidKeyStoreRSACipherSpi { + public PKCS1Padding() { + super(KeymasterDefs.KM_PAD_RSA_PKCS1_1_5_ENCRYPT); + } + + @Override + protected void initAlgorithmSpecificParameters() throws InvalidKeyException {} + + @Override + protected void initAlgorithmSpecificParameters(@Nullable AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException { + if (params != null) { + throw new InvalidAlgorithmParameterException( + "Unexpected parameters: " + params + ". No parameters supported"); + } + } + + @Override + protected void initAlgorithmSpecificParameters(@Nullable AlgorithmParameters params) + throws InvalidAlgorithmParameterException { + + if (params != null) { + throw new InvalidAlgorithmParameterException( + "Unexpected parameters: " + params + ". No parameters supported"); + } + } + + @Override + protected AlgorithmParameters engineGetParameters() { + return null; + } + + @Override + protected final int getAdditionalEntropyAmountForBegin() { + return (isEncrypting()) ? getModulusSizeBytes() : 0; + } + } + + /** + * RSA cipher with OAEP encryption padding. Only SHA-1 based MGF1 is supported as MGF. + */ + abstract static class OAEPWithMGF1Padding extends AndroidKeyStoreRSACipherSpi { + + private static final String MGF_ALGORITGM_MGF1 = "MGF1"; + + private int mKeymasterDigest = -1; + private int mDigestOutputSizeBytes; + + OAEPWithMGF1Padding(int keymasterDigest) { + super(KeymasterDefs.KM_PAD_RSA_OAEP); + mKeymasterDigest = keymasterDigest; + mDigestOutputSizeBytes = + (KeymasterUtils.getDigestOutputSizeBits(keymasterDigest) + 7) / 8; + } + + @Override + protected final void initAlgorithmSpecificParameters() throws InvalidKeyException {} + + @Override + protected final void initAlgorithmSpecificParameters( + @Nullable AlgorithmParameterSpec params) throws InvalidAlgorithmParameterException { + if (params == null) { + return; + } + + if (!(params instanceof OAEPParameterSpec)) { + throw new InvalidAlgorithmParameterException( + "Unsupported parameter spec: " + params + + ". Only OAEPParameterSpec supported"); + } + OAEPParameterSpec spec = (OAEPParameterSpec) params; + if (!MGF_ALGORITGM_MGF1.equalsIgnoreCase(spec.getMGFAlgorithm())) { + throw new InvalidAlgorithmParameterException( + "Unsupported MGF: " + spec.getMGFAlgorithm() + + ". Only " + MGF_ALGORITGM_MGF1 + " supported"); + } + String jcaDigest = spec.getDigestAlgorithm(); + int keymasterDigest; + try { + keymasterDigest = KeyProperties.Digest.toKeymaster(jcaDigest); + } catch (IllegalArgumentException e) { + throw new InvalidAlgorithmParameterException( + "Unsupported digest: " + jcaDigest, e); + } + switch (keymasterDigest) { + case KeymasterDefs.KM_DIGEST_SHA1: + case KeymasterDefs.KM_DIGEST_SHA_2_224: + case KeymasterDefs.KM_DIGEST_SHA_2_256: + case KeymasterDefs.KM_DIGEST_SHA_2_384: + case KeymasterDefs.KM_DIGEST_SHA_2_512: + // Permitted. + break; + default: + throw new InvalidAlgorithmParameterException( + "Unsupported digest: " + jcaDigest); + } + AlgorithmParameterSpec mgfParams = spec.getMGFParameters(); + if (mgfParams == null) { + throw new InvalidAlgorithmParameterException("MGF parameters must be provided"); + } + // Check whether MGF parameters match the OAEPParameterSpec + if (!(mgfParams instanceof MGF1ParameterSpec)) { + throw new InvalidAlgorithmParameterException("Unsupported MGF parameters" + + ": " + mgfParams + ". Only MGF1ParameterSpec supported"); + } + MGF1ParameterSpec mgfSpec = (MGF1ParameterSpec) mgfParams; + String mgf1JcaDigest = mgfSpec.getDigestAlgorithm(); + if (!KeyProperties.DIGEST_SHA1.equalsIgnoreCase(mgf1JcaDigest)) { + throw new InvalidAlgorithmParameterException( + "Unsupported MGF1 digest: " + mgf1JcaDigest + + ". Only " + KeyProperties.DIGEST_SHA1 + " supported"); + } + PSource pSource = spec.getPSource(); + if (!(pSource instanceof PSource.PSpecified)) { + throw new InvalidAlgorithmParameterException( + "Unsupported source of encoding input P: " + pSource + + ". Only pSpecifiedEmpty (PSource.PSpecified.DEFAULT) supported"); + } + PSource.PSpecified pSourceSpecified = (PSource.PSpecified) pSource; + byte[] pSourceValue = pSourceSpecified.getValue(); + if ((pSourceValue != null) && (pSourceValue.length > 0)) { + throw new InvalidAlgorithmParameterException( + "Unsupported source of encoding input P: " + pSource + + ". Only pSpecifiedEmpty (PSource.PSpecified.DEFAULT) supported"); + } + mKeymasterDigest = keymasterDigest; + mDigestOutputSizeBytes = + (KeymasterUtils.getDigestOutputSizeBits(keymasterDigest) + 7) / 8; + } + + @Override + protected final void initAlgorithmSpecificParameters(@Nullable AlgorithmParameters params) + throws InvalidAlgorithmParameterException { + if (params == null) { + return; + } + + OAEPParameterSpec spec; + try { + spec = params.getParameterSpec(OAEPParameterSpec.class); + } catch (InvalidParameterSpecException e) { + throw new InvalidAlgorithmParameterException("OAEP parameters required" + + ", but not found in parameters: " + params, e); + } + if (spec == null) { + throw new InvalidAlgorithmParameterException("OAEP parameters required" + + ", but not provided in parameters: " + params); + } + initAlgorithmSpecificParameters(spec); + } + + @Override + protected final AlgorithmParameters engineGetParameters() { + OAEPParameterSpec spec = + new OAEPParameterSpec( + KeyProperties.Digest.fromKeymaster(mKeymasterDigest), + MGF_ALGORITGM_MGF1, + MGF1ParameterSpec.SHA1, + PSource.PSpecified.DEFAULT); + try { + AlgorithmParameters params = AlgorithmParameters.getInstance("OAEP"); + params.init(spec); + return params; + } catch (NoSuchAlgorithmException e) { + throw new ProviderException( + "Failed to obtain OAEP AlgorithmParameters", e); + } catch (InvalidParameterSpecException e) { + throw new ProviderException( + "Failed to initialize OAEP AlgorithmParameters with an IV", + e); + } + } + + @Override + protected final void addAlgorithmSpecificParametersToBegin( + KeymasterArguments keymasterArgs) { + super.addAlgorithmSpecificParametersToBegin(keymasterArgs); + keymasterArgs.addInt(KeymasterDefs.KM_TAG_DIGEST, mKeymasterDigest); + } + + @Override + protected final void loadAlgorithmSpecificParametersFromBeginResult( + @NonNull KeymasterArguments keymasterArgs) { + super.loadAlgorithmSpecificParametersFromBeginResult(keymasterArgs); + } + + @Override + protected final int getAdditionalEntropyAmountForBegin() { + return (isEncrypting()) ? mDigestOutputSizeBytes : 0; + } + } + + public static class OAEPWithSHA1AndMGF1Padding extends OAEPWithMGF1Padding { + public OAEPWithSHA1AndMGF1Padding() { + super(KeymasterDefs.KM_DIGEST_SHA1); + } + } + + public static class OAEPWithSHA224AndMGF1Padding extends OAEPWithMGF1Padding { + public OAEPWithSHA224AndMGF1Padding() { + super(KeymasterDefs.KM_DIGEST_SHA_2_224); + } + } + + public static class OAEPWithSHA256AndMGF1Padding extends OAEPWithMGF1Padding { + public OAEPWithSHA256AndMGF1Padding() { + super(KeymasterDefs.KM_DIGEST_SHA_2_256); + } + } + + public static class OAEPWithSHA384AndMGF1Padding extends OAEPWithMGF1Padding { + public OAEPWithSHA384AndMGF1Padding() { + super(KeymasterDefs.KM_DIGEST_SHA_2_384); + } + } + + public static class OAEPWithSHA512AndMGF1Padding extends OAEPWithMGF1Padding { + public OAEPWithSHA512AndMGF1Padding() { + super(KeymasterDefs.KM_DIGEST_SHA_2_512); + } + } + + private final int mKeymasterPadding; + + private int mModulusSizeBytes = -1; + + AndroidKeyStoreRSACipherSpi(int keymasterPadding) { + mKeymasterPadding = keymasterPadding; + } + + @Override + protected final void initKey(int opmode, Key key) throws InvalidKeyException { + if (key == null) { + throw new InvalidKeyException("Unsupported key: null"); + } + if (!KeyProperties.KEY_ALGORITHM_RSA.equalsIgnoreCase(key.getAlgorithm())) { + throw new InvalidKeyException("Unsupported key algorithm: " + key.getAlgorithm() + + ". Only " + KeyProperties.KEY_ALGORITHM_RSA + " supported"); + } + AndroidKeyStoreKey keystoreKey; + if (key instanceof AndroidKeyStorePrivateKey) { + keystoreKey = (AndroidKeyStoreKey) key; + } else if (key instanceof AndroidKeyStorePublicKey) { + keystoreKey = (AndroidKeyStoreKey) key; + } else { + throw new InvalidKeyException("Unsupported key type: " + key); + } + + if (keystoreKey instanceof PrivateKey) { + if ((opmode != Cipher.DECRYPT_MODE) && (opmode != Cipher.UNWRAP_MODE)) { + throw new InvalidKeyException("Private key cannot be used with opmode: " + opmode + + ". Only DECRYPT_MODE and UNWRAP_MODE supported"); + } + } else { + if ((opmode != Cipher.ENCRYPT_MODE) && (opmode != Cipher.WRAP_MODE)) { + throw new InvalidKeyException("Public key cannot be used with opmode: " + opmode + + ". Only ENCRYPT_MODE and WRAP_MODE supported"); + } + } + + KeyCharacteristics keyCharacteristics = new KeyCharacteristics(); + int errorCode = getKeyStore().getKeyCharacteristics( + keystoreKey.getAlias(), null, null, keyCharacteristics); + if (errorCode != KeyStore.NO_ERROR) { + throw getKeyStore().getInvalidKeyException(keystoreKey.getAlias(), errorCode); + } + int keySizeBits = keyCharacteristics.getInt(KeymasterDefs.KM_TAG_KEY_SIZE, -1); + if (keySizeBits == -1) { + throw new InvalidKeyException("Size of key not known"); + } + mModulusSizeBytes = (keySizeBits + 7) / 8; + + setKey(keystoreKey); + } + + @Override + protected final void resetAll() { + mModulusSizeBytes = -1; + super.resetAll(); + } + + @Override + protected final void resetWhilePreservingInitState() { + super.resetWhilePreservingInitState(); + } + + @Override + protected void addAlgorithmSpecificParametersToBegin( + @NonNull KeymasterArguments keymasterArgs) { + keymasterArgs.addInt(KeymasterDefs.KM_TAG_ALGORITHM, KeymasterDefs.KM_ALGORITHM_RSA); + keymasterArgs.addInt(KeymasterDefs.KM_TAG_PADDING, mKeymasterPadding); + } + + @Override + protected void loadAlgorithmSpecificParametersFromBeginResult( + @NonNull KeymasterArguments keymasterArgs) { + } + + @Override + protected final int engineGetBlockSize() { + // Not a block cipher, according to the RI + return 0; + } + + @Override + protected final byte[] engineGetIV() { + // IV never used + return null; + } + + @Override + protected final int engineGetOutputSize(int inputLen) { + return getModulusSizeBytes(); + } + + protected final int getModulusSizeBytes() { + if (mModulusSizeBytes == -1) { + throw new IllegalStateException("Not initialized"); + } + return mModulusSizeBytes; + } +} diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreRSAPublicKey.java b/keystore/java/android/security/keystore/AndroidKeyStoreRSAPublicKey.java new file mode 100644 index 0000000..36bc997 --- /dev/null +++ b/keystore/java/android/security/keystore/AndroidKeyStoreRSAPublicKey.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2015 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.security.keystore; + +import java.math.BigInteger; +import java.security.interfaces.RSAPublicKey; + +/** + * {@link RSAPublicKey} backed by Android Keystore. + * + * @hide + */ +public class AndroidKeyStoreRSAPublicKey extends AndroidKeyStorePublicKey implements RSAPublicKey { + private final BigInteger mModulus; + private final BigInteger mPublicExponent; + + public AndroidKeyStoreRSAPublicKey(String alias, byte[] x509EncodedForm, BigInteger modulus, + BigInteger publicExponent) { + super(alias, "RSA", x509EncodedForm); + mModulus = modulus; + mPublicExponent = publicExponent; + } + + public AndroidKeyStoreRSAPublicKey(String alias, RSAPublicKey info) { + this(alias, info.getEncoded(), info.getModulus(), info.getPublicExponent()); + if (!"X.509".equalsIgnoreCase(info.getFormat())) { + throw new IllegalArgumentException( + "Unsupported key export format: " + info.getFormat()); + } + } + + @Override + public BigInteger getModulus() { + return mModulus; + } + + @Override + public BigInteger getPublicExponent() { + return mPublicExponent; + } +} diff --git a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKey.java b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKey.java index f75516b..af354ab 100644 --- a/keystore/java/android/security/keystore/AndroidKeyStoreSecretKey.java +++ b/keystore/java/android/security/keystore/AndroidKeyStoreSecretKey.java @@ -19,7 +19,7 @@ package android.security.keystore; import javax.crypto.SecretKey; /** - * {@link SecretKey} backed by keystore. + * {@link SecretKey} backed by Android Keystore. * * @hide */ diff --git a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java index 7d57e5f..47b4996 100644 --- a/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java +++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationChunkedStreamer.java @@ -44,12 +44,12 @@ import java.io.IOException; * * @hide */ -public class KeyStoreCryptoOperationChunkedStreamer { +class KeyStoreCryptoOperationChunkedStreamer implements KeyStoreCryptoOperationStreamer { /** * Bidirectional chunked data stream over a KeyStore crypto operation. */ - public interface Stream { + interface Stream { /** * Returns the result of the KeyStore {@code update} operation or null if keystore couldn't * be reached. @@ -66,12 +66,11 @@ public class KeyStoreCryptoOperationChunkedStreamer { // Binder buffer is about 1MB, but it's shared between all active transactions of the process. // Thus, it's safer to use a much smaller upper bound. private static final int DEFAULT_MAX_CHUNK_SIZE = 64 * 1024; - private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; private final Stream mKeyStoreStream; private final int mMaxChunkSize; - private byte[] mBuffered = EMPTY_BYTE_ARRAY; + private byte[] mBuffered = EmptyArray.BYTE; private int mBufferedOffset; private int mBufferedLength; @@ -84,10 +83,11 @@ public class KeyStoreCryptoOperationChunkedStreamer { mMaxChunkSize = maxChunkSize; } + @Override public byte[] update(byte[] input, int inputOffset, int inputLength) throws KeyStoreException { if (inputLength == 0) { // No input provided - return EMPTY_BYTE_ARRAY; + return EmptyArray.BYTE; } ByteArrayOutputStream bufferedOutput = null; @@ -129,7 +129,7 @@ public class KeyStoreCryptoOperationChunkedStreamer { if (opResult.inputConsumed == chunk.length) { // The whole chunk was consumed - mBuffered = EMPTY_BYTE_ARRAY; + mBuffered = EmptyArray.BYTE; mBufferedOffset = 0; mBufferedLength = 0; } else if (opResult.inputConsumed == 0) { @@ -185,17 +185,18 @@ public class KeyStoreCryptoOperationChunkedStreamer { if (bufferedOutput == null) { // No output produced - return EMPTY_BYTE_ARRAY; + return EmptyArray.BYTE; } else { return bufferedOutput.toByteArray(); } } + @Override public byte[] doFinal(byte[] input, int inputOffset, int inputLength) throws KeyStoreException { if (inputLength == 0) { // No input provided -- simplify the rest of the code - input = EMPTY_BYTE_ARRAY; + input = EmptyArray.BYTE; inputOffset = 0; } diff --git a/keystore/java/android/security/keystore/KeyStoreCryptoOperationStreamer.java b/keystore/java/android/security/keystore/KeyStoreCryptoOperationStreamer.java new file mode 100644 index 0000000..2fb8f20 --- /dev/null +++ b/keystore/java/android/security/keystore/KeyStoreCryptoOperationStreamer.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2015 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.security.keystore; + +import android.security.KeyStore; +import android.security.KeyStoreException; + +/** + * Helper for streaming a crypto operation's input and output via {@link KeyStore} service's + * {@code update} and {@code finish} operations. + * + * <p>The helper abstracts away to issues that need to be solved in most code that uses KeyStore's + * update and finish operations. Firstly, KeyStore's update operation can consume only a limited + * amount of data in one go because the operations are marshalled via Binder. Secondly, the update + * operation may consume less data than provided, in which case the caller has to buffer the + * remainder for next time. The helper exposes {@link #update(byte[], int, int) update} and + * {@link #doFinal(byte[], int, int) doFinal} operations which can be used to conveniently implement + * various JCA crypto primitives. + * + * @hide + */ +interface KeyStoreCryptoOperationStreamer { + byte[] update(byte[] input, int inputOffset, int inputLength) throws KeyStoreException; + byte[] doFinal(byte[] input, int inputOffset, int inputLength) throws KeyStoreException; +} diff --git a/libs/hwui/FrameInfo.h b/libs/hwui/FrameInfo.h index 38a6a21..6815254 100644 --- a/libs/hwui/FrameInfo.h +++ b/libs/hwui/FrameInfo.h @@ -30,35 +30,36 @@ namespace uirenderer { #define UI_THREAD_FRAME_INFO_SIZE 9 enum class FrameInfoIndex { - kFlags = 0, - kIntendedVsync, - kVsync, - kOldestInputEvent, - kNewestInputEvent, - kHandleInputStart, - kAnimationStart, - kPerformTraversalsStart, - kDrawStart, + Flags = 0, + IntendedVsync, + Vsync, + OldestInputEvent, + NewestInputEvent, + HandleInputStart, + AnimationStart, + PerformTraversalsStart, + DrawStart, // End of UI frame info - kSyncStart, - kIssueDrawCommandsStart, - kSwapBuffers, - kFrameCompleted, + SyncStart, + IssueDrawCommandsStart, + SwapBuffers, + FrameCompleted, // Must be the last value! - kNumIndexes + NumIndexes }; extern const std::string FrameInfoNames[]; -enum class FrameInfoFlags { - kWindowLayoutChanged = 1 << 0, - kRTAnimation = 1 << 1, - kSurfaceCanvas = 1 << 2, - kSkippedFrame = 1 << 3, +namespace FrameInfoFlags { + enum { + WindowLayoutChanged = 1 << 0, + RTAnimation = 1 << 1, + SurfaceCanvas = 1 << 2, + SkippedFrame = 1 << 3, + }; }; -MAKE_FLAGS_ENUM(FrameInfoFlags) class ANDROID_API UiFrameInfoBuilder { public: @@ -67,19 +68,19 @@ public: } UiFrameInfoBuilder& setVsync(nsecs_t vsyncTime, nsecs_t intendedVsync) { - set(FrameInfoIndex::kVsync) = vsyncTime; - set(FrameInfoIndex::kIntendedVsync) = intendedVsync; + set(FrameInfoIndex::Vsync) = vsyncTime; + set(FrameInfoIndex::IntendedVsync) = intendedVsync; // Pretend the other fields are all at vsync, too, so that naive // duration calculations end up being 0 instead of very large - set(FrameInfoIndex::kHandleInputStart) = vsyncTime; - set(FrameInfoIndex::kAnimationStart) = vsyncTime; - set(FrameInfoIndex::kPerformTraversalsStart) = vsyncTime; - set(FrameInfoIndex::kDrawStart) = vsyncTime; + set(FrameInfoIndex::HandleInputStart) = vsyncTime; + set(FrameInfoIndex::AnimationStart) = vsyncTime; + set(FrameInfoIndex::PerformTraversalsStart) = vsyncTime; + set(FrameInfoIndex::DrawStart) = vsyncTime; return *this; } - UiFrameInfoBuilder& addFlag(FrameInfoFlags flag) { - set(FrameInfoIndex::kFlags) |= static_cast<uint64_t>(flag); + UiFrameInfoBuilder& addFlag(int frameInfoFlag) { + set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag); return *this; } @@ -96,32 +97,32 @@ public: void importUiThreadInfo(int64_t* info); void markSyncStart() { - set(FrameInfoIndex::kSyncStart) = systemTime(CLOCK_MONOTONIC); + set(FrameInfoIndex::SyncStart) = systemTime(CLOCK_MONOTONIC); } void markIssueDrawCommandsStart() { - set(FrameInfoIndex::kIssueDrawCommandsStart) = systemTime(CLOCK_MONOTONIC); + set(FrameInfoIndex::IssueDrawCommandsStart) = systemTime(CLOCK_MONOTONIC); } void markSwapBuffers() { - set(FrameInfoIndex::kSwapBuffers) = systemTime(CLOCK_MONOTONIC); + set(FrameInfoIndex::SwapBuffers) = systemTime(CLOCK_MONOTONIC); } void markFrameCompleted() { - set(FrameInfoIndex::kFrameCompleted) = systemTime(CLOCK_MONOTONIC); + set(FrameInfoIndex::FrameCompleted) = systemTime(CLOCK_MONOTONIC); } - void addFlag(FrameInfoFlags flag) { - set(FrameInfoIndex::kFlags) |= static_cast<uint64_t>(flag); + void addFlag(int frameInfoFlag) { + set(FrameInfoIndex::Flags) |= static_cast<uint64_t>(frameInfoFlag); } int64_t operator[](FrameInfoIndex index) const { - if (index == FrameInfoIndex::kNumIndexes) return 0; + if (index == FrameInfoIndex::NumIndexes) return 0; return mFrameInfo[static_cast<int>(index)]; } int64_t operator[](int index) const { - if (index < 0 || index >= static_cast<int>(FrameInfoIndex::kNumIndexes)) return 0; + if (index < 0 || index >= static_cast<int>(FrameInfoIndex::NumIndexes)) return 0; return mFrameInfo[index]; } @@ -130,7 +131,7 @@ private: return mFrameInfo[static_cast<int>(index)]; } - int64_t mFrameInfo[static_cast<int>(FrameInfoIndex::kNumIndexes)]; + int64_t mFrameInfo[static_cast<int>(FrameInfoIndex::NumIndexes)]; }; } /* namespace uirenderer */ diff --git a/libs/hwui/FrameInfoVisualizer.cpp b/libs/hwui/FrameInfoVisualizer.cpp index 95b0995..9557cb0 100644 --- a/libs/hwui/FrameInfoVisualizer.cpp +++ b/libs/hwui/FrameInfoVisualizer.cpp @@ -46,15 +46,15 @@ struct BarSegment { }; static const std::array<BarSegment,9> Bar {{ - { FrameInfoIndex::kIntendedVsync, FrameInfoIndex::kVsync, 0x00695C }, - { FrameInfoIndex::kVsync, FrameInfoIndex::kHandleInputStart, 0x00796B }, - { FrameInfoIndex::kHandleInputStart, FrameInfoIndex::kAnimationStart, 0x00897B }, - { FrameInfoIndex::kAnimationStart, FrameInfoIndex::kPerformTraversalsStart, 0x009688 }, - { FrameInfoIndex::kPerformTraversalsStart, FrameInfoIndex::kDrawStart, 0x26A69A}, - { FrameInfoIndex::kDrawStart, FrameInfoIndex::kSyncStart, 0x2196F3}, - { FrameInfoIndex::kSyncStart, FrameInfoIndex::kIssueDrawCommandsStart, 0x4FC3F7}, - { FrameInfoIndex::kIssueDrawCommandsStart, FrameInfoIndex::kSwapBuffers, 0xF44336}, - { FrameInfoIndex::kSwapBuffers, FrameInfoIndex::kFrameCompleted, 0xFF9800}, + { FrameInfoIndex::IntendedVsync, FrameInfoIndex::Vsync, 0x00695C }, + { FrameInfoIndex::Vsync, FrameInfoIndex::HandleInputStart, 0x00796B }, + { FrameInfoIndex::HandleInputStart, FrameInfoIndex::AnimationStart, 0x00897B }, + { FrameInfoIndex::AnimationStart, FrameInfoIndex::PerformTraversalsStart, 0x009688 }, + { FrameInfoIndex::PerformTraversalsStart, FrameInfoIndex::DrawStart, 0x26A69A}, + { FrameInfoIndex::DrawStart, FrameInfoIndex::SyncStart, 0x2196F3}, + { FrameInfoIndex::SyncStart, FrameInfoIndex::IssueDrawCommandsStart, 0x4FC3F7}, + { FrameInfoIndex::IssueDrawCommandsStart, FrameInfoIndex::SwapBuffers, 0xF44336}, + { FrameInfoIndex::SwapBuffers, FrameInfoIndex::FrameCompleted, 0xFF9800}, }}; static int dpToPx(int dp, float density) { @@ -137,7 +137,7 @@ void FrameInfoVisualizer::nextBarSegment(FrameInfoIndex start, FrameInfoIndex en for (size_t fi = 0, ri = 0; fi < mFrameSource.size(); fi++, ri += 4) { // TODO: Skipped frames will leave little holes in the graph, but this // is better than bogus and freaky lines, so... - if (mFrameSource[fi][FrameInfoIndex::kFlags] & FrameInfoFlags::kSkippedFrame) { + if (mFrameSource[fi][FrameInfoIndex::Flags] & FrameInfoFlags::SkippedFrame) { continue; } @@ -166,7 +166,7 @@ void FrameInfoVisualizer::drawCurrentFrame(const int baseline, OpenGLRenderer* c size_t fi = mFrameSource.size() - 1; size_t ri = fi * 4; float top = baseline - (mVerticalUnit * duration(fi, - FrameInfoIndex::kIntendedVsync, FrameInfoIndex::kIssueDrawCommandsStart)); + FrameInfoIndex::IntendedVsync, FrameInfoIndex::IssueDrawCommandsStart)); canvas->drawRect(mRects[ri], top, mRects[ri + 2], baseline, &paint); } @@ -214,15 +214,15 @@ void FrameInfoVisualizer::dumpData(int fd) { fprintf(file, "\n\tDraw\tPrepare\tProcess\tExecute\n"); for (size_t i = 0; i < mFrameSource.size(); i++) { - if (mFrameSource[i][FrameInfoIndex::kIntendedVsync] <= mLastFrameLogged) { + if (mFrameSource[i][FrameInfoIndex::IntendedVsync] <= mLastFrameLogged) { continue; } - mLastFrameLogged = mFrameSource[i][FrameInfoIndex::kIntendedVsync]; + mLastFrameLogged = mFrameSource[i][FrameInfoIndex::IntendedVsync]; fprintf(file, "\t%3.2f\t%3.2f\t%3.2f\t%3.2f\n", - duration(i, FrameInfoIndex::kIntendedVsync, FrameInfoIndex::kSyncStart), - duration(i, FrameInfoIndex::kSyncStart, FrameInfoIndex::kIssueDrawCommandsStart), - duration(i, FrameInfoIndex::kIssueDrawCommandsStart, FrameInfoIndex::kSwapBuffers), - duration(i, FrameInfoIndex::kSwapBuffers, FrameInfoIndex::kFrameCompleted)); + duration(i, FrameInfoIndex::IntendedVsync, FrameInfoIndex::SyncStart), + duration(i, FrameInfoIndex::SyncStart, FrameInfoIndex::IssueDrawCommandsStart), + duration(i, FrameInfoIndex::IssueDrawCommandsStart, FrameInfoIndex::SwapBuffers), + duration(i, FrameInfoIndex::SwapBuffers, FrameInfoIndex::FrameCompleted)); } fflush(file); diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp index cc5c403..5c0801e 100644 --- a/libs/hwui/JankTracker.cpp +++ b/libs/hwui/JankTracker.cpp @@ -40,11 +40,11 @@ struct Comparison { }; static const Comparison COMPARISONS[] = { - {FrameInfoIndex::kIntendedVsync, FrameInfoIndex::kVsync}, - {FrameInfoIndex::kOldestInputEvent, FrameInfoIndex::kVsync}, - {FrameInfoIndex::kVsync, FrameInfoIndex::kSyncStart}, - {FrameInfoIndex::kSyncStart, FrameInfoIndex::kIssueDrawCommandsStart}, - {FrameInfoIndex::kIssueDrawCommandsStart, FrameInfoIndex::kFrameCompleted}, + {FrameInfoIndex::IntendedVsync, FrameInfoIndex::Vsync}, + {FrameInfoIndex::OldestInputEvent, FrameInfoIndex::Vsync}, + {FrameInfoIndex::Vsync, FrameInfoIndex::SyncStart}, + {FrameInfoIndex::SyncStart, FrameInfoIndex::IssueDrawCommandsStart}, + {FrameInfoIndex::IssueDrawCommandsStart, FrameInfoIndex::FrameCompleted}, }; // If the event exceeds 10 seconds throw it away, this isn't a jank event @@ -64,8 +64,8 @@ static const int64_t IGNORE_EXCEEDING = seconds_to_nanoseconds(10); * time on the RenderThread, figure out how to attribute that as a jank-causer */ static const int64_t EXEMPT_FRAMES_FLAGS - = FrameInfoFlags::kWindowLayoutChanged - | FrameInfoFlags::kSurfaceCanvas; + = FrameInfoFlags::WindowLayoutChanged + | FrameInfoFlags::SurfaceCanvas; // The bucketing algorithm controls so to speak // If a frame is <= to this it goes in bucket 0 @@ -206,7 +206,7 @@ void JankTracker::addFrame(const FrameInfo& frame) { mData->totalFrameCount++; // Fast-path for jank-free frames int64_t totalDuration = - frame[FrameInfoIndex::kFrameCompleted] - frame[FrameInfoIndex::kIntendedVsync]; + frame[FrameInfoIndex::FrameCompleted] - frame[FrameInfoIndex::IntendedVsync]; uint32_t framebucket = frameCountIndexForFrameTime( totalDuration, mData->frameCounts.size()); // Keep the fast path as fast as possible. @@ -215,7 +215,7 @@ void JankTracker::addFrame(const FrameInfo& frame) { return; } - if (frame[FrameInfoIndex::kFlags] & EXEMPT_FRAMES_FLAGS) { + if (frame[FrameInfoIndex::Flags] & EXEMPT_FRAMES_FLAGS) { return; } diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp index acf9c13..b88f30e 100644 --- a/libs/hwui/renderthread/CanvasContext.cpp +++ b/libs/hwui/renderthread/CanvasContext.cpp @@ -157,7 +157,7 @@ void CanvasContext::processLayerUpdate(DeferredLayerUpdater* layerUpdater) { } static bool wasSkipped(FrameInfo* info) { - return info && ((*info)[FrameInfoIndex::kFlags] & FrameInfoFlags::kSkippedFrame); + return info && ((*info)[FrameInfoIndex::Flags] & FrameInfoFlags::SkippedFrame); } void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo) { @@ -185,7 +185,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo) { } if (CC_UNLIKELY(!mNativeWindow.get())) { - mCurrentFrameInfo->addFlag(FrameInfoFlags::kSkippedFrame); + mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame); info.out.canDrawThisFrame = false; return; } @@ -199,7 +199,7 @@ void CanvasContext::prepareTree(TreeInfo& info, int64_t* uiFrameInfo) { info.out.canDrawThisFrame = !runningBehind; if (!info.out.canDrawThisFrame) { - mCurrentFrameInfo->addFlag(FrameInfoFlags::kSkippedFrame); + mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame); } if (info.out.hasAnimations || !info.out.canDrawThisFrame) { @@ -228,7 +228,7 @@ void CanvasContext::draw() { mDamageAccumulator.finish(&dirty); if (dirty.isEmpty() && Properties::skipEmptyFrames) { - mCurrentFrameInfo->addFlag(FrameInfoFlags::kSkippedFrame); + mCurrentFrameInfo->addFlag(FrameInfoFlags::SkippedFrame); return; } @@ -288,7 +288,7 @@ void CanvasContext::doFrame() { int64_t frameInfo[UI_THREAD_FRAME_INFO_SIZE]; UiFrameInfoBuilder(frameInfo) - .addFlag(FrameInfoFlags::kRTAnimation) + .addFlag(FrameInfoFlags::RTAnimation) .setVsync(mRenderThread.timeLord().computeFrameTimeNanos(), mRenderThread.timeLord().latestVsync()); @@ -400,17 +400,17 @@ void CanvasContext::setTextureAtlas(RenderThread& thread, void CanvasContext::dumpFrames(int fd) { FILE* file = fdopen(fd, "a"); fprintf(file, "\n\n---PROFILEDATA---\n"); - for (size_t i = 0; i < static_cast<size_t>(FrameInfoIndex::kNumIndexes); i++) { + for (size_t i = 0; i < static_cast<size_t>(FrameInfoIndex::NumIndexes); i++) { fprintf(file, "%s", FrameInfoNames[i].c_str()); fprintf(file, ","); } for (size_t i = 0; i < mFrames.size(); i++) { FrameInfo& frame = mFrames[i]; - if (frame[FrameInfoIndex::kSyncStart] == 0) { + if (frame[FrameInfoIndex::SyncStart] == 0) { continue; } fprintf(file, "\n"); - for (int i = 0; i < static_cast<int>(FrameInfoIndex::kNumIndexes); i++) { + for (int i = 0; i < static_cast<int>(FrameInfoIndex::NumIndexes); i++) { fprintf(file, "%" PRId64 ",", frame[i]); } } diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp index 83af4ae..008e297 100644 --- a/libs/hwui/renderthread/DrawFrameTask.cpp +++ b/libs/hwui/renderthread/DrawFrameTask.cpp @@ -110,7 +110,7 @@ void DrawFrameTask::run() { bool DrawFrameTask::syncFrameState(TreeInfo& info) { ATRACE_CALL(); - int64_t vsync = mFrameInfo[static_cast<int>(FrameInfoIndex::kVsync)]; + int64_t vsync = mFrameInfo[static_cast<int>(FrameInfoIndex::Vsync)]; mRenderThread->timeLord().vsyncReceived(vsync); mContext->makeCurrent(); Caches::getInstance().textureCache.resetMarkInUse(); diff --git a/libs/hwui/utils/Macros.h b/libs/hwui/utils/Macros.h index 1b31059..5ca9083 100644 --- a/libs/hwui/utils/Macros.h +++ b/libs/hwui/utils/Macros.h @@ -35,30 +35,4 @@ static_assert(std::is_standard_layout<Type>::value, \ #Type " must have standard layout") -#define MAKE_FLAGS_ENUM(enumType) \ - inline void operator|=(int& lhs, enumType rhs) { \ - lhs |= static_cast<int>(rhs); \ - } \ - inline int operator|(int lhs, enumType rhs) { \ - return lhs | static_cast<int>(rhs); \ - } \ - inline int operator|(enumType lhs, int rhs) { \ - return static_cast<int>(lhs) | rhs; \ - } \ - inline int operator|(enumType lhs, enumType rhs) { \ - return static_cast<int>(lhs) | static_cast<int>(rhs); \ - } \ - inline void operator&=(int& lhs, enumType rhs) { \ - lhs &= static_cast<int>(rhs); \ - } \ - inline int operator&(int lhs, enumType rhs) { \ - return lhs & static_cast<int>(rhs); \ - } \ - inline int operator&(enumType lhs, int rhs) { \ - return static_cast<int>(lhs) & rhs; \ - } \ - inline int operator&(enumType lhs, enumType rhs) { \ - return static_cast<int>(lhs) & static_cast<int>(rhs); \ - } - #endif /* MACROS_H */ diff --git a/media/java/android/media/ClosedCaptionRenderer.java b/media/java/android/media/ClosedCaptionRenderer.java index e3680e9..8403c1c 100644 --- a/media/java/android/media/ClosedCaptionRenderer.java +++ b/media/java/android/media/ClosedCaptionRenderer.java @@ -1044,42 +1044,26 @@ class CCParser { } /** - * @hide - * - * MutableBackgroundColorSpan - * - * This is a mutable version of BackgroundSpan to facilitate text - * rendering with edge styles. + * Mutable version of BackgroundSpan to facilitate text rendering with edge + * styles. * + * @hide */ -class MutableBackgroundColorSpan extends CharacterStyle - implements UpdateAppearance, ParcelableSpan { +class MutableBackgroundColorSpan extends CharacterStyle implements UpdateAppearance { private int mColor; public MutableBackgroundColorSpan(int color) { mColor = color; } - public MutableBackgroundColorSpan(Parcel src) { - mColor = src.readInt(); - } + public void setBackgroundColor(int color) { mColor = color; } + public int getBackgroundColor() { return mColor; } - @Override - public int getSpanTypeId() { - return TextUtils.BACKGROUND_COLOR_SPAN; - } - @Override - public int describeContents() { - return 0; - } - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(mColor); - } + @Override public void updateDrawState(TextPaint ds) { ds.bgColor = mColor; diff --git a/media/java/android/media/Utils.java b/media/java/android/media/Utils.java index 9e01e65..2cd3c43 100644 --- a/media/java/android/media/Utils.java +++ b/media/java/android/media/Utils.java @@ -209,6 +209,9 @@ class Utils { } static int parseIntSafely(Object o, int fallback) { + if (o == null) { + return fallback; + } try { String s = (String)o; return Integer.parseInt(s); diff --git a/media/jni/android_media_MediaCrypto.cpp b/media/jni/android_media_MediaCrypto.cpp index a9accb0..d7968d2 100644 --- a/media/jni/android_media_MediaCrypto.cpp +++ b/media/jni/android_media_MediaCrypto.cpp @@ -301,17 +301,19 @@ static void android_media_MediaCrypto_setMediaDrmSession( status_t err = crypto->setMediaDrmSession(sessionId); - String8 msg("setMediaDrmSession failed"); - if (err == ERROR_DRM_SESSION_NOT_OPENED) { - msg += ": session not opened"; - } else if (err == ERROR_UNSUPPORTED) { - msg += ": not supported by this crypto scheme"; - } else if (err == NO_INIT) { - msg += ": crypto plugin not initialized"; - } else if (err != OK) { - msg.appendFormat(": general failure (%d)", err); + if (err != OK) { + String8 msg("setMediaDrmSession failed"); + if (err == ERROR_DRM_SESSION_NOT_OPENED) { + msg += ": session not opened"; + } else if (err == ERROR_UNSUPPORTED) { + msg += ": not supported by this crypto scheme"; + } else if (err == NO_INIT) { + msg += ": crypto plugin not initialized"; + } else { + msg.appendFormat(": general failure (%d)", err); + } + jniThrowException(env, "android/media/MediaCryptoException", msg.string()); } - jniThrowException(env, "android/media/MediaCryptoException", msg.string()); } static JNINativeMethod gMethods[] = { diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java index 29c3c75..cd0e587 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/CameraMetadataTest.java @@ -731,27 +731,31 @@ public class CameraMetadataTest extends junit.framework.TestCase { @SmallTest public void testReadWriteHighSpeedVideoConfiguration() { - // int32 x 4 x 1 + // int32 x 5 x 1 checkKeyMarshal("android.control.availableHighSpeedVideoConfigurations", new HighSpeedVideoConfiguration( - /*width*/1000, /*height*/255, /*fpsMin*/30, /*fpsMax*/200), + /*width*/1000, /*height*/255, /*fpsMin*/30, /*fpsMax*/200, + /*batchSizeMax*/8), /* width, height, fpsMin, fpsMax */ - toByteArray(1000, 255, 30, 200)); + toByteArray(1000, 255, 30, 200, 8)); - // int32 x 4 x 3 + // int32 x 5 x 3 checkKeyMarshal("android.control.availableHighSpeedVideoConfigurations", new HighSpeedVideoConfiguration[] { new HighSpeedVideoConfiguration( - /*width*/1280, /*height*/720, /*fpsMin*/60, /*fpsMax*/120), + /*width*/1280, /*height*/720, /*fpsMin*/60, /*fpsMax*/120, + /*batchSizeMax*/8), new HighSpeedVideoConfiguration( - /*width*/123, /*height*/456, /*fpsMin*/1, /*fpsMax*/200), + /*width*/123, /*height*/456, /*fpsMin*/1, /*fpsMax*/200, + /*batchSizeMax*/4), new HighSpeedVideoConfiguration( - /*width*/4096, /*height*/2592, /*fpsMin*/30, /*fpsMax*/60) + /*width*/4096, /*height*/2592, /*fpsMin*/30, /*fpsMax*/60, + /*batchSizeMax*/2) }, toByteArray( - 1280, 720, 60, 120, - 123, 456, 1, 200, - 4096, 2592, 30, 60 + 1280, 720, 60, 120, 8, + 123, 456, 1, 200, 4, + 4096, 2592, 30, 60, 2 )); } diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java index cf3b7c8..09c93e9 100644 --- a/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java +++ b/packages/SettingsLib/src/com/android/settingslib/wifi/WifiTracker.java @@ -357,19 +357,17 @@ public class WifiTracker { } private void updateNetworkInfo(NetworkInfo networkInfo) { - if (mScanner != null) { - /* sticky broadcasts can call this when wifi is disabled */ - if (!mWifiManager.isWifiEnabled()) { - mScanner.pause(); - return; - } + /* sticky broadcasts can call this when wifi is disabled */ + if (!mWifiManager.isWifiEnabled()) { + mMainHandler.sendEmptyMessage(MainHandler.MSG_PAUSE_SCANNING); + return; + } - if (networkInfo != null && - networkInfo.getDetailedState() == DetailedState.OBTAINING_IPADDR) { - mScanner.pause(); - } else { - mScanner.resume(); - } + if (networkInfo != null && + networkInfo.getDetailedState() == DetailedState.OBTAINING_IPADDR) { + mMainHandler.sendEmptyMessage(MainHandler.MSG_PAUSE_SCANNING); + } else { + mMainHandler.sendEmptyMessage(MainHandler.MSG_RESUME_SCANNING); } mLastInfo = mWifiManager.getConnectionInfo(); @@ -448,6 +446,8 @@ public class WifiTracker { private static final int MSG_CONNECTED_CHANGED = 0; private static final int MSG_WIFI_STATE_CHANGED = 1; private static final int MSG_ACCESS_POINT_CHANGED = 2; + private static final int MSG_RESUME_SCANNING = 3; + private static final int MSG_PAUSE_SCANNING = 4; public MainHandler(Looper looper) { super(looper); @@ -468,6 +468,16 @@ public class WifiTracker { case MSG_ACCESS_POINT_CHANGED: mListener.onAccessPointsChanged(); break; + case MSG_RESUME_SCANNING: + if (mScanner != null) { + mScanner.resume(); + } + break; + case MSG_PAUSE_SCANNING: + if (mScanner != null) { + mScanner.pause(); + } + break; } } } diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index fd0ba73..640fb29 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -25,6 +25,7 @@ <!-- Standard permissions granted to the shell. --> <uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.CALL_PHONE" /> + <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CONTACTS" /> <uses-permission android:name="android.permission.READ_CALENDAR" /> @@ -97,6 +98,10 @@ <uses-permission android:name="android.permission.CHANGE_APP_IDLE_STATE" /> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.MOUNT_FORMAT_FILESYSTEMS" /> + <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> + <uses-permission android:name="android.permission.REGISTER_CALL_PROVIDER" /> + <uses-permission android:name="android.permission.REGISTER_CONNECTION_MANAGER" /> + <uses-permission android:name="android.permission.REGISTER_SIM_SUBSCRIPTION" /> <application android:label="@string/app_label"> <provider diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 18a19cb..9f38185 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -336,7 +336,7 @@ <dimen name="keyguard_affordance_min_background_radius">30dp</dimen> <!-- The size of the touch targets on the keyguard for the affordances. --> - <dimen name="keyguard_affordance_touch_target_size">96dp</dimen> + <dimen name="keyguard_affordance_touch_target_size">120dp</dimen> <!-- The grow amount for the camera and phone circles when hinting --> <dimen name="hint_grow_amount_sideways">60dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index c702673..bbd3e60 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -35,6 +35,7 @@ import android.graphics.Rect; import android.os.Handler; import android.os.SystemClock; import android.os.UserHandle; +import android.util.MutableBoolean; import android.util.Pair; import android.view.Display; import android.view.LayoutInflater; @@ -57,7 +58,6 @@ import com.android.systemui.recents.views.TaskViewTransform; import com.android.systemui.statusbar.phone.PhoneStatusBar; import java.util.ArrayList; -import java.util.concurrent.atomic.AtomicBoolean; /** * Annotation for a method that is only called from the primary user's SystemUI process and will be @@ -362,7 +362,12 @@ public class Recents extends SystemUI // RecentsActivity) RecentsTaskLoader loader = RecentsTaskLoader.getInstance(); sInstanceLoadPlan = loader.createLoadPlan(mContext); - sInstanceLoadPlan.preloadRawTasks(true); + + ActivityManager.RunningTaskInfo topTask = mSystemServicesProxy.getTopMostTask(); + MutableBoolean isTopTaskHome = new MutableBoolean(true); + if (topTask != null && mSystemServicesProxy.isRecentsTopMost(topTask, isTopTaskHome)) { + sInstanceLoadPlan.preloadRawTasks(isTopTaskHome.value); + } } @Override @@ -546,7 +551,7 @@ public class Recents extends SystemUI // If Recents is the front most activity, then we should just communicate with it directly // to launch the first task or dismiss itself ActivityManager.RunningTaskInfo topTask = mSystemServicesProxy.getTopMostTask(); - AtomicBoolean isTopTaskHome = new AtomicBoolean(true); + MutableBoolean isTopTaskHome = new MutableBoolean(true); if (topTask != null && mSystemServicesProxy.isRecentsTopMost(topTask, isTopTaskHome)) { // Notify recents to toggle itself Intent intent = createLocalBroadcastIntent(mContext, ACTION_TOGGLE_RECENTS_ACTIVITY); @@ -555,7 +560,7 @@ public class Recents extends SystemUI return; } else { // Otherwise, start the recents activity - startRecentsActivity(topTask, isTopTaskHome.get()); + startRecentsActivity(topTask, isTopTaskHome.value); } } @@ -563,9 +568,9 @@ public class Recents extends SystemUI void startRecentsActivity() { // Check if the top task is in the home stack, and start the recents activity ActivityManager.RunningTaskInfo topTask = mSystemServicesProxy.getTopMostTask(); - AtomicBoolean isTopTaskHome = new AtomicBoolean(true); + MutableBoolean isTopTaskHome = new MutableBoolean(true); if (topTask == null || !mSystemServicesProxy.isRecentsTopMost(topTask, isTopTaskHome)) { - startRecentsActivity(topTask, isTopTaskHome.get()); + startRecentsActivity(topTask, isTopTaskHome.value); } } @@ -654,6 +659,7 @@ public class Recents extends SystemUI if (task == null) { // If no task is specified or we can not find the task just use the front most one task = tasks.get(tasks.size() - 1); + runningTaskOut.copyFrom(task); } // Get the transform for the running task diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java index ca0f357..272d39a 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java +++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java @@ -54,6 +54,7 @@ import android.os.SystemProperties; import android.os.UserHandle; import android.provider.Settings; import android.util.Log; +import android.util.MutableBoolean; import android.util.Pair; import android.util.SparseArray; import android.view.Display; @@ -67,12 +68,9 @@ import com.android.systemui.recents.Recents; import java.io.IOException; import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Random; -import java.util.concurrent.atomic.AtomicBoolean; /** * Acts as a shim around the real system services that we need to access data from, and provides @@ -192,7 +190,7 @@ public class SystemServicesProxy { // Break early if we can't get a valid set of tasks if (tasks == null) { - return new ArrayList<ActivityManager.RecentTaskInfo>(); + return new ArrayList<>(); } boolean isFirstValidTask = true; @@ -235,7 +233,7 @@ public class SystemServicesProxy { /** Returns whether the recents is currently running */ public boolean isRecentsTopMost(ActivityManager.RunningTaskInfo topTask, - AtomicBoolean isHomeTopMost) { + MutableBoolean isHomeTopMost) { if (topTask != null) { ComponentName topActivity = topTask.topActivity; @@ -243,13 +241,13 @@ public class SystemServicesProxy { if (topActivity.getPackageName().equals(Recents.sRecentsPackage) && topActivity.getClassName().equals(Recents.sRecentsActivity)) { if (isHomeTopMost != null) { - isHomeTopMost.set(false); + isHomeTopMost.value = false; } return true; } if (isHomeTopMost != null) { - isHomeTopMost.set(isInHomeStack(topTask.id)); + isHomeTopMost.value = isInHomeStack(topTask.id); } } return false; diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java index 40cd211..f40c58d 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java +++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java @@ -104,13 +104,9 @@ public class RecentsTaskLoadPlan { if (mRawTasks == null) { preloadRawTasks(isTopTaskHome); } - int firstStackId = -1; int taskCount = mRawTasks.size(); for (int i = 0; i < taskCount; i++) { ActivityManager.RecentTaskInfo t = mRawTasks.get(i); - if (firstStackId < 0) { - firstStackId = t.stackId; - } // Compose the task key Task.TaskKey taskKey = new Task.TaskKey(t.persistentId, t.stackId, t.baseIntent, @@ -158,17 +154,17 @@ public class RecentsTaskLoadPlan { if (!mConfig.multiStackEnabled || Constants.DebugFlags.App.EnableMultiStackToSingleStack) { - firstStackId = 0; + int firstStackId = 0; ArrayList<Task> stackTasks = stacksTasks.get(firstStackId); if (stackTasks == null) { - stackTasks = new ArrayList<Task>(); + stackTasks = new ArrayList<>(); stacksTasks.put(firstStackId, stackTasks); } stackTasks.add(task); } else { ArrayList<Task> stackTasks = stacksTasks.get(t.stackId); if (stackTasks == null) { - stackTasks = new ArrayList<Task>(); + stackTasks = new ArrayList<>(); stacksTasks.put(t.stackId, stackTasks); } stackTasks.add(task); 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 b3e6221..cec613c 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java @@ -550,7 +550,7 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV if (tv == null) { launchRunnable.run(); } else { - if (!task.group.isFrontMostTask(task)) { + if (task.group != null && !task.group.isFrontMostTask(task)) { // For affiliated tasks that are behind other tasks, we must animate the front cards // out of view before starting the task transition stackView.startLaunchTaskAnimation(tv, launchRunnable, lockToTask); diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java index 9fbcd7f..d6a16fa 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java +++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessController.java @@ -40,7 +40,7 @@ public class BrightnessController implements ToggleSlider.Listener { * {@link android.provider.Settings.System#SCREEN_AUTO_BRIGHTNESS_ADJ} uses the range [-1, 1]. * Using this factor, it is converted to [0, BRIGHTNESS_ADJ_RESOLUTION] for the SeekBar. */ - private static final float BRIGHTNESS_ADJ_RESOLUTION = 100; + private static final float BRIGHTNESS_ADJ_RESOLUTION = 2048; private final int mMinimumBacklight; private final int mMaximumBacklight; diff --git a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java index 35b574b..8abfe03 100644 --- a/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java +++ b/packages/SystemUI/src/com/android/systemui/settings/ToggleSlider.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; import android.util.AttributeSet; +import android.view.MotionEvent; import android.view.View; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; @@ -123,6 +124,16 @@ public class ToggleSlider extends RelativeLayout { } } + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + if (mMirror != null) { + MotionEvent copy = ev.copy(); + mMirror.dispatchTouchEvent(copy); + copy.recycle(); + } + return super.dispatchTouchEvent(ev); + } + private final OnCheckedChangeListener mCheckListener = new OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton toggle, boolean checked) { @@ -146,10 +157,6 @@ public class ToggleSlider extends RelativeLayout { mListener.onChanged( ToggleSlider.this, mTracking, mToggle.isChecked(), progress); } - - if (mMirror != null) { - mMirror.setValue(progress); - } } @Override @@ -163,10 +170,6 @@ public class ToggleSlider extends RelativeLayout { mToggle.setChecked(false); - if (mMirror != null) { - mMirror.mSlider.setPressed(true); - } - if (mMirrorController != null) { mMirrorController.showMirror(); mMirrorController.setLocation((View) getParent()); @@ -182,10 +185,6 @@ public class ToggleSlider extends RelativeLayout { ToggleSlider.this, mTracking, mToggle.isChecked(), mSlider.getProgress()); } - if (mMirror != null) { - mMirror.mSlider.setPressed(false); - } - if (mMirrorController != null) { mMirrorController.hideMirror(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java index 9ccff72..374d970 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardAffordanceView.java @@ -23,11 +23,14 @@ import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; +import android.graphics.CanvasProperty; import android.graphics.Color; import android.graphics.Paint; import android.graphics.PorterDuff; import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.view.DisplayListCanvas; +import android.view.RenderNodeAnimator; import android.view.View; import android.view.ViewAnimationUtils; import android.view.animation.AnimationUtils; @@ -35,6 +38,7 @@ import android.view.animation.Interpolator; import android.widget.ImageView; import com.android.systemui.R; import com.android.systemui.statusbar.phone.KeyguardAffordanceHelper; +import com.android.systemui.statusbar.phone.PhoneStatusBar; /** * An ImageView which does not have overlapping renderings commands and therefore does not need a @@ -77,6 +81,14 @@ public class KeyguardAffordanceView extends ImageView { private float mMaxCircleSize; private Animator mPreviewClipper; private float mRestingAlpha = KeyguardAffordanceHelper.SWIPE_RESTING_ALPHA_AMOUNT; + private boolean mSupportHardware; + private boolean mFinishing; + + private CanvasProperty<Float> mHwCircleRadius; + private CanvasProperty<Float> mHwCenterX; + private CanvasProperty<Float> mHwCenterY; + private CanvasProperty<Paint> mHwCirclePaint; + private AnimatorListenerAdapter mClipEndListener = new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { @@ -155,6 +167,7 @@ public class KeyguardAffordanceView extends ImageView { @Override protected void onDraw(Canvas canvas) { + mSupportHardware = canvas.isHardwareAccelerated(); drawBackgroundCircle(canvas); drawArrow(canvas); canvas.save(); @@ -196,8 +209,14 @@ public class KeyguardAffordanceView extends ImageView { private void drawBackgroundCircle(Canvas canvas) { if (mCircleRadius > 0) { - updateCircleColor(); - canvas.drawCircle(mCenterX, mCenterY, mCircleRadius, mCirclePaint); + if (mFinishing && mSupportHardware) { + DisplayListCanvas displayListCanvas = (DisplayListCanvas) canvas; + displayListCanvas.drawCircle(mHwCenterX, mHwCenterY, mHwCircleRadius, + mHwCirclePaint); + } else { + updateCircleColor(); + canvas.drawCircle(mCenterX, mCenterY, mCircleRadius, mCirclePaint); + } } } @@ -218,15 +237,23 @@ public class KeyguardAffordanceView extends ImageView { public void finishAnimation(float velocity, final Runnable mAnimationEndRunnable) { cancelAnimator(mCircleAnimator); cancelAnimator(mPreviewClipper); + mFinishing = true; mCircleStartRadius = mCircleRadius; float maxCircleSize = getMaxCircleSize(); - ValueAnimator animatorToRadius = getAnimatorToRadius(maxCircleSize); + Animator animatorToRadius; + if (mSupportHardware) { + initHwProperties(); + animatorToRadius = getRtAnimatorToRadius(maxCircleSize); + } else { + animatorToRadius = getAnimatorToRadius(maxCircleSize); + } mFlingAnimationUtils.applyDismissing(animatorToRadius, mCircleRadius, maxCircleSize, velocity, maxCircleSize); animatorToRadius.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mAnimationEndRunnable.run(); + mFinishing = false; } }); animatorToRadius.start(); @@ -240,9 +267,34 @@ public class KeyguardAffordanceView extends ImageView { velocity, maxCircleSize); mPreviewClipper.addListener(mClipEndListener); mPreviewClipper.start(); + if (mSupportHardware) { + startRtCircleFadeOut(animatorToRadius.getDuration()); + } } } + private void startRtCircleFadeOut(long duration) { + RenderNodeAnimator animator = new RenderNodeAnimator(mHwCirclePaint, + RenderNodeAnimator.PAINT_ALPHA, 0); + animator.setDuration(duration); + animator.setInterpolator(PhoneStatusBar.ALPHA_OUT); + animator.setTarget(this); + animator.start(); + } + + private Animator getRtAnimatorToRadius(float circleRadius) { + RenderNodeAnimator animator = new RenderNodeAnimator(mHwCircleRadius, circleRadius); + animator.setTarget(this); + return animator; + } + + private void initHwProperties() { + mHwCenterX = CanvasProperty.createFloat(mCenterX); + mHwCenterY = CanvasProperty.createFloat(mCenterY); + mHwCirclePaint = CanvasProperty.createPaint(mCirclePaint); + mHwCircleRadius = CanvasProperty.createFloat(mCircleRadius); + } + private float getMaxCircleSize() { getLocationInWindow(mTempPoint); float rootWidth = getRootView().getWidth(); 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 2fe98bb..4bc317a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -196,6 +196,7 @@ public class NotificationPanelView extends PanelView implements private boolean mCollapsedOnDown; private int mPositionMinSideMargin; private int mLastOrientation = -1; + private boolean mClosingWithAlphaFadeOut; private Runnable mHeadsUpExistenceChangedRunnable = new Runnable() { @Override @@ -527,6 +528,7 @@ public class NotificationPanelView extends PanelView implements protected void flingToHeight(float vel, boolean expand, float target, float collapseSpeedUpFactor, boolean expandBecauseOfFalsing) { mHeadsUpTouchHelper.notifyFling(!expand); + setClosingWithAlphaFadeout(!expand && getFadeoutAlpha() == 1.0f); super.flingToHeight(vel, expand, target, collapseSpeedUpFactor, expandBecauseOfFalsing); } @@ -638,10 +640,9 @@ public class NotificationPanelView extends PanelView implements @Override protected boolean isInContentBounds(float x, float y) { - float yTransformed = y - mNotificationStackScroller.getY(); float stackScrollerX = mNotificationStackScroller.getX(); - return mNotificationStackScroller.isInContentBounds(yTransformed) && stackScrollerX < x - && x < stackScrollerX + mNotificationStackScroller.getWidth(); + return !mNotificationStackScroller.isBelowLastNotification(x - stackScrollerX, y) + && stackScrollerX < x && x < stackScrollerX + mNotificationStackScroller.getWidth(); } private void initDownStates(MotionEvent event) { @@ -1074,8 +1075,12 @@ public class NotificationPanelView extends PanelView implements }; private void animateHeaderSlidingIn() { - mHeaderAnimating = true; - getViewTreeObserver().addOnPreDrawListener(mStartHeaderSlidingIn); + // If the QS is already expanded we don't need to slide in the header as it's already + // visible. + if (!mQsExpanded) { + mHeaderAnimating = true; + getViewTreeObserver().addOnPreDrawListener(mStartHeaderSlidingIn); + } } private void animateHeaderSlidingOut() { @@ -1585,26 +1590,22 @@ public class NotificationPanelView extends PanelView implements } } private void updateNotificationTranslucency() { - float alpha; - if (mExpandingFromHeadsUp || mHeadsUpManager.hasPinnedHeadsUp()) { - alpha = 1f; - } else { - alpha = (getNotificationsTopY() + mNotificationStackScroller.getItemHeight()) - / (mQsMinExpansionHeight + mNotificationStackScroller.getBottomStackPeekSize() - - mNotificationStackScroller.getCollapseSecondCardPadding()); - alpha = Math.max(0, Math.min(alpha, 1)); - alpha = (float) Math.pow(alpha, 0.75); - } - - if (alpha != 1f && mNotificationStackScroller.getLayerType() != LAYER_TYPE_HARDWARE) { - mNotificationStackScroller.setLayerType(LAYER_TYPE_HARDWARE, null); - } else if (alpha == 1f - && mNotificationStackScroller.getLayerType() == LAYER_TYPE_HARDWARE) { - mNotificationStackScroller.setLayerType(LAYER_TYPE_NONE, null); + float alpha = 1f; + if (mClosingWithAlphaFadeOut && !mExpandingFromHeadsUp && !mHeadsUpManager.hasPinnedHeadsUp()) { + alpha = getFadeoutAlpha(); } mNotificationStackScroller.setAlpha(alpha); } + private float getFadeoutAlpha() { + float alpha = (getNotificationsTopY() + mNotificationStackScroller.getItemHeight()) + / (mQsMinExpansionHeight + mNotificationStackScroller.getBottomStackPeekSize() + - mNotificationStackScroller.getCollapseSecondCardPadding()); + alpha = Math.max(0, Math.min(alpha, 1)); + alpha = (float) Math.pow(alpha, 0.75); + return alpha; + } + @Override protected float getOverExpansionAmount() { return mNotificationStackScroller.getCurrentOverScrollAmount(true /* top */); @@ -2261,6 +2262,12 @@ public class NotificationPanelView extends PanelView implements protected void onClosingFinished() { super.onClosingFinished(); resetVerticalPanelPosition(); + setClosingWithAlphaFadeout(false); + } + + private void setClosingWithAlphaFadeout(boolean closing) { + mClosingWithAlphaFadeOut = closing; + mNotificationStackScroller.forceNoOverlappingRendering(closing); } /** 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 6d35ff0..9d4997c 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java @@ -777,6 +777,15 @@ public abstract class PanelView extends FrameLayout { public void setExpandedFraction(float frac) { setExpandedHeight(getMaxPanelHeight() * frac); + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD + && mStatusBar.getBarState() == StatusBarState.KEYGUARD) { + if (frac == 0.0f) { + Log.i(PhoneStatusBar.TAG, "Panel collapsed! Stacktrace: " + + Log.getStackTraceString(new Throwable())); + } else if (frac == 1.0f) { + mStatusBar.endWindowManagerLogging(); + } + } } public float getExpandedHeight() { @@ -808,6 +817,11 @@ public abstract class PanelView extends FrameLayout { } public void collapse(boolean delayed, float speedUpFactor) { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD + && mStatusBar.getBarState() == StatusBarState.KEYGUARD) { + Log.i(PhoneStatusBar.TAG, "Panel collapsed! Stacktrace: " + + Log.getStackTraceString(new Throwable())); + } if (DEBUG) logf("collapse: " + this); if (mPeekPending || mPeekAnimator != null) { mCollapseAfterPeek = true; 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 def95aa..7c7bec9 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -185,6 +185,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, HeadsUpManager.OnHeadsUpChangedListener { static final String TAG = "PhoneStatusBar"; public static final boolean DEBUG = BaseStatusBar.DEBUG; + public static final boolean DEBUG_EMPTY_KEYGUARD = true; public static final boolean SPEW = false; public static final boolean DUMPTRUCK = true; // extra dumpsys info public static final boolean DEBUG_GESTURES = false; @@ -2003,6 +2004,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mStatusBarWindowManager.setPanelExpanded(isExpanded); } + public void endWindowManagerLogging() { + mStatusBarWindowManager.setLogState(false); + } + /** * All changes to the status bar and notifications funnel through here and are batched. */ @@ -3547,6 +3552,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // Make our window larger and the panel expanded. makeExpandedVisible(true); mNotificationPanel.instantExpand(); + if (DEBUG_EMPTY_KEYGUARD) { + mStatusBarWindowManager.setLogState(true); + } } private void instantCollapseNotificationPanel() { 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 aa499ad..b7e675d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java @@ -20,12 +20,14 @@ 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; import com.android.systemui.EventLogTags; import com.android.systemui.R; +import com.android.systemui.statusbar.StatusBarState; public class PhoneStatusBarView extends PanelBar { private static final String TAG = "PhoneStatusBarView"; @@ -108,7 +110,11 @@ public class PhoneStatusBarView extends PanelBar { @Override public void onAllPanelsCollapsed() { super.onAllPanelsCollapsed(); - + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD + && mBar.getBarState() == StatusBarState.KEYGUARD) { + Log.i(PhoneStatusBar.TAG, "Panel collapsed! Stacktrace: " + + Log.getStackTraceString(new Throwable())); + } // Close the status bar in the next frame so we can show the end of the animation. postOnAnimation(new Runnable() { @Override diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java index de42643..58017d0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java @@ -21,6 +21,7 @@ import android.content.pm.ActivityInfo; import android.content.res.Resources; import android.graphics.PixelFormat; import android.os.SystemProperties; +import android.util.Log; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -31,6 +32,8 @@ import com.android.systemui.keyguard.KeyguardViewMediator; import com.android.systemui.statusbar.BaseStatusBar; import com.android.systemui.statusbar.StatusBarState; +import java.lang.reflect.Field; + /** * Encapsulates all logic for the status bar window state management. */ @@ -45,6 +48,7 @@ public class StatusBarWindowManager { private final boolean mKeyguardScreenRotation; private final State mCurrentState = new State(); + private boolean mLogState; public StatusBarWindowManager(Context context) { mContext = context; @@ -129,9 +133,7 @@ public class StatusBarWindowManager { } private void applyHeight(State state) { - boolean expanded = !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded() - || state.panelVisible || state.keyguardFadingAway || state.bouncerShowing - || state.headsUpShowing); + boolean expanded = isExpanded(state); if (expanded) { mLpChanged.height = ViewGroup.LayoutParams.MATCH_PARENT; } else { @@ -139,6 +141,12 @@ public class StatusBarWindowManager { } } + private boolean isExpanded(State state) { + return !state.forceCollapsed && (state.isKeyguardShowingAndNotOccluded() + || state.panelVisible || state.keyguardFadingAway || state.bouncerShowing + || state.headsUpShowing); + } + private void applyFitsSystemWindows(State state) { mStatusBarView.setFitsSystemWindows(!state.isKeyguardShowingAndNotOccluded()); } @@ -176,6 +184,9 @@ public class StatusBarWindowManager { applyFitsSystemWindows(state); applyModalFlag(state); if (mLp.copyFrom(mLpChanged) != 0) { + if (PhoneStatusBar.DEBUG_EMPTY_KEYGUARD && mLogState) { + logCurrentState(); + } mWindowManager.updateViewLayout(mStatusBarView, mLp); } } @@ -272,6 +283,21 @@ public class StatusBarWindowManager { apply(mCurrentState); } + public void setLogState(boolean logState) { + mLogState = logState; + if (logState) { + Log.w(PhoneStatusBar.TAG, "===== Started logging WM state changes ====="); + logCurrentState(); + } else { + Log.w(PhoneStatusBar.TAG, "===== Finished logging WM state changes ====="); + } + } + + private void logCurrentState() { + Log.i(PhoneStatusBar.TAG, mCurrentState.toString() + + "\n Expanded: " + isExpanded(mCurrentState)); + } + private static class State { boolean keyguardShowing; boolean keyguardOccluded; @@ -294,5 +320,31 @@ public class StatusBarWindowManager { private boolean isKeyguardShowingAndNotOccluded() { return keyguardShowing && !keyguardOccluded; } + + @Override + public String toString() { + StringBuilder result = new StringBuilder(); + String newLine = "\n"; + result.append("Window State {"); + result.append(newLine); + + Field[] fields = this.getClass().getDeclaredFields(); + + // Print field names paired with their values + for (Field field : fields) { + result.append(" "); + try { + result.append(field.getName()); + result.append(": "); + //requires access to private field: + result.append(field.get(this)); + } catch (IllegalAccessException ex) { + } + result.append(newLine); + } + result.append("}"); + + return result.toString(); + } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java index 3b91751..6a8f8ee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java @@ -171,7 +171,6 @@ public class StatusBarWindowView extends FrameLayout { if (mNotificationPanel.isFullyExpanded() && mStackScrollLayout.getVisibility() == View.VISIBLE && mService.getBarState() == StatusBarState.KEYGUARD - && !mService.isQsExpanded() && !mService.isBouncerShowing()) { intercept = mDragDownHelper.onInterceptTouchEvent(ev); // wake up on a touch down event, if dozing @@ -195,7 +194,7 @@ public class StatusBarWindowView extends FrameLayout { @Override public boolean onTouchEvent(MotionEvent ev) { boolean handled = false; - if (mService.getBarState() == StatusBarState.KEYGUARD && !mService.isQsExpanded()) { + if (mService.getBarState() == StatusBarState.KEYGUARD) { handled = mDragDownHelper.onTouchEvent(ev); } if (!handled) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java index 4ae800f..d8f6bcd 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -225,6 +225,7 @@ public class NotificationStackScrollLayout extends ViewGroup private HeadsUpManager mHeadsUpManager; private boolean mTrackingHeadsUp; private ScrimController mScrimController; + private boolean mForceNoOverlappingRendering; public NotificationStackScrollLayout(Context context) { this(context, null); @@ -811,8 +812,7 @@ public class NotificationStackScrollLayout extends ViewGroup } handleEmptySpaceClick(ev); boolean expandWantsIt = false; - if (mIsExpanded && !mSwipingInProgress && !mOnlyScrollingInThisMotion - && isScrollingEnabled()) { + if (mIsExpanded && !mSwipingInProgress && !mOnlyScrollingInThisMotion) { if (isCancelOrUp) { mExpandHelper.onlyObserveMovements(false); } @@ -1566,7 +1566,7 @@ public class NotificationStackScrollLayout extends ViewGroup initDownStates(ev); handleEmptySpaceClick(ev); boolean expandWantsIt = false; - if (!mSwipingInProgress && !mOnlyScrollingInThisMotion && isScrollingEnabled()) { + if (!mSwipingInProgress && !mOnlyScrollingInThisMotion) { expandWantsIt = mExpandHelper.onInterceptTouchEvent(ev); } boolean scrollWantsIt = false; @@ -2267,11 +2267,11 @@ public class NotificationStackScrollLayout extends ViewGroup private void updateScrollPositionOnExpandInBottom(ExpandableView view) { if (view instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) view; - if (row.isUserLocked()) { + if (row.isUserLocked() && row != getFirstChildNotGone()) { // We are actually expanding this view float endPosition = row.getTranslationY() + row.getActualHeight(); int stackEnd = mMaxLayoutHeight - mBottomStackPeekSize - - mBottomStackSlowDownHeight; + mBottomStackSlowDownHeight + (int) mStackTranslation; if (endPosition > stackEnd) { mOwnScrollY += endPosition - stackEnd; mDisallowScrollingInThisMotion = true; @@ -2614,7 +2614,7 @@ public class NotificationStackScrollLayout extends ViewGroup } } - private boolean isBelowLastNotification(float touchX, float touchY) { + public boolean isBelowLastNotification(float touchX, float touchY) { int childCount = getChildCount(); for (int i = childCount - 1; i >= 0; i--) { ExpandableView child = (ExpandableView) getChildAt(i); @@ -2640,7 +2640,7 @@ public class NotificationStackScrollLayout extends ViewGroup } } } - return touchY > mIntrinsicPadding; + return touchY > mTopPadding + mStackTranslation; } private void updateExpandButtons() { @@ -2732,6 +2732,15 @@ public class NotificationStackScrollLayout extends ViewGroup mScrimController = scrimController; } + public void forceNoOverlappingRendering(boolean force) { + mForceNoOverlappingRendering = force; + } + + @Override + public boolean hasOverlappingRendering() { + return !mForceNoOverlappingRendering && super.hasOverlappingRendering(); + } + /** * A listener that is notified when some child locations might have changed. */ diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java index d4c3194..7bcbcfb 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java @@ -166,8 +166,6 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { private final List<AccessibilityServiceInfo> mEnabledServicesForFeedbackTempList = new ArrayList<>(); - private final Region mTempRegion = new Region(); - private final Rect mTempRect = new Rect(); private final Rect mTempRect1 = new Rect(); @@ -2241,7 +2239,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { throws RemoteException { final int resolvedWindowId; IAccessibilityInteractionConnection connection = null; - Region partialInteractiveRegion = mTempRegion; + Region partialInteractiveRegion = Region.obtain(); synchronized (mLock) { // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below @@ -2265,6 +2263,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked( resolvedWindowId, partialInteractiveRegion)) { + partialInteractiveRegion.recycle(); partialInteractiveRegion = null; } } @@ -2282,6 +2281,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } finally { Binder.restoreCallingIdentity(identityToken); + // Recycle if passed to another process. + if (partialInteractiveRegion != null && Binder.isProxy(connection)) { + partialInteractiveRegion.recycle(); + } } return false; } @@ -2293,7 +2296,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { throws RemoteException { final int resolvedWindowId; IAccessibilityInteractionConnection connection = null; - Region partialInteractiveRegion = mTempRegion; + Region partialInteractiveRegion = Region.obtain(); synchronized (mLock) { // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below @@ -2317,6 +2320,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked( resolvedWindowId, partialInteractiveRegion)) { + partialInteractiveRegion.recycle(); partialInteractiveRegion = null; } } @@ -2334,6 +2338,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } finally { Binder.restoreCallingIdentity(identityToken); + // Recycle if passed to another process. + if (partialInteractiveRegion != null && Binder.isProxy(connection)) { + partialInteractiveRegion.recycle(); + } } return false; } @@ -2345,7 +2353,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { long interrogatingTid) throws RemoteException { final int resolvedWindowId; IAccessibilityInteractionConnection connection = null; - Region partialInteractiveRegion = mTempRegion; + Region partialInteractiveRegion = Region.obtain(); synchronized (mLock) { // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below @@ -2369,6 +2377,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked( resolvedWindowId, partialInteractiveRegion)) { + partialInteractiveRegion.recycle(); partialInteractiveRegion = null; } } @@ -2386,6 +2395,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } finally { Binder.restoreCallingIdentity(identityToken); + // Recycle if passed to another process. + if (partialInteractiveRegion != null && Binder.isProxy(connection)) { + partialInteractiveRegion.recycle(); + } } return false; } @@ -2397,7 +2410,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { throws RemoteException { final int resolvedWindowId; IAccessibilityInteractionConnection connection = null; - Region partialInteractiveRegion = mTempRegion; + Region partialInteractiveRegion = Region.obtain(); synchronized (mLock) { // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below @@ -2422,6 +2435,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked( resolvedWindowId, partialInteractiveRegion)) { + partialInteractiveRegion.recycle(); partialInteractiveRegion = null; } } @@ -2439,6 +2453,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } finally { Binder.restoreCallingIdentity(identityToken); + // Recycle if passed to another process. + if (partialInteractiveRegion != null && Binder.isProxy(connection)) { + partialInteractiveRegion.recycle(); + } } return false; } @@ -2450,7 +2468,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { throws RemoteException { final int resolvedWindowId; IAccessibilityInteractionConnection connection = null; - Region partialInteractiveRegion = mTempRegion; + Region partialInteractiveRegion = Region.obtain(); synchronized (mLock) { // We treat calls from a profile as if made by its parent as profiles // share the accessibility state of the parent. The call below @@ -2474,6 +2492,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } if (!mSecurityPolicy.computePartialInteractiveRegionForWindowLocked( resolvedWindowId, partialInteractiveRegion)) { + partialInteractiveRegion.recycle(); partialInteractiveRegion = null; } } @@ -2491,6 +2510,10 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub { } } finally { Binder.restoreCallingIdentity(identityToken); + // Recycle if passed to another process. + if (partialInteractiveRegion != null && Binder.isProxy(connection)) { + partialInteractiveRegion.recycle(); + } } return false; } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index e07e4e2..928d1d6 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -1661,6 +1661,12 @@ public class ConnectivityService extends IConnectivityManager.Stub } private static final String DEFAULT_TCP_BUFFER_SIZES = "4096,87380,110208,4096,16384,110208"; + private static final String DEFAULT_TCP_RWND_KEY = "net.tcp.default_init_rwnd"; + + // Overridden for testing purposes to avoid writing to SystemProperties. + protected int getDefaultTcpRwnd() { + return SystemProperties.getInt(DEFAULT_TCP_RWND_KEY, 0); + } private void updateTcpBufferSizes(NetworkAgentInfo nai) { if (isDefaultNetwork(nai) == false) { @@ -1696,10 +1702,8 @@ public class ConnectivityService extends IConnectivityManager.Stub loge("Can't set TCP buffer sizes:" + e); } - final String defaultRwndKey = "net.tcp.default_init_rwnd"; - int defaultRwndValue = SystemProperties.getInt(defaultRwndKey, 0); Integer rwndValue = Settings.Global.getInt(mContext.getContentResolver(), - Settings.Global.TCP_DEFAULT_INIT_RWND, defaultRwndValue); + Settings.Global.TCP_DEFAULT_INIT_RWND, getDefaultTcpRwnd()); final String sysctlKey = "sys.sysctl.tcp_def_init_rwnd"; if (rwndValue != 0) { SystemProperties.set(sysctlKey, rwndValue.toString()); @@ -3819,10 +3823,12 @@ public class ConnectivityService extends IConnectivityManager.Stub // } updateTcpBufferSizes(networkAgent); - // TODO: deprecate and remove mDefaultDns when we can do so safely. - // For now, use it only when the network has Internet access. http://b/18327075 - final boolean useDefaultDns = networkAgent.networkCapabilities.hasCapability( - NET_CAPABILITY_INTERNET); + // TODO: deprecate and remove mDefaultDns when we can do so safely. See http://b/18327075 + // In L, we used it only when the network had Internet access but provided no DNS servers. + // For now, just disable it, and if disabling it doesn't break things, remove it. + // final boolean useDefaultDns = networkAgent.networkCapabilities.hasCapability( + // NET_CAPABILITY_INTERNET); + final boolean useDefaultDns = false; final boolean flushDns = updateRoutes(newLp, oldLp, netId); updateDnses(newLp, oldLp, netId, flushDns, useDefaultDns); diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index 201a4ca..0513d8b 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -960,26 +960,33 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } private void switchUserLocked(int newUserId) { + if (DEBUG) Slog.d(TAG, "Switching user stage 1/3. newUserId=" + newUserId + + " currentUserId=" + mSettings.getCurrentUserId()); + mSettings.setCurrentUserId(newUserId); updateCurrentProfileIds(); // InputMethodFileManager should be reset when the user is changed mFileManager = new InputMethodFileManager(mMethodMap, newUserId); final String defaultImiId = mSettings.getSelectedInputMethod(); + + if (DEBUG) Slog.d(TAG, "Switching user stage 2/3. newUserId=" + newUserId + + " defaultImiId=" + defaultImiId); + // For secondary users, the list of enabled IMEs may not have been updated since the // callbacks to PackageMonitor are ignored for the secondary user. Here, defaultImiId may // not be empty even if the IME has been uninstalled by the primary user. // Even in such cases, IMMS works fine because it will find the most applicable // IME for that user. final boolean initialUserSwitch = TextUtils.isEmpty(defaultImiId); - if (DEBUG) { - Slog.d(TAG, "Switch user: " + newUserId + " current ime = " + defaultImiId); - } resetAllInternalStateLocked(false /* updateOnlyWhenLocaleChanged */, initialUserSwitch /* needsToResetDefaultIme */); if (initialUserSwitch) { InputMethodUtils.setNonSelectedSystemImesDisabledUntilUsed(mContext.getPackageManager(), mSettings.getEnabledInputMethodListLocked()); } + + if (DEBUG) Slog.d(TAG, "Switching user stage 3/3. newUserId=" + newUserId + + " selectedIme=" + mSettings.getSelectedInputMethod()); } void updateCurrentProfileIds() { @@ -3706,6 +3713,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub p.println(" mCurUserActionNotificationSequenceNumber=" + mCurUserActionNotificationSequenceNumber); p.println(" mSystemReady=" + mSystemReady + " mInteractive=" + mScreenOn); + p.println(" mSwitchingController:"); + mSwitchingController.dump(p); } p.println(" "); diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index 3315c89..21f96c9 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -1785,7 +1785,13 @@ public class AccountManagerService // Get the calling package. We will use it for the purpose of caching. final String callerPkg = loginOptions.getString(AccountManager.KEY_ANDROID_PACKAGE_NAME); - List<String> callerOwnedPackageNames = Arrays.asList(mPackageManager.getPackagesForUid(callerUid)); + List<String> callerOwnedPackageNames; + long ident = Binder.clearCallingIdentity(); + try { + callerOwnedPackageNames = Arrays.asList(mPackageManager.getPackagesForUid(callerUid)); + } finally { + Binder.restoreCallingIdentity(ident); + } if (callerPkg == null || !callerOwnedPackageNames.contains(callerPkg)) { String msg = String.format( "Uid %s is attempting to illegally masquerade as package %s!", @@ -1798,15 +1804,15 @@ public class AccountManagerService loginOptions.putInt(AccountManager.KEY_CALLER_UID, callerUid); loginOptions.putInt(AccountManager.KEY_CALLER_PID, Binder.getCallingPid()); - // Distill the caller's package signatures into a single digest. - final byte[] callerPkgSigDigest = calculatePackageSignatureDigest(callerPkg); - if (notifyOnAuthFailure) { loginOptions.putBoolean(AccountManager.KEY_NOTIFY_ON_FAILURE, true); } long identityToken = clearCallingIdentity(); try { + // Distill the caller's package signatures into a single digest. + final byte[] callerPkgSigDigest = calculatePackageSignatureDigest(callerPkg); + // if the caller has permission, do the peek. otherwise go the more expensive // route of starting a Session if (!customTokens && permissionGranted) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 81b8457..64e30e5 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -39,13 +39,13 @@ import static org.xmlpull.v1.XmlPullParser.START_TAG; import android.Manifest; import android.app.AppOpsManager; import android.app.ApplicationThreadNative; -import android.app.AssistContent; -import android.app.AssistStructure; import android.app.IActivityContainer; import android.app.IActivityContainerCallback; import android.app.IAppTask; import android.app.ITaskStackListener; import android.app.ProfilerInfo; +import android.app.assist.AssistContent; +import android.app.assist.AssistStructure; import android.app.usage.UsageEvents; import android.app.usage.UsageStatsManagerInternal; import android.appwidget.AppWidgetManager; diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java index 745cb7e..80b8a93 100644 --- a/services/core/java/com/android/server/am/BroadcastQueue.java +++ b/services/core/java/com/android/server/am/BroadcastQueue.java @@ -1121,25 +1121,23 @@ public final class BroadcastQueue { } final void logBroadcastReceiverDiscardLocked(BroadcastRecord r) { - if (r.nextReceiver > 0) { - Object curReceiver = r.receivers.get(r.nextReceiver-1); + final int logIndex = r.nextReceiver - 1; + if (logIndex >= 0 && logIndex < r.receivers.size()) { + Object curReceiver = r.receivers.get(logIndex); if (curReceiver instanceof BroadcastFilter) { BroadcastFilter bf = (BroadcastFilter) curReceiver; EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_FILTER, bf.owningUserId, System.identityHashCode(r), - r.intent.getAction(), - r.nextReceiver - 1, - System.identityHashCode(bf)); + r.intent.getAction(), logIndex, System.identityHashCode(bf)); } else { - ResolveInfo ri = (ResolveInfo)curReceiver; + ResolveInfo ri = (ResolveInfo) curReceiver; EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, UserHandle.getUserId(ri.activityInfo.applicationInfo.uid), - System.identityHashCode(r), r.intent.getAction(), - r.nextReceiver - 1, ri.toString()); + System.identityHashCode(r), r.intent.getAction(), logIndex, ri.toString()); } } else { - Slog.w(TAG, "Discarding broadcast before first receiver is invoked: " - + r); + if (logIndex < 0) Slog.w(TAG, + "Discarding broadcast before first receiver is invoked: " + r); EventLog.writeEvent(EventLogTags.AM_BROADCAST_DISCARD_APP, -1, System.identityHashCode(r), r.intent.getAction(), diff --git a/services/core/java/com/android/server/am/TaskPersister.java b/services/core/java/com/android/server/am/TaskPersister.java index ef1559a..aa154a7 100644 --- a/services/core/java/com/android/server/am/TaskPersister.java +++ b/services/core/java/com/android/server/am/TaskPersister.java @@ -33,6 +33,7 @@ import android.util.AtomicFile; import android.util.Slog; import android.util.SparseArray; import android.util.Xml; +import android.os.Process; import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.XmlUtils; @@ -471,6 +472,7 @@ public class TaskPersister { @Override public void run() { + Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); ArraySet<Integer> persistentTaskIds = new ArraySet<Integer>(); while (true) { // We can't lock mService while holding TaskPersister.this, but we don't want to diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index bf896a5..fc50e2c 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -32,6 +32,7 @@ import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Handler; import android.os.Message; +import android.os.Process; import android.os.SystemClock; import android.os.SystemProperties; import android.os.UserHandle; @@ -48,6 +49,7 @@ import android.telephony.CellInfoWcdma; import android.telephony.TelephonyManager; import android.util.Log; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Protocol; import com.android.internal.util.State; import com.android.internal.util.StateMachine; @@ -177,8 +179,8 @@ public class NetworkMonitor extends StateMachine { private static final int CMD_LAUNCH_CAPTIVE_PORTAL_APP = BASE + 11; private static final String LINGER_DELAY_PROPERTY = "persist.netmon.linger"; - // Default to 30s linger time-out. - private static final int DEFAULT_LINGER_DELAY_MS = 30000; + // Default to 30s linger time-out. Modifyable only for testing. + private static int DEFAULT_LINGER_DELAY_MS = 30000; private final int mLingerDelayMs; private int mLingerToken = 0; @@ -771,4 +773,13 @@ public class NetworkMonitor extends StateMachine { mContext.sendBroadcastAsUser(latencyBroadcast, UserHandle.CURRENT, PERMISSION_ACCESS_NETWORK_CONDITIONS); } + + // Allow tests to override linger time. + @VisibleForTesting + public static void SetDefaultLingerTime(int time_ms) { + if (Process.myUid() == Process.SYSTEM_UID) { + throw new SecurityException("SetDefaultLingerTime only for internal testing."); + } + DEFAULT_LINGER_DELAY_MS = time_ms; + } } diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index dcf668d..1cec750 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -52,6 +52,7 @@ import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.RemoteException; +import android.os.SELinux; import android.os.UserHandle; import android.system.ErrnoException; import android.system.Os; @@ -77,6 +78,7 @@ import java.io.File; import java.io.FileDescriptor; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; @@ -163,6 +165,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { private final List<File> mResolvedStagedFiles = new ArrayList<>(); @GuardedBy("mLock") private final List<File> mResolvedInheritedFiles = new ArrayList<>(); + @GuardedBy("mLock") + private File mInheritedFilesBase; private final Handler.Callback mHandlerCallback = new Handler.Callback() { @Override @@ -511,8 +515,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { final List<File> fromFiles = mResolvedInheritedFiles; final File toDir = resolveStageDir(); + if (LOGD) Slog.d(TAG, "Inherited files: " + mResolvedInheritedFiles); + if (!mResolvedInheritedFiles.isEmpty() && mInheritedFilesBase == null) { + throw new IllegalStateException("mInheritedFilesBase == null"); + } + if (isLinkPossible(fromFiles, toDir)) { - linkFiles(fromFiles, toDir); + createDirsAndLinkFiles(fromFiles, toDir, mInheritedFilesBase); } else { // TODO: this should delegate to DCS so the system process // avoids holding open FDs into containers. @@ -690,6 +699,31 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } } } + + // Inherit compiled oat directory. + final File packageInstallDir = (new File(app.getBaseCodePath())).getParentFile(); + mInheritedFilesBase = packageInstallDir; + final File oatDir = new File(packageInstallDir, "oat"); + if (oatDir.exists()) { + final File[] archSubdirs = oatDir.listFiles(); + // Only add "oatDir" if it contains arch specific subdirs. + if (archSubdirs != null && archSubdirs.length > 0) { + mResolvedInheritedFiles.add(oatDir); + } + final String[] instructionSets = InstructionSets.getAllDexCodeInstructionSets(); + for (File archSubDir : archSubdirs) { + // Skip any directory that isn't an ISA subdir. + if (!ArrayUtils.contains(instructionSets, archSubDir.getName())) { + continue; + } + + List<File> oatFiles = Arrays.asList(archSubDir.listFiles()); + if (!oatFiles.isEmpty()) { + mResolvedInheritedFiles.add(archSubDir); + mResolvedInheritedFiles.addAll(oatFiles); + } + } + } } } @@ -768,14 +802,69 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { return true; } - private static void linkFiles(List<File> fromFiles, File toDir) throws IOException { + /** + * Reparents the path of {@code file} from {@code oldBase} to {@code newBase}. {@code file} + * must necessarily be a subpath of {@code oldBase}. It is an error for {@code file} to have + * relative path components such as {@code "."} or {@code ".."}. For example, for we will + * reparent {@code /foo/bar/baz} to {@code /foo2/bar/baz} if {@code oldBase} was {@code /foo} + * and {@code newBase} was {@code /foo2}. + */ + private static File reparentPath(File file, File oldBase, File newBase) throws IOException { + final String oldBaseStr = oldBase.getAbsolutePath(); + final String pathStr = file.getAbsolutePath(); + + // Don't allow relative paths. + if (pathStr.contains("/.") ) { + throw new IOException("Invalid path (was relative) : " + pathStr); + } + + if (pathStr.startsWith(oldBaseStr)) { + final String relative = pathStr.substring(oldBaseStr.length()); + return new File(newBase, relative); + } + + throw new IOException("File: " + pathStr + " outside base: " + oldBaseStr); + } + + /** + * Recreates a directory and file structure, specified by a list of files {@code fromFiles} + * which are subpaths of {@code fromDir} to {@code toDir}. Directories are created with the + * same permissions, and regular files are linked. + * + * TODO: Move this function to installd so that the system process doesn't have to + * manipulate / relabel directories. + */ + private static void createDirsAndLinkFiles(List<File> fromFiles, File toDir, File fromDir) + throws IOException { for (File fromFile : fromFiles) { - final File toFile = new File(toDir, fromFile.getName()); + final File toFile = reparentPath(fromFile, fromDir, toDir); + final StructStat stat; try { - if (LOGD) Slog.d(TAG, "Linking " + fromFile + " to " + toFile); - Os.link(fromFile.getAbsolutePath(), toFile.getAbsolutePath()); + stat = Os.stat(fromFile.getAbsolutePath()); } catch (ErrnoException e) { - throw new IOException("Failed to link " + fromFile + " to " + toFile, e); + throw new IOException("Failed to stat: " + fromFile.getAbsolutePath(), e); + } + + if (OsConstants.S_ISDIR(stat.st_mode)) { + if (LOGD) Slog.d(TAG, "Creating directory " + toFile.getAbsolutePath()); + try { + Os.mkdir(toFile.getAbsolutePath(), stat.st_mode); + } catch (ErrnoException e) { + throw new IOException("Failed to create dir: " + toFile.getAbsolutePath(), e); + } + + // We do this to ensure that the oat/ directory is created with the right + // label (data_dalvikcache_file) instead of apk_tmpfile. + if (!SELinux.restorecon(toFile)) { + throw new IOException("Failed to restorecon: " + toFile.getAbsolutePath()); + } + } else { + if (LOGD) Slog.d(TAG, "Linking " + fromFile + " to " + toFile); + try { + Os.link(fromFile.getAbsolutePath(), toFile.getAbsolutePath()); + } catch (ErrnoException e) { + throw new IOException("Failed to link " + fromFile + " to " + toFile, e); + } } } Slog.d(TAG, "Linked " + fromFiles.size() + " files into " + toDir); diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 47e3963..7dfe836 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -11504,7 +11504,7 @@ public class PackageManagerService extends IPackageManager.Stub { final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0) || (args.volumeUuid != null)); boolean replace = false; - int scanFlags = SCAN_NEW_INSTALL | SCAN_FORCE_DEX | SCAN_UPDATE_SIGNATURE; + int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE; // Result object to be returned res.returnCode = PackageManager.INSTALL_SUCCEEDED; @@ -11705,7 +11705,7 @@ public class PackageManagerService extends IPackageManager.Stub { // Run dexopt before old package gets removed, to minimize time when app is unavailable int result = mPackageDexOptimizer - .performDexOpt(pkg, null /* instruction sets */, true /* forceDex */, + .performDexOpt(pkg, null /* instruction sets */, false /* forceDex */, false /* defer */, false /* inclDependencies */); if (result == PackageDexOptimizer.DEX_OPT_FAILED) { res.setError(INSTALL_FAILED_DEXOPT, "Dexopt failed for " + pkg.codePath); diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index b8d0692..46793b9 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -1087,16 +1087,19 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } - private void sleepPress(KeyEvent event) { + private void sleepPress(long eventTime) { + if (mShortPressOnSleepBehavior == SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME) { + launchHomeFromHotKey(false /* awakenDreams */, true /*respectKeyguard*/); + } + } + + private void sleepRelease(long eventTime) { switch (mShortPressOnSleepBehavior) { case SHORT_PRESS_SLEEP_GO_TO_SLEEP: - mPowerManager.goToSleep(event.getEventTime(), - PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0); - break; case SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME: - launchHomeFromHotKey(false /* awakenDreams */, true /*respectKeyguard*/); - mPowerManager.goToSleep(event.getEventTime(), - PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0); + Slog.i(TAG, "sleepRelease() calling goToSleep(GO_TO_SLEEP_REASON_SLEEP_BUTTON)"); + mPowerManager.goToSleep(eventTime, + PowerManager.GO_TO_SLEEP_REASON_SLEEP_BUTTON, 0); break; } } @@ -2116,7 +2119,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { case TYPE_KEYGUARD_SCRIM: return false; default: - return true; + // Hide only windows below the keyguard host window. + return windowTypeToLayerLw(win.getBaseType()) + < windowTypeToLayerLw(TYPE_STATUS_BAR); } } @@ -4903,7 +4908,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (!mPowerManager.isInteractive()) { useHapticFeedback = false; // suppress feedback if already non-interactive } - sleepPress(event); + if (down) { + sleepPress(event.getEventTime()); + } else { + sleepRelease(event.getEventTime()); + } break; } @@ -5517,6 +5526,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { /** {@inheritDoc} */ @Override + public boolean isKeyguardShowingOrOccluded() { + return mKeyguardDelegate == null ? false : mKeyguardDelegate.isShowing(); + } + + /** {@inheritDoc} */ + @Override public boolean inKeyguardRestrictedKeyInputMode() { if (mKeyguardDelegate == null) return false; return mKeyguardDelegate.isInputRestricted(); diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java index 01c110f..f1f9c50 100644 --- a/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java +++ b/services/core/java/com/android/server/policy/keyguard/KeyguardStateMonitor.java @@ -36,10 +36,11 @@ public class KeyguardStateMonitor extends IKeyguardStateCallback.Stub { // Keyguard changes its state, it always triggers a layout in window manager. Because // IKeyguardStateCallback is synchronous and because these states are declared volatile, it's // guaranteed that window manager picks up the new state all the time in the layout caused by - // the state change of Keyguard. - private volatile boolean mIsShowing; - private volatile boolean mSimSecure; - private volatile boolean mInputRestricted; + // the state change of Keyguard. To be extra safe, assume most restrictive values until Keyguard + // tells us the actual value. + private volatile boolean mIsShowing = true; + private volatile boolean mSimSecure = true; + private volatile boolean mInputRestricted = true; private int mCurrentUserId; diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 9169351..3305e1e 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -191,7 +191,8 @@ public class WindowAnimator { private boolean shouldForceHide(WindowState win) { final WindowState imeTarget = mService.mInputMethodTarget; final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleNow() && - (imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0; + ((imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0 + || !mPolicy.canBeForceHidden(imeTarget, imeTarget.mAttrs)); final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw(); final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ? @@ -203,7 +204,11 @@ public class WindowAnimator { || (win.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0 && win.isAnimatingLw() // Show error dialogs over apps that dismiss keyguard. || (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0))); - return (mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked; + + // Only hide windows if the keyguard is active and not animating away. + boolean keyguardOn = mPolicy.isKeyguardShowingOrOccluded() + && mForceHiding != KEYGUARD_ANIMATING_OUT; + return keyguardOn && hideWhenLocked; } private void updateWindowsLocked(final int displayId) { @@ -228,6 +233,7 @@ public class WindowAnimator { winAnimator.mAnimation.setDuration(KEYGUARD_ANIM_TIMEOUT_MS); winAnimator.mAnimationIsEntrance = false; winAnimator.mAnimationStartTime = -1; + winAnimator.mKeyguardGoingAwayAnimation = true; } } else { if (DEBUG_KEYGUARD) Slog.d(TAG, @@ -310,7 +316,7 @@ public class WindowAnimator { mKeyguardGoingAway = false; } if (win.isReadyForDisplay()) { - if (nowAnimating) { + if (nowAnimating && win.mWinAnimator.mKeyguardGoingAwayAnimation) { mForceHiding = KEYGUARD_ANIMATING_OUT; } else { mForceHiding = win.isDrawnLw() ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN; diff --git a/services/net/java/android/net/dhcp/DhcpAckPacket.java b/services/net/java/android/net/dhcp/DhcpAckPacket.java index c0e1d19..334f708 100644 --- a/services/net/java/android/net/dhcp/DhcpAckPacket.java +++ b/services/net/java/android/net/dhcp/DhcpAckPacket.java @@ -30,8 +30,8 @@ class DhcpAckPacket extends DhcpPacket { private final Inet4Address mSrcIp; DhcpAckPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress, - Inet4Address clientIp, byte[] clientMac) { - super(transId, secs, INADDR_ANY, clientIp, serverAddress, INADDR_ANY, clientMac, broadcast); + Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) { + super(transId, secs, clientIp, yourIp, serverAddress, INADDR_ANY, clientMac, broadcast); mBroadcast = broadcast; mSrcIp = serverAddress; } diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java index d8d74e2..575a300 100644 --- a/services/net/java/android/net/dhcp/DhcpClient.java +++ b/services/net/java/android/net/dhcp/DhcpClient.java @@ -58,7 +58,7 @@ import java.nio.ByteBuffer; import java.util.Arrays; import java.util.Random; -import libcore.io.IoUtils; +import libcore.io.IoBridge; import static android.system.OsConstants.*; import static android.net.dhcp.DhcpPacket.*; @@ -297,9 +297,15 @@ public class DhcpClient extends BaseDhcpStateMachine { return true; } + private static void closeQuietly(FileDescriptor fd) { + try { + IoBridge.closeAndSignalBlockedThreads(fd); + } catch (IOException ignored) {} + } + private void closeSockets() { - IoUtils.closeQuietly(mUdpSock); - IoUtils.closeQuietly(mPacketSock); + closeQuietly(mUdpSock); + closeQuietly(mPacketSock); } private boolean setIpAddress(LinkAddress address) { @@ -326,7 +332,7 @@ public class DhcpClient extends BaseDhcpStateMachine { @Override public void run() { - maybeLog("Starting receive thread"); + maybeLog("Receive thread started"); while (!stopped) { try { int length = Os.read(mPacketSock, mPacket, 0, mPacket.length); @@ -345,7 +351,7 @@ public class DhcpClient extends BaseDhcpStateMachine { } } } - maybeLog("Stopping receive thread"); + maybeLog("Receive thread stopped"); } } @@ -463,6 +469,8 @@ public class DhcpClient extends BaseDhcpStateMachine { return "CMD_KICK"; case CMD_RECEIVED_PACKET: return "CMD_RECEIVED_PACKET"; + case CMD_TIMEOUT: + return "CMD_TIMEOUT"; default: return Integer.toString(what); } @@ -601,12 +609,15 @@ public class DhcpClient extends BaseDhcpStateMachine { /** * Retransmits packets using jittered exponential backoff with an optional timeout. Packet - * transmission is triggered by CMD_KICK, which is sent by an AlarmManager alarm. + * transmission is triggered by CMD_KICK, which is sent by an AlarmManager alarm. If a subclass + * sets mTimeout to a positive value, then timeout() is called by an AlarmManager alarm mTimeout + * milliseconds after entering the state. Kicks and timeouts are cancelled when leaving the + * state. * * Concrete subclasses must implement sendPacket, which is called when the alarm fires and a * packet needs to be transmitted, and receivePacket, which is triggered by CMD_RECEIVED_PACKET - * sent by the receive thread. They may implement timeout, which is called when the timeout - * fires. + * sent by the receive thread. They may also set mTimeout and if desired override the default + * timeout implementation. */ abstract class PacketRetransmittingState extends LoggingState { @@ -647,7 +658,19 @@ public class DhcpClient extends BaseDhcpStateMachine { abstract protected boolean sendPacket(); abstract protected void receivePacket(DhcpPacket packet); - protected void timeout() {} + + // Default implementation of timeout. This is only invoked if mTimeout > 0, so it will never + // be called if the subclass does not set a timeout. + protected void timeout() { + maybeLog("Timeout in " + getName()); + notifyFailure(); + if (this != mDhcpInitState) { + // Only transition to INIT if we're not already there. Otherwise, we'll exit the + // state and re-enter it, which will reset the packet transmission interval, re-set + // the timeout, etc. + transitionTo(mDhcpInitState); + } + } protected void initTimer() { mTimer = FIRST_TIMEOUT_MS; @@ -696,11 +719,6 @@ public class DhcpClient extends BaseDhcpStateMachine { return sendDiscoverPacket(); } - protected void timeout() { - maybeLog("Timeout"); - notifyFailure(); - } - protected void receivePacket(DhcpPacket packet) { if (!isValidPacket(packet)) return; if (!(packet instanceof DhcpOfferPacket)) return; @@ -747,11 +765,6 @@ public class DhcpClient extends BaseDhcpStateMachine { transitionTo(mDhcpInitState); } } - - protected void timeout() { - notifyFailure(); - transitionTo(mDhcpInitState); - } } class DhcpHaveAddressState extends LoggingState { @@ -760,6 +773,8 @@ public class DhcpClient extends BaseDhcpStateMachine { super.enter(); if (!setIpAddress(mDhcpLease.ipAddress)) { notifyFailure(); + // There's likely no point in going into DhcpInitState here, we'll probably just + // repeat the transaction, get the same IP address as before, and fail. transitionTo(mStoppedState); } } @@ -797,7 +812,6 @@ public class DhcpClient extends BaseDhcpStateMachine { } } - // TODO: timeout. class DhcpRenewingState extends PacketRetransmittingState { public DhcpRenewingState() { super(); diff --git a/services/net/java/android/net/dhcp/DhcpOfferPacket.java b/services/net/java/android/net/dhcp/DhcpOfferPacket.java index af41708..7ca7100 100644 --- a/services/net/java/android/net/dhcp/DhcpOfferPacket.java +++ b/services/net/java/android/net/dhcp/DhcpOfferPacket.java @@ -32,8 +32,8 @@ class DhcpOfferPacket extends DhcpPacket { * Generates a OFFER packet with the specified parameters. */ DhcpOfferPacket(int transId, short secs, boolean broadcast, Inet4Address serverAddress, - Inet4Address clientIp, byte[] clientMac) { - super(transId, secs, INADDR_ANY, clientIp, INADDR_ANY, INADDR_ANY, clientMac, broadcast); + Inet4Address clientIp, Inet4Address yourIp, byte[] clientMac) { + super(transId, secs, clientIp, yourIp, INADDR_ANY, INADDR_ANY, clientMac, broadcast); mSrcIp = serverAddress; } diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java index 2a25d30..d42404b 100644 --- a/services/net/java/android/net/dhcp/DhcpPacket.java +++ b/services/net/java/android/net/dhcp/DhcpPacket.java @@ -919,7 +919,7 @@ abstract class DhcpPacket { break; case DHCP_MESSAGE_TYPE_OFFER: newPacket = new DhcpOfferPacket( - transactionId, secs, broadcast, ipSrc, yourIp, clientMac); + transactionId, secs, broadcast, ipSrc, clientIp, yourIp, clientMac); break; case DHCP_MESSAGE_TYPE_REQUEST: newPacket = new DhcpRequestPacket( @@ -932,7 +932,7 @@ abstract class DhcpPacket { break; case DHCP_MESSAGE_TYPE_ACK: newPacket = new DhcpAckPacket( - transactionId, secs, broadcast, ipSrc, yourIp, clientMac); + transactionId, secs, broadcast, ipSrc, clientIp, yourIp, clientMac); break; case DHCP_MESSAGE_TYPE_NAK: newPacket = new DhcpNakPacket( @@ -982,9 +982,9 @@ abstract class DhcpPacket { */ public DhcpResults toDhcpResults() { Inet4Address ipAddress = mYourIp; - if (ipAddress == Inet4Address.ANY) { + if (ipAddress.equals(Inet4Address.ANY)) { ipAddress = mClientIp; - if (ipAddress == Inet4Address.ANY) { + if (ipAddress.equals(Inet4Address.ANY)) { return null; } } @@ -1052,7 +1052,7 @@ abstract class DhcpPacket { Inet4Address gateway, List<Inet4Address> dnsServers, Inet4Address dhcpServerIdentifier, String domainName) { DhcpPacket pkt = new DhcpOfferPacket( - transactionId, (short) 0, broadcast, serverIpAddr, clientIpAddr, mac); + transactionId, (short) 0, broadcast, serverIpAddr, INADDR_ANY, clientIpAddr, mac); pkt.mGateway = gateway; pkt.mDnsServers = dnsServers; pkt.mLeaseTime = timeout; @@ -1072,7 +1072,7 @@ abstract class DhcpPacket { Inet4Address gateway, List<Inet4Address> dnsServers, Inet4Address dhcpServerIdentifier, String domainName) { DhcpPacket pkt = new DhcpAckPacket( - transactionId, (short) 0, broadcast, serverIpAddr, clientIpAddr, mac); + transactionId, (short) 0, broadcast, serverIpAddr, INADDR_ANY, clientIpAddr, mac); pkt.mGateway = gateway; pkt.mDnsServers = dnsServers; pkt.mLeaseTime = timeout; diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml index 636dd4d..919293a 100644 --- a/services/tests/servicestests/AndroidManifest.xml +++ b/services/tests/servicestests/AndroidManifest.xml @@ -36,6 +36,9 @@ <uses-permission android:name="android.permission.MANAGE_USERS" /> <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" /> <uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" /> + <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" /> + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <application> <uses-library android:name="android.test.runner" /> diff --git a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java index f116042..e0e3fcf 100644 --- a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java +++ b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java @@ -18,6 +18,7 @@ package android.net.dhcp; import android.net.NetworkUtils; import android.net.DhcpResults; +import android.net.LinkAddress; import android.system.OsConstants; import android.test.suitebuilder.annotation.SmallTest; import junit.framework.TestCase; @@ -34,19 +35,27 @@ public class DhcpPacketTest extends TestCase { (Inet4Address) NetworkUtils.numericToInetAddress("192.0.2.1"); private static Inet4Address CLIENT_ADDR = (Inet4Address) NetworkUtils.numericToInetAddress("192.0.2.234"); + // Use our own empty address instead of Inet4Address.ANY or INADDR_ANY to ensure that the code + // doesn't use == instead of equals when comparing addresses. + private static Inet4Address ANY = (Inet4Address) NetworkUtils.numericToInetAddress("0.0.0.0"); + private static byte[] CLIENT_MAC = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; class TestDhcpPacket extends DhcpPacket { private byte mType; // TODO: Make this a map of option numbers to bytes instead. - private byte[] mDomainBytes, mVendorInfoBytes, mLeaseTimeBytes; + private byte[] mDomainBytes, mVendorInfoBytes, mLeaseTimeBytes, mNetmaskBytes; - public TestDhcpPacket(byte type) { - super(0xdeadbeef, (short) 0, INADDR_ANY, CLIENT_ADDR, INADDR_ANY, INADDR_ANY, + public TestDhcpPacket(byte type, Inet4Address clientIp, Inet4Address yourIp) { + super(0xdeadbeef, (short) 0, clientIp, yourIp, INADDR_ANY, INADDR_ANY, CLIENT_MAC, true); mType = type; } + public TestDhcpPacket(byte type) { + this(type, INADDR_ANY, CLIENT_ADDR); + } + public TestDhcpPacket setDomainBytes(byte[] domainBytes) { mDomainBytes = domainBytes; return this; @@ -62,6 +71,11 @@ public class DhcpPacketTest extends TestCase { return this; } + public TestDhcpPacket setNetmaskBytes(byte[] netmaskBytes) { + mNetmaskBytes = netmaskBytes; + return this; + } + public ByteBuffer buildPacket(int encap, short unusedDestUdp, short unusedSrcUdp) { ByteBuffer result = ByteBuffer.allocate(MAX_LENGTH); fillInPacket(encap, CLIENT_ADDR, SERVER_ADDR, @@ -80,6 +94,9 @@ public class DhcpPacketTest extends TestCase { if (mLeaseTimeBytes != null) { addTlv(buffer, DHCP_LEASE_TIME, mLeaseTimeBytes); } + if (mNetmaskBytes != null) { + addTlv(buffer, DHCP_SUBNET_MASK, mNetmaskBytes); + } addTlvEnd(buffer); } @@ -175,4 +192,50 @@ public class DhcpPacketTest extends TestCase { assertLeaseTimeParses(true, -2147483647, 2147483649L * 1000, maxIntPlusOneLease); assertLeaseTimeParses(true, DhcpPacket.INFINITE_LEASE, 0, infiniteLease); } + + private void checkIpAddress(String expected, Inet4Address clientIp, Inet4Address yourIp, + byte[] netmaskBytes) { + checkIpAddress(expected, DHCP_MESSAGE_TYPE_OFFER, clientIp, yourIp, netmaskBytes); + checkIpAddress(expected, DHCP_MESSAGE_TYPE_ACK, clientIp, yourIp, netmaskBytes); + } + + private void checkIpAddress(String expected, byte type, + Inet4Address clientIp, Inet4Address yourIp, + byte[] netmaskBytes) { + ByteBuffer packet = new TestDhcpPacket(type, clientIp, yourIp) + .setNetmaskBytes(netmaskBytes) + .build(); + DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP); + DhcpResults results = offerPacket.toDhcpResults(); + + if (expected != null) { + LinkAddress expectedAddress = new LinkAddress(expected); + assertEquals(expectedAddress, results.ipAddress); + } else { + assertNull(results); + } + } + + @SmallTest + public void testIpAddress() throws Exception { + byte[] slash11Netmask = new byte[] { (byte) 0xff, (byte) 0xe0, 0x00, 0x00 }; + byte[] slash24Netmask = new byte[] { (byte) 0xff, (byte) 0xff, (byte) 0xff, 0x00 }; + byte[] invalidNetmask = new byte[] { (byte) 0xff, (byte) 0xfb, (byte) 0xff, 0x00 }; + Inet4Address example1 = (Inet4Address) NetworkUtils.numericToInetAddress("192.0.2.1"); + Inet4Address example2 = (Inet4Address) NetworkUtils.numericToInetAddress("192.0.2.43"); + + // A packet without any addresses is not valid. + checkIpAddress(null, ANY, ANY, slash24Netmask); + + // ClientIP is used iff YourIP is not present. + checkIpAddress("192.0.2.1/24", example2, example1, slash24Netmask); + checkIpAddress("192.0.2.43/11", example2, ANY, slash11Netmask); + checkIpAddress("192.0.2.43/11", ANY, example2, slash11Netmask); + + // Invalid netmasks are ignored. + checkIpAddress(null, example2, ANY, invalidNetmask); + + // If there is no netmask, implicit netmasks are used. + checkIpAddress("192.0.2.43/24", ANY, example2, null); + } } diff --git a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java index 48d8ffb..56f1d48c 100644 --- a/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java @@ -20,6 +20,10 @@ import static android.net.ConnectivityManager.CONNECTIVITY_ACTION; import static android.net.ConnectivityManager.TYPE_MOBILE; import static android.net.ConnectivityManager.TYPE_WIFI; import static android.net.ConnectivityManager.getNetworkTypeName; +import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET; +import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED; +import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR; +import static android.net.NetworkCapabilities.TRANSPORT_WIFI; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isA; @@ -30,21 +34,36 @@ import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; +import android.content.BroadcastReceiver; import android.content.Context; +import android.content.ContextWrapper; +import android.content.Intent; +import android.content.IntentFilter; +import android.net.ConnectivityManager; +import android.net.ConnectivityManager.NetworkCallback; import android.net.INetworkPolicyManager; import android.net.INetworkStatsService; import android.net.LinkProperties; +import android.net.Network; +import android.net.NetworkAgent; +import android.net.NetworkCapabilities; import android.net.NetworkConfig; import android.net.NetworkInfo; import android.net.NetworkInfo.DetailedState; +import android.net.NetworkMisc; +import android.net.NetworkRequest; import android.net.RouteInfo; +import android.os.ConditionVariable; import android.os.Handler; +import android.os.Looper; import android.os.INetworkManagementService; import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.LargeTest; import android.util.Log; import android.util.LogPrinter; +import com.android.server.connectivity.NetworkMonitor; + import org.mockito.ArgumentCaptor; import java.net.InetAddress; @@ -52,8 +71,10 @@ import java.util.concurrent.Future; /** * Tests for {@link ConnectivityService}. + * + * Build, install and run with: + * runtest frameworks-services -c com.android.server.ConnectivityServiceTest */ -@LargeTest public class ConnectivityServiceTest extends AndroidTestCase { private static final String TAG = "ConnectivityServiceTest"; @@ -75,73 +96,336 @@ public class ConnectivityServiceTest extends AndroidTestCase { private INetworkManagementService mNetManager; private INetworkStatsService mStatsService; private INetworkPolicyManager mPolicyService; -// private ConnectivityService.NetworkFactory mNetFactory; private BroadcastInterceptingContext mServiceContext; private ConnectivityService mService; + private ConnectivityManager mCm; + private MockNetworkAgent mWiFiNetworkAgent; + private MockNetworkAgent mCellNetworkAgent; + + private class MockContext extends BroadcastInterceptingContext { + MockContext(Context base) { + super(base); + } + + @Override + public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { + // PendingIntents sent by the AlarmManager are not intercepted by + // BroadcastInterceptingContext so we must really register the receiver. + // This shouldn't effect the real NetworkMonitors as the action contains a random token. + if (filter.getAction(0).startsWith("android.net.netmon.lingerExpired")) { + return getBaseContext().registerReceiver(receiver, filter); + } else { + return super.registerReceiver(receiver, filter); + } + } + + @Override + public Object getSystemService (String name) { + if (name == Context.CONNECTIVITY_SERVICE) return mCm; + return super.getSystemService(name); + } + } + + private class MockNetworkAgent { + private final NetworkInfo mNetworkInfo; + private final NetworkCapabilities mNetworkCapabilities; + private final Thread mThread; + private NetworkAgent mNetworkAgent; + + MockNetworkAgent(int transport) { + final int type = transportToLegacyType(transport); + final String typeName = ConnectivityManager.getNetworkTypeName(type); + mNetworkInfo = new NetworkInfo(type, 0, typeName, "Mock"); + mNetworkCapabilities = new NetworkCapabilities(); + mNetworkCapabilities.addTransportType(transport); + final int score; + switch (transport) { + case TRANSPORT_WIFI: + score = 60; + break; + case TRANSPORT_CELLULAR: + score = 50; + break; + default: + throw new UnsupportedOperationException("unimplemented network type"); + } + final ConditionVariable initComplete = new ConditionVariable(); + mThread = new Thread() { + public void run() { + Looper.prepare(); + mNetworkAgent = new NetworkAgent(Looper.myLooper(), mServiceContext, + "Mock" + typeName, mNetworkInfo, mNetworkCapabilities, + new LinkProperties(), score, new NetworkMisc()) { + public void unwanted() {} + }; + initComplete.open(); + Looper.loop(); + } + }; + mThread.start(); + initComplete.block(); + } + + /** + * Transition this NetworkAgent to CONNECTED state. + * @param validated Indicate if network should pretend to be validated. + */ + public void connect(boolean validated) { + assertEquals(mNetworkInfo.getDetailedState(), DetailedState.IDLE); + assertFalse(mNetworkCapabilities.hasCapability(NET_CAPABILITY_INTERNET)); + + // To pretend network is validated, we transition it to the CONNECTED state without + // NET_CAPABILITY_INTERNET so NetworkMonitor doesn't bother trying to validate and + // just rubber stamps it as validated. Afterwards we add NET_CAPABILITY_INTERNET so + // the network can satisfy the default request. + NetworkCallback callback = null; + final ConditionVariable validatedCv = new ConditionVariable(); + if (validated) { + // If we connect a network without INTERNET capability, it'll get reaped. + // Prevent the reaping by adding a NetworkRequest. + NetworkRequest request = new NetworkRequest.Builder() + .addTransportType(mNetworkCapabilities.getTransportTypes()[0]) + .build(); + callback = new NetworkCallback() { + public void onCapabilitiesChanged(Network network, + NetworkCapabilities networkCapabilities) { + if (networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED)) { + validatedCv.open(); + } + } + }; + mCm.requestNetwork(request, callback); + } else { + mNetworkCapabilities.addCapability(NET_CAPABILITY_INTERNET); + mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); + } + + mNetworkInfo.setDetailedState(DetailedState.CONNECTED, null, null); + mNetworkAgent.sendNetworkInfo(mNetworkInfo); + + if (validated) { + // Wait for network to validate. + validatedCv.block(); + mNetworkCapabilities.addCapability(NET_CAPABILITY_INTERNET); + mNetworkAgent.sendNetworkCapabilities(mNetworkCapabilities); + } + + if (callback != null) mCm.unregisterNetworkCallback(callback); + } + + public void disconnect() { + mNetworkInfo.setDetailedState(DetailedState.DISCONNECTED, null, null); + mNetworkAgent.sendNetworkInfo(mNetworkInfo); + } + + public Network getNetwork() { + return new Network(mNetworkAgent.netId); + } + } + + private class WrappedConnectivityService extends ConnectivityService { + public WrappedConnectivityService(Context context, INetworkManagementService netManager, + INetworkStatsService statsService, INetworkPolicyManager policyManager) { + super(context, netManager, statsService, policyManager); + } + + @Override + protected int getDefaultTcpRwnd() { + // Prevent wrapped ConnectivityService from trying to write to SystemProperties. + return 0; + } + } + + @Override + public void setUp() throws Exception { + super.setUp(); + + mServiceContext = new MockContext(getContext()); + + mNetManager = mock(INetworkManagementService.class); + mStatsService = mock(INetworkStatsService.class); + mPolicyService = mock(INetworkPolicyManager.class); + + mService = new WrappedConnectivityService( + mServiceContext, mNetManager, mStatsService, mPolicyService); + mService.systemReady(); + mCm = new ConnectivityManager(mService); + } + + private int transportToLegacyType(int transport) { + switch (transport) { + case TRANSPORT_WIFI: + return TYPE_WIFI; + case TRANSPORT_CELLULAR: + return TYPE_MOBILE; + default: + throw new IllegalStateException("Unknown transport" + transport); + } + } + + private void verifyActiveNetwork(int transport) { + // Test getActiveNetworkInfo() + assertNotNull(mCm.getActiveNetworkInfo()); + assertEquals(transportToLegacyType(transport), mCm.getActiveNetworkInfo().getType()); + // Test getActiveNetwork() + assertNotNull(mCm.getActiveNetwork()); + switch (transport) { + case TRANSPORT_WIFI: + assertEquals(mCm.getActiveNetwork(), mWiFiNetworkAgent.getNetwork()); + break; + case TRANSPORT_CELLULAR: + assertEquals(mCm.getActiveNetwork(), mCellNetworkAgent.getNetwork()); + break; + default: + throw new IllegalStateException("Unknown transport" + transport); + } + // Test getNetworkInfo(Network) + assertNotNull(mCm.getNetworkInfo(mCm.getActiveNetwork())); + assertEquals(transportToLegacyType(transport), mCm.getNetworkInfo(mCm.getActiveNetwork()).getType()); + // Test getNetworkCapabilities(Network) + assertNotNull(mCm.getNetworkCapabilities(mCm.getActiveNetwork())); + assertTrue(mCm.getNetworkCapabilities(mCm.getActiveNetwork()).hasTransport(transport)); + } + + private void verifyNoNetwork() { + // Test getActiveNetworkInfo() + assertNull(mCm.getActiveNetworkInfo()); + // Test getActiveNetwork() + assertNull(mCm.getActiveNetwork()); + // Test getAllNetworks() + assertEquals(0, mCm.getAllNetworks().length); + } + + /** + * Return a ConditionVariable that opens when {@code count} numbers of CONNECTIVITY_ACTION + * broadcasts are received. + */ + private ConditionVariable waitForConnectivityBroadcasts(final int count) { + final ConditionVariable cv = new ConditionVariable(); + mServiceContext.registerReceiver(new BroadcastReceiver() { + private int remaining = count; + public void onReceive(Context context, Intent intent) { + if (--remaining == 0) { + cv.open(); + mServiceContext.unregisterReceiver(this); + } + } + }, new IntentFilter(CONNECTIVITY_ACTION)); + return cv; + } + + @LargeTest + public void testLingering() throws Exception { + // Decrease linger timeout to the minimum allowed by AlarmManagerService. + NetworkMonitor.SetDefaultLingerTime(5000); + verifyNoNetwork(); + mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + assertNull(mCm.getActiveNetworkInfo()); + assertNull(mCm.getActiveNetwork()); + // Test bringing up validated cellular. + ConditionVariable cv = waitForConnectivityBroadcasts(1); + mCellNetworkAgent.connect(true); + cv.block(); + verifyActiveNetwork(TRANSPORT_CELLULAR); + assertEquals(2, mCm.getAllNetworks().length); + assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) || + mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); + assertTrue(mCm.getAllNetworks()[0].equals(mWiFiNetworkAgent.getNetwork()) || + mCm.getAllNetworks()[1].equals(mWiFiNetworkAgent.getNetwork())); + // Test bringing up validated WiFi. + cv = waitForConnectivityBroadcasts(2); + mWiFiNetworkAgent.connect(true); + cv.block(); + verifyActiveNetwork(TRANSPORT_WIFI); + assertEquals(2, mCm.getAllNetworks().length); + assertTrue(mCm.getAllNetworks()[0].equals(mCm.getActiveNetwork()) || + mCm.getAllNetworks()[1].equals(mCm.getActiveNetwork())); + assertTrue(mCm.getAllNetworks()[0].equals(mCellNetworkAgent.getNetwork()) || + mCm.getAllNetworks()[1].equals(mCellNetworkAgent.getNetwork())); + // Test cellular linger timeout. + try { + Thread.sleep(6000); + } catch (Exception e) { + } + verifyActiveNetwork(TRANSPORT_WIFI); + assertEquals(1, mCm.getAllNetworks().length); + assertEquals(mCm.getAllNetworks()[0], mCm.getActiveNetwork()); + // Test WiFi disconnect. + cv = waitForConnectivityBroadcasts(1); + mWiFiNetworkAgent.disconnect(); + cv.block(); + verifyNoNetwork(); + } + + @LargeTest + public void testValidatedCellularOutscoresUnvalidatedWiFi() throws Exception { + // Test bringing up unvalidated WiFi + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + ConditionVariable cv = waitForConnectivityBroadcasts(1); + mWiFiNetworkAgent.connect(false); + cv.block(); + verifyActiveNetwork(TRANSPORT_WIFI); + // Test bringing up unvalidated cellular + mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); + mCellNetworkAgent.connect(false); + try { + Thread.sleep(1000); + } catch (Exception e) { + } + verifyActiveNetwork(TRANSPORT_WIFI); + // Test cellular disconnect. + mCellNetworkAgent.disconnect(); + try { + Thread.sleep(1000); + } catch (Exception e) { + } + verifyActiveNetwork(TRANSPORT_WIFI); + // Test bringing up validated cellular + mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); + cv = waitForConnectivityBroadcasts(2); + mCellNetworkAgent.connect(true); + cv.block(); + verifyActiveNetwork(TRANSPORT_CELLULAR); + // Test cellular disconnect. + cv = waitForConnectivityBroadcasts(2); + mCellNetworkAgent.disconnect(); + cv.block(); + verifyActiveNetwork(TRANSPORT_WIFI); + // Test WiFi disconnect. + cv = waitForConnectivityBroadcasts(1); + mWiFiNetworkAgent.disconnect(); + cv.block(); + verifyNoNetwork(); + } + + @LargeTest + public void testUnvalidatedWifiOutscoresUnvalidatedCellular() throws Exception { + // Test bringing up unvalidated cellular. + mCellNetworkAgent = new MockNetworkAgent(TRANSPORT_CELLULAR); + ConditionVariable cv = waitForConnectivityBroadcasts(1); + mCellNetworkAgent.connect(false); + cv.block(); + verifyActiveNetwork(TRANSPORT_CELLULAR); + // Test bringing up unvalidated WiFi. + mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); + cv = waitForConnectivityBroadcasts(2); + mWiFiNetworkAgent.connect(false); + cv.block(); + verifyActiveNetwork(TRANSPORT_WIFI); + // Test WiFi disconnect. + cv = waitForConnectivityBroadcasts(2); + mWiFiNetworkAgent.disconnect(); + cv.block(); + verifyActiveNetwork(TRANSPORT_CELLULAR); + // Test cellular disconnect. + cv = waitForConnectivityBroadcasts(1); + mCellNetworkAgent.disconnect(); + cv.block(); + verifyNoNetwork(); + } -// TODO: rework with network factory -// private MockNetwork mMobile; -// private MockNetwork mWifi; -// -// private Handler mTrackerHandler; -// -// private static class MockNetwork { -// public NetworkStateTracker tracker; -// public NetworkInfo info; -// public LinkProperties link; -// -// public MockNetwork(int type) { -// tracker = mock(NetworkStateTracker.class); -// info = new NetworkInfo(type, -1, getNetworkTypeName(type), null); -// link = new LinkProperties(); -// } -// -// public void doReturnDefaults() { -// // TODO: eventually CS should make defensive copies -// doReturn(new NetworkInfo(info)).when(tracker).getNetworkInfo(); -// doReturn(new LinkProperties(link)).when(tracker).getLinkProperties(); -// -// // fallback to default TCP buffers -// doReturn("").when(tracker).getTcpBufferSizesPropName(); -// } -// } -// -// @Override -// public void setUp() throws Exception { -// super.setUp(); -// -// mServiceContext = new BroadcastInterceptingContext(getContext()); -// -// mNetManager = mock(INetworkManagementService.class); -// mStatsService = mock(INetworkStatsService.class); -// mPolicyService = mock(INetworkPolicyManager.class); -// mNetFactory = mock(ConnectivityService.NetworkFactory.class); -// -// mMobile = new MockNetwork(TYPE_MOBILE); -// mWifi = new MockNetwork(TYPE_WIFI); -// -// // omit most network trackers -// doThrow(new IllegalArgumentException("Not supported in test environment")) -// .when(mNetFactory).createTracker(anyInt(), isA(NetworkConfig.class)); -// -// doReturn(mMobile.tracker) -// .when(mNetFactory).createTracker(eq(TYPE_MOBILE), isA(NetworkConfig.class)); -// doReturn(mWifi.tracker) -// .when(mNetFactory).createTracker(eq(TYPE_WIFI), isA(NetworkConfig.class)); -// -// final ArgumentCaptor<Handler> trackerHandler = ArgumentCaptor.forClass(Handler.class); -// doNothing().when(mMobile.tracker) -// .startMonitoring(isA(Context.class), trackerHandler.capture()); -// -// mService = new ConnectivityService( -// mServiceContext, mNetManager, mStatsService, mPolicyService); -// mService.systemReady(); -// -// mTrackerHandler = trackerHandler.getValue(); -// mTrackerHandler.getLooper().setMessageLogging(new LogPrinter(Log.INFO, TAG)); -// } -// // @Override // public void tearDown() throws Exception { // super.tearDown(); @@ -157,9 +441,9 @@ public class ConnectivityServiceTest extends AndroidTestCase { // mMobile.link.addRoute(MOBILE_ROUTE_V6); // mMobile.doReturnDefaults(); // -// nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION); +// cv = waitForConnectivityBroadcasts(1); // mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget(); -// nextConnBroadcast.get(); +// cv.block(); // // // verify that both routes were added // int mobileNetId = mMobile.tracker.getNetwork().netId; @@ -177,9 +461,9 @@ public class ConnectivityServiceTest extends AndroidTestCase { // mMobile.link.addRoute(MOBILE_ROUTE_V6); // mMobile.doReturnDefaults(); // -// nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION); +// cv = waitForConnectivityBroadcasts(1); // mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget(); -// nextConnBroadcast.get(); +// cv.block(); // // reset(mNetManager); // @@ -193,9 +477,9 @@ public class ConnectivityServiceTest extends AndroidTestCase { // // expect that mobile will be torn down // doReturn(true).when(mMobile.tracker).teardown(); // -// nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION); +// cv = waitForConnectivityBroadcasts(1); // mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mWifi.info).sendToTarget(); -// nextConnBroadcast.get(); +// cv.block(); // // // verify that wifi routes added, and teardown requested // int wifiNetId = mWifi.tracker.getNetwork().netId; @@ -212,9 +496,9 @@ public class ConnectivityServiceTest extends AndroidTestCase { // mMobile.link.clear(); // mMobile.doReturnDefaults(); // -// nextConnBroadcast = mServiceContext.nextBroadcastIntent(CONNECTIVITY_ACTION); +// cv = waitForConnectivityBroadcasts(1); // mTrackerHandler.obtainMessage(EVENT_STATE_CHANGED, mMobile.info).sendToTarget(); -// nextConnBroadcast.get(); +// cv.block(); // // verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V4)); // verify(mNetManager).removeRoute(eq(mobileNetId), eq(MOBILE_ROUTE_V6)); diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java index 6de887b..d8569bc 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java @@ -201,7 +201,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne Slog.w(TAG, "finish does not match active session"); return; } - mActiveSession.cancel(); + mActiveSession.cancelLocked(); mActiveSession = null; } @@ -251,7 +251,7 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne // If there is an active session, cancel it to allow it to clean up its window and other // state. if (mActiveSession != null) { - mActiveSession.cancel(); + mActiveSession.cancelLocked(); mActiveSession = null; } try { diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java index b4629f2..0b430ca 100644 --- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java +++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java @@ -19,9 +19,9 @@ package com.android.server.voiceinteraction; import android.app.ActivityManager; import android.app.ActivityManagerNative; import android.app.AppOpsManager; -import android.app.AssistContent; -import android.app.AssistStructure; import android.app.IActivityManager; +import android.app.assist.AssistContent; +import android.app.assist.AssistStructure; import android.content.ClipData; import android.content.ComponentName; import android.content.ContentProvider; @@ -376,6 +376,40 @@ final class VoiceInteractionSessionConnection implements ServiceConnection { return false; } + public void cancelLocked() { + hideLocked(); + mCanceled = true; + if (mBound) { + if (mSession != null) { + try { + mSession.destroy(); + } catch (RemoteException e) { + Slog.w(TAG, "Voice interation session already dead"); + } + } + if (mSession != null) { + try { + mAm.finishVoiceTask(mSession); + } catch (RemoteException e) { + } + } + mContext.unbindService(this); + try { + mIWindowManager.removeWindowToken(mToken); + } catch (RemoteException e) { + Slog.w(TAG, "Failed removing window token", e); + } + mBound = false; + mService = null; + mSession = null; + mInteractor = null; + } + if (mFullyBound) { + mContext.unbindService(mFullConnection); + mFullyBound = false; + } + } + public boolean deliverNewSessionLocked(IVoiceInteractionSession session, IVoiceInteractor interactor) { mSession = session; @@ -432,39 +466,6 @@ final class VoiceInteractionSessionConnection implements ServiceConnection { mService = null; } - public void cancel() { - mCanceled = true; - if (mBound) { - if (mSession != null) { - try { - mSession.destroy(); - } catch (RemoteException e) { - Slog.w(TAG, "Voice interation session already dead"); - } - } - if (mSession != null) { - try { - mAm.finishVoiceTask(mSession); - } catch (RemoteException e) { - } - } - mContext.unbindService(this); - try { - mIWindowManager.removeWindowToken(mToken); - } catch (RemoteException e) { - Slog.w(TAG, "Failed removing window token", e); - } - mBound = false; - mService = null; - mSession = null; - mInteractor = null; - } - if (mFullyBound) { - mContext.unbindService(mFullConnection); - mFullyBound = false; - } - } - private boolean isStructureEnabled() { return Settings.Secure.getIntForUser(mContext.getContentResolver(), Settings.Secure.ASSIST_STRUCTURE_ENABLED, 1, mUser) != 0; diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index 1d751d5..dfb02bb 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -51,6 +51,10 @@ public class CarrierConfigManager { public static final String ACTION_CARRIER_CONFIG_CHANGED = "android.telephony.action.CARRIER_CONFIG_CHANGED"; + // Below are the keys used in carrier config bundles. To add a new variable, define the key and + // give it a default value in sDefaults. If you need to ship a per-network override in the + // system image, that can be added in packages/apps/CarrierConfig. + /** * Flag indicating whether the Phone app should ignore EVENT_SIM_NETWORK_LOCKED * events from the Sim. diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java index f66a9ce..dae1ac3 100644 --- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java +++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionSession.java @@ -17,9 +17,9 @@ package com.android.test.voiceinteraction; import android.app.ActivityManager; +import android.app.VoiceInteractor; import android.app.AssistContent; import android.app.AssistStructure; -import android.app.VoiceInteractor; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; @@ -71,7 +71,7 @@ public class MainInteractionSession extends VoiceInteractionSession public void onCreate(Bundle args, int startFlags) { super.onCreate(args, startFlags); ActivityManager am = getContext().getSystemService(ActivityManager.class); - am.setWatchHeapLimit(40*1024*1024); + am.setWatchHeapLimit(40 * 1024 * 1024); } @Override @@ -118,6 +118,30 @@ public class MainInteractionSession extends VoiceInteractionSession return mContentView; } + public void onHandleAssist(Bundle assistBundle) { + if (assistBundle != null) { + Bundle assistContext = assistBundle.getBundle(Intent.EXTRA_ASSIST_CONTEXT); + if (assistContext != null) { + mAssistStructure = AssistStructure.getAssistStructure(assistContext); + if (mAssistStructure != null) { + if (mAssistVisualizer != null) { + mAssistVisualizer.setAssistStructure(mAssistStructure); + } + } + AssistContent content = AssistContent.getAssistContent(assistContext); + if (content != null) { + Log.i(TAG, "Assist intent: " + content.getIntent()); + Log.i(TAG, "Assist clipdata: " + content.getClipData()); + } + return; + } + } + if (mAssistVisualizer != null) { + mAssistVisualizer.clearAssistData(); + } + } + + /* @Override public void onHandleAssist(Bundle data, AssistStructure structure, AssistContent content) { mAssistStructure = structure; @@ -131,6 +155,7 @@ public class MainInteractionSession extends VoiceInteractionSession Log.i(TAG, "Assist clipdata: " + content.getClipData()); } } + */ @Override public void onHandleScreenshot(Bitmap screenshot) { diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java index 5f430f0..a3dc077 100644 --- a/wifi/java/android/net/wifi/WifiScanner.java +++ b/wifi/java/android/net/wifi/WifiScanner.java @@ -1007,7 +1007,7 @@ public class WifiScanner { ((ParcelableScanResults) msg.obj).getResults()); return; case CMD_SINGLE_SCAN_COMPLETED: - Log.d(TAG, "removing listener for single scan"); + if (DBG) Log.d(TAG, "removing listener for single scan"); removeListener(msg.arg2); break; default: |
