diff options
348 files changed, 3968 insertions, 1883 deletions
diff --git a/Android.mk b/Android.mk index 4dc5fd349109..0bd6b7f925d2 100644 --- a/Android.mk +++ b/Android.mk @@ -413,6 +413,8 @@ LOCAL_SRC_FILES += \ telephony/java/com/android/ims/internal/IImsRegistrationListener.aidl \ telephony/java/com/android/ims/internal/IImsEcbm.aidl \ telephony/java/com/android/ims/internal/IImsEcbmListener.aidl \ + telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl \ + telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl \ telephony/java/com/android/ims/internal/IImsService.aidl \ telephony/java/com/android/ims/internal/IImsStreamMediaSession.aidl \ telephony/java/com/android/ims/internal/IImsUt.aidl \ diff --git a/api/current.txt b/api/current.txt index 032b2cbe3c0c..1944157d04b8 100644 --- a/api/current.txt +++ b/api/current.txt @@ -5979,6 +5979,7 @@ package android.app.admin { field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2 field public static final int ENCRYPTION_STATUS_ACTIVE = 3; // 0x3 field public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4; // 0x4 + field public static final int ENCRYPTION_STATUS_ACTIVE_PER_USER = 5; // 0x5 field public static final int ENCRYPTION_STATUS_INACTIVE = 1; // 0x1 field public static final int ENCRYPTION_STATUS_UNSUPPORTED = 0; // 0x0 field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION"; @@ -8113,7 +8114,7 @@ package android.content { field public static final java.lang.String DOWNLOAD_SERVICE = "download"; field public static final java.lang.String DROPBOX_SERVICE = "dropbox"; field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint"; - field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardwareproperties"; + field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties"; field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method"; field public static final java.lang.String INPUT_SERVICE = "input"; field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler"; @@ -9327,6 +9328,7 @@ package android.content.pm { field public int flags; field public int largestWidthLimitDp; field public java.lang.String manageSpaceActivityName; + field public java.lang.String minSdkVersion; field public java.lang.String nativeLibraryDir; field public java.lang.String permission; field public java.lang.String processName; @@ -13776,6 +13778,7 @@ package android.hardware.camera2 { public static abstract class CameraCaptureSession.CaptureCallback { ctor public CameraCaptureSession.CaptureCallback(); + method public void onCaptureBufferLost(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.view.Surface, long); method public void onCaptureCompleted(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.TotalCaptureResult); method public void onCaptureFailed(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureFailure); method public void onCaptureProgressed(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult); diff --git a/api/system-current.txt b/api/system-current.txt index 3b8f584c3006..cf175cc2d374 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -6130,6 +6130,7 @@ package android.app.admin { field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2 field public static final int ENCRYPTION_STATUS_ACTIVE = 3; // 0x3 field public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4; // 0x4 + field public static final int ENCRYPTION_STATUS_ACTIVE_PER_USER = 5; // 0x5 field public static final int ENCRYPTION_STATUS_INACTIVE = 1; // 0x1 field public static final int ENCRYPTION_STATUS_UNSUPPORTED = 0; // 0x0 field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION"; @@ -8416,7 +8417,7 @@ package android.content { field public static final java.lang.String DOWNLOAD_SERVICE = "download"; field public static final java.lang.String DROPBOX_SERVICE = "dropbox"; field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint"; - field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardwareproperties"; + field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties"; field public static final java.lang.String HDMI_CONTROL_SERVICE = "hdmi_control"; field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method"; field public static final java.lang.String INPUT_SERVICE = "input"; @@ -9649,6 +9650,7 @@ package android.content.pm { field public int flags; field public int largestWidthLimitDp; field public java.lang.String manageSpaceActivityName; + field public java.lang.String minSdkVersion; field public java.lang.String nativeLibraryDir; field public java.lang.String permission; field public java.lang.String processName; @@ -9930,6 +9932,7 @@ package android.content.pm { method public void setAppLabel(java.lang.CharSequence); method public void setAppPackageName(java.lang.String); method public void setGrantedRuntimePermissions(java.lang.String[]); + method public void setInstallFlagsDowngrade(); method public void setInstallLocation(int); method public void setOriginatingUid(int); method public void setOriginatingUri(android.net.Uri); @@ -14177,6 +14180,7 @@ package android.hardware.camera2 { public static abstract class CameraCaptureSession.CaptureCallback { ctor public CameraCaptureSession.CaptureCallback(); + method public void onCaptureBufferLost(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.view.Surface, long); method public void onCaptureCompleted(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.TotalCaptureResult); method public void onCaptureFailed(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureFailure); method public void onCaptureProgressed(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult); @@ -23826,6 +23830,7 @@ package android.media.audiopolicy { public static class AudioMix.Builder { ctor public AudioMix.Builder(android.media.audiopolicy.AudioMixingRule) throws java.lang.IllegalArgumentException; method public android.media.audiopolicy.AudioMix build() throws java.lang.IllegalArgumentException; + method public android.media.audiopolicy.AudioMix.Builder setDevice(android.media.AudioDeviceInfo) throws java.lang.IllegalArgumentException; method public android.media.audiopolicy.AudioMix.Builder setFormat(android.media.AudioFormat) throws java.lang.IllegalArgumentException; method public android.media.audiopolicy.AudioMix.Builder setRouteFlags(int) throws java.lang.IllegalArgumentException; } diff --git a/api/test-current.txt b/api/test-current.txt index da31235d8e74..b8f7326c853a 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -5983,6 +5983,7 @@ package android.app.admin { field public static final int ENCRYPTION_STATUS_ACTIVATING = 2; // 0x2 field public static final int ENCRYPTION_STATUS_ACTIVE = 3; // 0x3 field public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4; // 0x4 + field public static final int ENCRYPTION_STATUS_ACTIVE_PER_USER = 5; // 0x5 field public static final int ENCRYPTION_STATUS_INACTIVE = 1; // 0x1 field public static final int ENCRYPTION_STATUS_UNSUPPORTED = 0; // 0x0 field public static final java.lang.String EXTRA_ADD_EXPLANATION = "android.app.extra.ADD_EXPLANATION"; @@ -8119,7 +8120,7 @@ package android.content { field public static final java.lang.String DOWNLOAD_SERVICE = "download"; field public static final java.lang.String DROPBOX_SERVICE = "dropbox"; field public static final java.lang.String FINGERPRINT_SERVICE = "fingerprint"; - field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardwareproperties"; + field public static final java.lang.String HARDWARE_PROPERTIES_SERVICE = "hardware_properties"; field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method"; field public static final java.lang.String INPUT_SERVICE = "input"; field public static final java.lang.String JOB_SCHEDULER_SERVICE = "jobscheduler"; @@ -9336,6 +9337,7 @@ package android.content.pm { field public int flags; field public int largestWidthLimitDp; field public java.lang.String manageSpaceActivityName; + field public java.lang.String minSdkVersion; field public java.lang.String nativeLibraryDir; field public java.lang.String permission; field public java.lang.String processName; @@ -13786,6 +13788,7 @@ package android.hardware.camera2 { public static abstract class CameraCaptureSession.CaptureCallback { ctor public CameraCaptureSession.CaptureCallback(); + method public void onCaptureBufferLost(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.view.Surface, long); method public void onCaptureCompleted(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.TotalCaptureResult); method public void onCaptureFailed(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureFailure); method public void onCaptureProgressed(android.hardware.camera2.CameraCaptureSession, android.hardware.camera2.CaptureRequest, android.hardware.camera2.CaptureResult); diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java index 844063c04e83..8e31d323009f 100644 --- a/core/java/android/animation/Animator.java +++ b/core/java/android/animation/Animator.java @@ -16,6 +16,7 @@ package android.animation; +import android.content.pm.ActivityInfo.Config; import android.content.res.ConstantState; import java.util.ArrayList; @@ -50,7 +51,7 @@ public abstract class Animator implements Cloneable { * A set of flags which identify the type of configuration changes that can affect this * Animator. Used by the Animator cache. */ - int mChangingConfigurations = 0; + @Config int mChangingConfigurations = 0; /** * If this animator is inflated from a constant state, keep a reference to it so that @@ -344,7 +345,7 @@ public abstract class Animator implements Cloneable { * @see android.content.pm.ActivityInfo * @hide */ - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations; } @@ -358,7 +359,7 @@ public abstract class Animator implements Cloneable { * @see android.content.pm.ActivityInfo * @hide */ - public void setChangingConfigurations(int configs) { + public void setChangingConfigurations(@Config int configs) { mChangingConfigurations = configs; } @@ -368,7 +369,7 @@ public abstract class Animator implements Cloneable { * This method is called while loading the animator. * @hide */ - public void appendChangingConfigurations(int configs) { + public void appendChangingConfigurations(@Config int configs) { mChangingConfigurations |= configs; } @@ -564,7 +565,7 @@ public abstract class Animator implements Cloneable { private static class AnimatorConstantState extends ConstantState<Animator> { final Animator mAnimator; - int mChangingConf; + @Config int mChangingConf; public AnimatorConstantState(Animator animator) { mAnimator = animator; @@ -574,7 +575,7 @@ public abstract class Animator implements Cloneable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConf; } diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java index 8d03b551a347..7d5931fc1cc2 100644 --- a/core/java/android/animation/AnimatorInflater.java +++ b/core/java/android/animation/AnimatorInflater.java @@ -16,7 +16,10 @@ package android.animation; import android.annotation.AnimatorRes; +import android.annotation.AnyRes; +import android.annotation.NonNull; import android.content.Context; +import android.content.pm.ActivityInfo.Config; import android.content.res.ConfigurationBoundResourceCache; import android.content.res.ConstantState; import android.content.res.Resources; @@ -1062,7 +1065,7 @@ public class AnimatorInflater { return anim; } - private static int getChangingConfigs(Resources resources, int id) { + private static @Config int getChangingConfigs(@NonNull Resources resources, @AnyRes int id) { synchronized (sTmpTypedValue) { resources.getValue(id, sTmpTypedValue, true); return sTmpTypedValue.changingConfigurations; diff --git a/core/java/android/animation/StateListAnimator.java b/core/java/android/animation/StateListAnimator.java index d49e914cf5cc..b6d6910c1dc8 100644 --- a/core/java/android/animation/StateListAnimator.java +++ b/core/java/android/animation/StateListAnimator.java @@ -16,6 +16,7 @@ package android.animation; +import android.content.pm.ActivityInfo.Config; import android.content.res.ConstantState; import android.util.StateSet; import android.view.View; @@ -53,7 +54,7 @@ public class StateListAnimator implements Cloneable { private WeakReference<View> mViewRef; private StateListAnimatorConstantState mConstantState; private AnimatorListenerAdapter mAnimatorListener; - private int mChangingConfigurations; + private @Config int mChangingConfigurations; public StateListAnimator() { initAnimatorListener(); @@ -223,7 +224,7 @@ public class StateListAnimator implements Cloneable { * @see android.content.pm.ActivityInfo * @hide */ - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations; } @@ -237,7 +238,7 @@ public class StateListAnimator implements Cloneable { * @see android.content.pm.ActivityInfo * @hide */ - public void setChangingConfigurations(int configs) { + public void setChangingConfigurations(@Config int configs) { mChangingConfigurations = configs; } @@ -247,7 +248,7 @@ public class StateListAnimator implements Cloneable { * This method is called while loading the animator. * @hide */ - public void appendChangingConfigurations(int configs) { + public void appendChangingConfigurations(@Config int configs) { mChangingConfigurations |= configs; } @@ -309,7 +310,7 @@ public class StateListAnimator implements Cloneable { final StateListAnimator mAnimator; - int mChangingConf; + @Config int mChangingConf; public StateListAnimatorConstantState(StateListAnimator animator) { mAnimator = animator; @@ -318,7 +319,7 @@ public class StateListAnimator implements Cloneable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConf; } diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java index 5ab2c1d491d7..663f297a7feb 100644 --- a/core/java/android/animation/ValueAnimator.java +++ b/core/java/android/animation/ValueAnimator.java @@ -972,7 +972,14 @@ public class ValueAnimator extends Animator implements AnimationHandler.Animatio // to be consistent with the previous behavior. Otherwise, postpone this until the first // frame after the start delay. startAnimation(); - setCurrentFraction(mSeekFraction == -1 ? 0 : mSeekFraction); + if (mSeekFraction == -1) { + // No seek, start at play time 0. Note that the reason we are not using fraction 0 + // is because for animations with 0 duration, we want to be consistent with pre-N + // behavior: skip to the final value immediately. + setCurrentPlayTime(0); + } else { + setCurrentFraction(mSeekFraction); + } } } diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 2f6907e3f31e..2d33a2c8450f 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -3329,6 +3329,23 @@ public class ActivityManager { } } + /** + * Logs out current current foreground user by switching to the system user and stopping the + * user being switched from. + * @hide + */ + public static void logoutCurrentUser() { + int currentUser = ActivityManager.getCurrentUser(); + if (currentUser != UserHandle.USER_SYSTEM) { + try { + ActivityManagerNative.getDefault().switchUser(UserHandle.USER_SYSTEM); + ActivityManagerNative.getDefault().stopUser(currentUser, /* force= */ false, null); + } catch (RemoteException e) { + e.rethrowFromSystemServer(); + } + } + } + /** {@hide} */ public static final int FLAG_OR_STOPPED = 1 << 0; /** {@hide} */ diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 82c4c51b6a04..64586a6d8415 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -1267,8 +1267,15 @@ public class AppOpsManager { /** @hide */ public void setUserRestriction(int code, boolean restricted, IBinder token) { + setUserRestriction(code, restricted, token, /*exceptionPackages*/null); + } + + /** @hide */ + public void setUserRestriction(int code, boolean restricted, IBinder token, + String[] exceptionPackages) { try { - mService.setUserRestriction(code, restricted, token, mContext.getUserId()); + mService.setUserRestriction(code, restricted, token, mContext.getUserId(), + exceptionPackages); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/MediaRouteButton.java b/core/java/android/app/MediaRouteButton.java index 181c90758e8e..70a5e15c6c27 100644 --- a/core/java/android/app/MediaRouteButton.java +++ b/core/java/android/app/MediaRouteButton.java @@ -19,6 +19,7 @@ package android.app; import com.android.internal.R; import com.android.internal.app.MediaRouteDialogPresenter; +import android.annotation.NonNull; import android.content.Context; import android.content.ContextWrapper; import android.content.res.TypedArray; @@ -279,7 +280,7 @@ public class MediaRouteButton extends View { } @Override - protected boolean verifyDrawable(Drawable who) { + protected boolean verifyDrawable(@NonNull Drawable who) { return super.verifyDrawable(who) || who == mRemoteIndicator; } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 53a6351b36e6..ec1e3e67fbe3 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -2487,6 +2487,12 @@ public class DevicePolicyManager { public static final int ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY = 4; /** + * Result code for {@link #getStorageEncryptionStatus}: + * indicating that encryption is active and the encryption key is tied to the user. + */ + public static final int ENCRYPTION_STATUS_ACTIVE_PER_USER = 5; + + /** * Activity action: begin the process of encrypting data on the device. This activity should * be launched after using {@link #setStorageEncryption} to request encryption be activated. * After resuming from this activity, use {@link #getStorageEncryption} @@ -2627,7 +2633,7 @@ public class DevicePolicyManager { public int getStorageEncryptionStatus(int userHandle) { if (mService != null) { try { - return mService.getStorageEncryptionStatus(userHandle); + return mService.getStorageEncryptionStatus(mContext.getPackageName(), userHandle); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl index dc73e2613f18..c38496dba4e9 100644 --- a/core/java/android/app/admin/IDevicePolicyManager.aidl +++ b/core/java/android/app/admin/IDevicePolicyManager.aidl @@ -91,7 +91,7 @@ interface IDevicePolicyManager { int setStorageEncryption(in ComponentName who, boolean encrypt); boolean getStorageEncryption(in ComponentName who, int userHandle); - int getStorageEncryptionStatus(int userHandle); + int getStorageEncryptionStatus(in String callerPackage, int userHandle); boolean requestBugreport(in ComponentName who); diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java index 30c11efd658e..f256a9536061 100644 --- a/core/java/android/app/backup/WallpaperBackupHelper.java +++ b/core/java/android/app/backup/WallpaperBackupHelper.java @@ -120,6 +120,7 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu * need to be backed up, write them to the data stream, and fill in newState with the * state as it exists now. */ + @Override public void performBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) { performBackup_checked(oldState, data, newState, mFiles, mKeys); @@ -130,6 +131,7 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu * magic wallpaper file, take specific action to determine whether it is suitable for * the current device. */ + @Override public void restoreEntity(BackupDataInputStream data) { final String key = data.getKey(); if (isKeyInList(key, mKeys)) { @@ -174,12 +176,8 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu } // We passed the acceptable-dimensions test (if any), so we're going to - // use the restored image. - // TODO: spin a service to copy the restored image to sd/usb storage, - // since it does not exist anywhere other than the private wallpaper - // file. - Slog.d(TAG, "Applying restored wallpaper image."); - f.renameTo(new File(WALLPAPER_IMAGE)); + // use the restored image. That comes last, when we are done restoring + // both the pixels and the metadata. } } else if (key.equals(WALLPAPER_INFO_KEY)) { // XML file containing wallpaper info @@ -188,4 +186,20 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu } } } + + /** + * Hook for the agent to call this helper upon completion of the restore. We do this + * upon completion so that we know both the imagery and the wallpaper info have + * been emplaced without requiring either or relying on ordering. + */ + public void onRestoreFinished() { + final File f = new File(STAGE_FILE); + if (f.exists()) { + // TODO: spin a service to copy the restored image to sd/usb storage, + // since it does not exist anywhere other than the private wallpaper + // file. + Slog.d(TAG, "Applying restored wallpaper image."); + f.renameTo(new File(WALLPAPER_IMAGE)); + } + } } diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java index 039c9d7c3c31..bbfec41a5015 100644 --- a/core/java/android/app/job/JobInfo.java +++ b/core/java/android/app/job/JobInfo.java @@ -536,6 +536,9 @@ public class JobInfo implements Parcelable { * {@link #setPeriodic(long)} or {@link #setPersisted(boolean)}. To continually monitor * for content changes, you need to schedule a new JobInfo observing the same URIs * before you finish execution of the JobService handling the most recent changes.</p> + * <p>Because because setting this property is not compatible with periodic or + * persisted jobs, doing so will throw an {@link java.lang.IllegalArgumentException} when + * {@link android.app.job.JobInfo.Builder#build()} is called.</p> * @param uri The content: URI to monitor. */ public Builder addTriggerContentUri(@NonNull TriggerContentUri uri) { diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java index 4e1b6e019b48..441f188f91e6 100644 --- a/core/java/android/content/ContentResolver.java +++ b/core/java/android/content/ContentResolver.java @@ -2440,6 +2440,28 @@ public abstract class ContentResolver { } } + /** {@hide} */ + public void putCache(Uri key, Bundle value) { + try { + getContentService().putCache(mContext.getPackageName(), key, value, + mContext.getUserId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** {@hide} */ + public Bundle getCache(Uri key) { + try { + final Bundle bundle = getContentService().getCache(mContext.getPackageName(), key, + mContext.getUserId()); + if (bundle != null) bundle.setClassLoader(mContext.getClassLoader()); + return bundle; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** * Returns sampling percentage for a given duration. * diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 825dd5bc6613..ccb0552ae482 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -2742,7 +2742,7 @@ public abstract class Context { * <dt> {@link #NETWORK_STATS_SERVICE} ("netstats") * <dd> A {@link android.app.usage.NetworkStatsManager NetworkStatsManager} for querying network * usage statistics. - * <dt> {@link #HARDWARE_PROPERTIES_SERVICE} ("hardwareproperties") + * <dt> {@link #HARDWARE_PROPERTIES_SERVICE} ("hardware_properties") * <dd> A {@link android.os.HardwarePropertiesManager} for accessing hardware properties. * </dl> * @@ -3574,7 +3574,7 @@ public abstract class Context { * * @see #getSystemService */ - public static final String HARDWARE_PROPERTIES_SERVICE = "hardwareproperties"; + public static final String HARDWARE_PROPERTIES_SERVICE = "hardware_properties"; /** * TODO Javadoc diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl index 8b471a04f25b..d47e780fa4d2 100644 --- a/core/java/android/content/IContentService.aidl +++ b/core/java/android/content/IContentService.aidl @@ -179,6 +179,8 @@ interface IContentService { int userId); void addStatusChangeListener(int mask, ISyncStatusObserver callback); - void removeStatusChangeListener(ISyncStatusObserver callback); + + void putCache(in String packageName, in Uri key, in Bundle value, int userId); + Bundle getCache(in String packageName, in Uri key, int userId); } diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 14ef61ce63d4..5da3c866077a 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -18,6 +18,7 @@ package android.content.pm; import android.annotation.IntDef; import android.content.res.Configuration; +import android.content.res.Configuration.NativeConfig; import android.os.Parcel; import android.os.Parcelable; import android.util.Printer; @@ -495,6 +496,28 @@ public class ActivityInfo extends ComponentInfo @ScreenOrientation public int screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED; + /** @hide */ + @IntDef(flag = true, + value = { + CONFIG_MCC, + CONFIG_MNC, + CONFIG_LOCALE, + CONFIG_TOUCHSCREEN, + CONFIG_KEYBOARD, + CONFIG_KEYBOARD_HIDDEN, + CONFIG_NAVIGATION, + CONFIG_ORIENTATION, + CONFIG_SCREEN_LAYOUT, + CONFIG_UI_MODE, + CONFIG_SCREEN_SIZE, + CONFIG_SMALLEST_SCREEN_SIZE, + CONFIG_DENSITY, + CONFIG_LAYOUT_DIRECTION, + CONFIG_FONT_SCALE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface Config {} + /** * Bit in {@link #configChanges} that indicates that the activity * can itself handle changes to the IMSI MCC. Set from the @@ -629,7 +652,7 @@ public class ActivityInfo extends ComponentInfo * * @hide */ - public static int activityInfoConfigToNative(int input) { + public static @NativeConfig int activityInfoConfigJavaToNative(@Config int input) { int output = 0; for (int i = 0; i < CONFIG_NATIVE_BITS.length; i++) { if ((input & (1 << i)) != 0) { @@ -644,7 +667,7 @@ public class ActivityInfo extends ComponentInfo * * @hide */ - public static int activityInfoConfigNativeToJava(int input) { + public static @Config int activityInfoConfigNativeToJava(@NativeConfig int input) { int output = 0; for (int i = 0; i < CONFIG_NATIVE_BITS.length; i++) { if ((input & CONFIG_NATIVE_BITS[i]) != 0) { diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java index ad174f6da061..58d75f761c8e 100644 --- a/core/java/android/content/pm/ApplicationInfo.java +++ b/core/java/android/content/pm/ApplicationInfo.java @@ -707,6 +707,12 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { public int uid; /** + * The minimum SDK version this application can run on. It will not run + * on earlier versions. + */ + public String minSdkVersion; + + /** * The minimum SDK version this application targets. It may run on earlier * versions, but it knows how to work with any new behavior added at this * version. Will be {@link android.os.Build.VERSION_CODES#CUR_DEVELOPMENT} @@ -790,7 +796,9 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { pw.println(prefix + "sharedLibraryFiles=" + Arrays.toString(sharedLibraryFiles)); } } - pw.println(prefix + "enabled=" + enabled + " targetSdkVersion=" + targetSdkVersion + pw.println(prefix + "enabled=" + enabled + + " minSdkVersion=" + minSdkVersion + + " targetSdkVersion=" + targetSdkVersion + " versionCode=" + versionCode); if ((flags&DUMP_FLAG_DETAILS) != 0) { if (manageSpaceActivityName != null) { @@ -884,6 +892,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { deviceEncryptedDataDir = orig.deviceEncryptedDataDir; credentialEncryptedDataDir = orig.credentialEncryptedDataDir; uid = orig.uid; + minSdkVersion = orig.minSdkVersion; targetSdkVersion = orig.targetSdkVersion; versionCode = orig.versionCode; enabled = orig.enabled; @@ -938,6 +947,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { dest.writeString(deviceEncryptedDataDir); dest.writeString(credentialEncryptedDataDir); dest.writeInt(uid); + dest.writeString(minSdkVersion); dest.writeInt(targetSdkVersion); dest.writeInt(versionCode); dest.writeInt(enabled ? 1 : 0); @@ -992,6 +1002,7 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable { deviceEncryptedDataDir = source.readString(); credentialEncryptedDataDir = source.readString(); uid = source.readInt(); + minSdkVersion = source.readString(); targetSdkVersion = source.readInt(); versionCode = source.readInt(); enabled = source.readInt() != 0; diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 1f603ef80638..0f5ec919710e 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -1053,6 +1053,12 @@ public class PackageInstaller { } /** {@hide} */ + @SystemApi + public void setInstallFlagsDowngrade() { + installFlags |= PackageManager.INSTALL_ALLOW_DOWNGRADE; + } + + /** {@hide} */ public void setInstallFlagsExternal() { installFlags |= PackageManager.INSTALL_EXTERNAL; installFlags &= ~PackageManager.INSTALL_INTERNAL; diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index bc28ff177a7e..7d7be9abbb90 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -1524,6 +1524,7 @@ public class PackageParser { childPkg.baseRevisionCode = parentPkg.baseRevisionCode; childPkg.mVersionName = parentPkg.mVersionName; childPkg.applicationInfo.targetSdkVersion = parentPkg.applicationInfo.targetSdkVersion; + childPkg.applicationInfo.minSdkVersion = parentPkg.applicationInfo.minSdkVersion; childPkg = parseBaseApkCommon(childPkg, CHILD_PACKAGE_TAGS, res, parser, flags, outError); if (childPkg == null) { @@ -1854,10 +1855,16 @@ public class PackageParser { com.android.internal.R.styleable.AndroidManifestUsesSdk_targetSdkVersion); if (val != null) { if (val.type == TypedValue.TYPE_STRING && val.string != null) { - targetCode = minCode = val.string.toString(); + targetCode = val.string.toString(); + if (minCode == null) { + minCode = targetCode; + } } else { // If it's not a string, it's an integer. targetVers = val.data; + if (minVers == 0) { + minVers = targetVers; + } } } @@ -1883,11 +1890,14 @@ public class PackageParser { mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK; return null; } + pkg.applicationInfo.minSdkVersion = minCode; } else if (minVers > SDK_VERSION) { outError[0] = "Requires newer sdk version #" + minVers + " (current version is #" + SDK_VERSION + ")"; mParseError = PackageManager.INSTALL_FAILED_OLDER_SDK; return null; + } else { + pkg.applicationInfo.minSdkVersion = Integer.toString(minVers); } if (targetCode != null) { diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java index 83a70cd1a769..e41136c0038a 100644 --- a/core/java/android/content/pm/ShortcutInfo.java +++ b/core/java/android/content/pm/ShortcutInfo.java @@ -160,10 +160,12 @@ public class ShortcutInfo implements Parcelable { mIcon = b.mIcon; mTitle = b.mTitle; mIntent = b.mIntent; - final Bundle intentExtras = mIntent.getExtras(); - if (intentExtras != null) { - mIntent.replaceExtras((Bundle) null); - mIntentPersistableExtras = new PersistableBundle(intentExtras); + if (mIntent != null) { + final Bundle intentExtras = mIntent.getExtras(); + if (intentExtras != null) { + mIntent.replaceExtras((Bundle) null); + mIntentPersistableExtras = new PersistableBundle(intentExtras); + } } mWeight = b.mWeight; mExtras = b.mExtras; @@ -194,6 +196,7 @@ public class ShortcutInfo implements Parcelable { if ((cloneFlags & CLONE_REMOVE_ICON) == 0) { mIcon = source.mIcon; + mBitmapPath = source.mBitmapPath; } mTitle = source.mTitle; @@ -204,8 +207,6 @@ public class ShortcutInfo implements Parcelable { mWeight = source.mWeight; mExtras = source.mExtras; mIconResourceId = source.mIconResourceId; - mBitmapPath = source.mBitmapPath; - } else { // Set this bit. mFlags |= FLAG_KEY_FIELDS_ONLY; @@ -231,9 +232,9 @@ public class ShortcutInfo implements Parcelable { * @hide */ public void copyNonNullFieldsFrom(ShortcutInfo source) { - Preconditions.checkState(mId == source.mId, "ID must match"); + Preconditions.checkState(mId.equals(source.mId), "ID must match"); Preconditions.checkState(mPackageName.equals(source.mPackageName), - "Package namae must match"); + "Package name must match"); if (source.mActivityComponent != null) { mActivityComponent = source.mActivityComponent; diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 7b0b98d4389c..4ad86f7c7019 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -21,6 +21,7 @@ import android.annotation.ArrayRes; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StringRes; +import android.content.res.Configuration.NativeConfig; import android.os.ParcelFileDescriptor; import android.util.Log; import android.util.SparseArray; @@ -796,7 +797,10 @@ public final class AssetManager implements AutoCloseable { /*package*/ static final int STYLE_DATA = 1; /*package*/ static final int STYLE_ASSET_COOKIE = 2; /*package*/ static final int STYLE_RESOURCE_ID = 3; - /*package*/ static final int STYLE_CHANGING_CONFIGURATIONS = 4; + + /* Offset within typed data array for native changingConfigurations. */ + static final int STYLE_CHANGING_CONFIGURATIONS = 4; + /*package*/ static final int STYLE_DENSITY = 5; /*package*/ native static final boolean applyStyle(long theme, int defStyleAttr, int defStyleRes, long xmlParser, @@ -845,7 +849,7 @@ public final class AssetManager implements AutoCloseable { TypedValue outValue, boolean resolve); /*package*/ native static final void dumpTheme(long theme, int priority, String tag, String prefix); - /*package*/ native static final int getThemeChangingConfigurations(long theme); + /*package*/ native static final @NativeConfig int getThemeChangingConfigurations(long theme); private native final long openXmlAssetNative(int cookie, String fileName); diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java index 9e1b312c8372..5bf2e3e5aa49 100644 --- a/core/java/android/content/res/ColorStateList.java +++ b/core/java/android/content/res/ColorStateList.java @@ -19,6 +19,7 @@ package android.content.res; import android.annotation.ColorInt; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.ActivityInfo.Config; import android.content.res.Resources.Theme; import android.graphics.Color; @@ -82,7 +83,7 @@ public class ColorStateList extends ComplexColor implements Parcelable { private ColorStateListFactory mFactory; private int[][] mThemeAttrs; - private int mChangingConfigurations; + private @Config int mChangingConfigurations; private int[][] mStateSpecs; private int[] mColors; @@ -251,7 +252,7 @@ public class ColorStateList extends ComplexColor implements Parcelable { int depth; int type; - int changingConfigurations = 0; + @Config int changingConfigurations = 0; int defaultColor = DEFAULT_COLOR; boolean hasUnresolvedAttrs = false; @@ -440,7 +441,7 @@ public class ColorStateList extends ComplexColor implements Parcelable { * * @see android.content.pm.ActivityInfo */ - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations; } @@ -620,7 +621,7 @@ public class ColorStateList extends ComplexColor implements Parcelable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mSrc.mChangingConfigurations; } diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java index be4f89567f51..9b1d4627807c 100644 --- a/core/java/android/content/res/Configuration.java +++ b/core/java/android/content/res/Configuration.java @@ -22,8 +22,11 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import org.xmlpull.v1.XmlSerializer; +import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.Nullable; import android.content.pm.ActivityInfo; +import android.content.pm.ActivityInfo.Config; import android.os.Build; import android.os.Parcel; import android.os.Parcelable; @@ -32,6 +35,8 @@ import android.util.LocaleList; import android.view.View; import java.io.IOException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.Locale; @@ -663,6 +668,28 @@ public final class Configuration implements Parcelable, Comparable<Configuration */ public int seq; + /** @hide */ + @IntDef(flag = true, + value = { + NATIVE_CONFIG_MCC, + NATIVE_CONFIG_MNC, + NATIVE_CONFIG_LOCALE, + NATIVE_CONFIG_TOUCHSCREEN, + NATIVE_CONFIG_KEYBOARD, + NATIVE_CONFIG_KEYBOARD_HIDDEN, + NATIVE_CONFIG_NAVIGATION, + NATIVE_CONFIG_ORIENTATION, + NATIVE_CONFIG_DENSITY, + NATIVE_CONFIG_SCREEN_SIZE, + NATIVE_CONFIG_VERSION, + NATIVE_CONFIG_SCREEN_LAYOUT, + NATIVE_CONFIG_UI_MODE, + NATIVE_CONFIG_SMALLEST_SCREEN_SIZE, + NATIVE_CONFIG_LAYOUTDIR, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface NativeConfig {} + /** @hide Native-specific bit mask for MCC config; DO NOT USE UNLESS YOU ARE SURE. */ public static final int NATIVE_CONFIG_MCC = 0x0001; /** @hide Native-specific bit mask for MNC config; DO NOT USE UNLESS YOU ARE SURE. */ @@ -917,14 +944,13 @@ public final class Configuration implements Parcelable, Comparable<Configuration } /** - * Copy the fields from delta into this Configuration object, keeping - * track of which ones have changed. Any undefined fields in - * <var>delta</var> are ignored and not copied in to the current - * Configuration. - * @return Returns a bit mask of the changed fields, as per - * {@link #diff}. + * Copies the fields from delta into this Configuration object, keeping + * track of which ones have changed. Any undefined fields in {@code delta} + * are ignored and not copied in to the current Configuration. + * + * @return a bit mask of the changed fields, as per {@link #diff} */ - public int updateFrom(Configuration delta) { + public @Config int updateFrom(@NonNull Configuration delta) { int changed = 0; if (delta.fontScale > 0 && fontScale != delta.fontScale) { changed |= ActivityInfo.CONFIG_FONT_SCALE; @@ -1171,17 +1197,19 @@ public final class Configuration implements Parcelable, Comparable<Configuration } /** - * Determine if a new resource needs to be loaded from the bit set of + * Determines if a new resource needs to be loaded from the bit set of * configuration changes returned by {@link #updateFrom(Configuration)}. * - * @param configChanges The mask of changes configurations as returned by - * {@link #updateFrom(Configuration)}. - * @param interestingChanges The configuration changes that the resource - * can handled, as given in {@link android.util.TypedValue#changingConfigurations}. - * - * @return Return true if the resource needs to be loaded, else false. + * @param configChanges the mask of changes configurations as returned by + * {@link #updateFrom(Configuration)} + * @param interestingChanges the configuration changes that the resource + * can handle as given in + * {@link android.util.TypedValue#changingConfigurations} + * @return {@code true} if the resource needs to be loaded, {@code false} + * otherwise */ - public static boolean needNewResources(int configChanges, int interestingChanges) { + public static boolean needNewResources(@Config int configChanges, + @Config int interestingChanges) { return (configChanges & (interestingChanges|ActivityInfo.CONFIG_FONT_SCALE)) != 0; } diff --git a/core/java/android/content/res/ConfigurationBoundResourceCache.java b/core/java/android/content/res/ConfigurationBoundResourceCache.java index 40d2a82b7b83..70290c4b0595 100644 --- a/core/java/android/content/res/ConfigurationBoundResourceCache.java +++ b/core/java/android/content/res/ConfigurationBoundResourceCache.java @@ -16,6 +16,8 @@ package android.content.res; +import android.content.pm.ActivityInfo.Config; + /** * A Cache class which can be used to cache resource objects that are easy to clone but more * expensive to inflate. @@ -42,7 +44,7 @@ public class ConfigurationBoundResourceCache<T> extends ThemedResourceCache<Cons } @Override - public boolean shouldInvalidateEntry(ConstantState<T> entry, int configChanges) { + public boolean shouldInvalidateEntry(ConstantState<T> entry, @Config int configChanges) { return Configuration.needNewResources(configChanges, entry.getChangingConfigurations()); } } diff --git a/core/java/android/content/res/ConstantState.java b/core/java/android/content/res/ConstantState.java index ee609df2e232..09d4a59d1418 100644 --- a/core/java/android/content/res/ConstantState.java +++ b/core/java/android/content/res/ConstantState.java @@ -15,6 +15,8 @@ */ package android.content.res; +import android.content.pm.ActivityInfo.Config; + /** * A cache class that can provide new instances of a particular resource which may change * depending on the current {@link Resources.Theme} or {@link Configuration}. @@ -33,7 +35,7 @@ abstract public class ConstantState<T> { * Return a bit mask of configuration changes that will impact * this resource (and thus require completely reloading it). */ - abstract public int getChangingConfigurations(); + abstract public @Config int getChangingConfigurations(); /** * Create a new instance without supplying resources the caller diff --git a/core/java/android/content/res/GradientColor.java b/core/java/android/content/res/GradientColor.java index cc46cbd43258..329134094824 100644 --- a/core/java/android/content/res/GradientColor.java +++ b/core/java/android/content/res/GradientColor.java @@ -20,6 +20,7 @@ import android.annotation.ColorInt; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.ActivityInfo.Config; import android.content.res.Resources.Theme; import com.android.internal.R; @@ -83,7 +84,7 @@ public class GradientColor extends ComplexColor { /** Lazily-created factory for this GradientColor. */ private GradientColorFactory mFactory; - private int mChangingConfigurations; + private @Config int mChangingConfigurations; private int mDefaultColor; // After parsing all the attributes from XML, this shader is the ultimate result containing @@ -506,7 +507,7 @@ public class GradientColor extends ComplexColor { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mSrc.mChangingConfigurations; } diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index 0858cb8b9305..90037f7b508c 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -15,6 +15,9 @@ */ package android.content.res; +import org.xmlpull.v1.XmlPullParser; +import org.xmlpull.v1.XmlPullParserException; + import android.animation.Animator; import android.animation.StateListAnimator; import android.annotation.AnyRes; @@ -26,6 +29,7 @@ import android.annotation.RawRes; import android.annotation.StyleRes; import android.annotation.StyleableRes; import android.content.pm.ActivityInfo; +import android.content.pm.ActivityInfo.Config; import android.content.res.Resources.NotFoundException; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -40,8 +44,6 @@ import android.util.LongSparseArray; import android.util.Slog; import android.util.TypedValue; import android.util.Xml; -import org.xmlpull.v1.XmlPullParser; -import org.xmlpull.v1.XmlPullParserException; import java.io.InputStream; import java.util.Arrays; @@ -65,7 +67,7 @@ public class ResourcesImpl { private static final boolean TRACE_FOR_PRELOAD = false; private static final boolean TRACE_FOR_MISS_PRELOAD = false; - private static final int LAYOUT_DIR_CONFIG = ActivityInfo.activityInfoConfigToNative( + private static final int LAYOUT_DIR_CONFIG = ActivityInfo.activityInfoConfigJavaToNative( ActivityInfo.CONFIG_LAYOUT_DIRECTION); private static final int ID_OTHER = 0x01000004; @@ -331,7 +333,7 @@ public class ResourcesImpl { // the framework. mCompatibilityInfo.applyToDisplayMetrics(mMetrics); - final int configChanges = calcConfigChanges(config); + final @Config int configChanges = calcConfigChanges(config); LocaleList locales = mConfiguration.getLocales(); if (locales.isEmpty()) { @@ -395,26 +397,30 @@ public class ResourcesImpl { } /** - * Called by ConfigurationBoundResourceCacheTest. + * Applies the new configuration, returning a bitmask of the changes + * between the old and new configurations. + * + * @param config the new configuration + * @return bitmask of config changes */ - public int calcConfigChanges(Configuration config) { - int configChanges = 0xfffffff; - if (config != null) { - mTmpConfig.setTo(config); - int density = config.densityDpi; - if (density == Configuration.DENSITY_DPI_UNDEFINED) { - density = mMetrics.noncompatDensityDpi; - } + public @Config int calcConfigChanges(@Nullable Configuration config) { + if (config == null) { + // If there is no configuration, assume all flags have changed. + return 0xFFFFFFFF; + } - mCompatibilityInfo.applyToConfiguration(density, mTmpConfig); + mTmpConfig.setTo(config); + int density = config.densityDpi; + if (density == Configuration.DENSITY_DPI_UNDEFINED) { + density = mMetrics.noncompatDensityDpi; + } - if (mTmpConfig.getLocales().isEmpty()) { - mTmpConfig.setLocales(LocaleList.getDefault()); - } - configChanges = mConfiguration.updateFrom(mTmpConfig); - configChanges = ActivityInfo.activityInfoConfigToNative(configChanges); + mCompatibilityInfo.applyToConfiguration(density, mTmpConfig); + + if (mTmpConfig.getLocales().isEmpty()) { + mTmpConfig.setLocales(LocaleList.getDefault()); } - return configChanges; + return mConfiguration.updateFrom(mTmpConfig); } /** @@ -593,8 +599,8 @@ public class ResourcesImpl { } } - private boolean verifyPreloadConfig(int changingConfigurations, int allowVarying, - int resourceId, String name) { + private boolean verifyPreloadConfig(@Config int changingConfigurations, + @Config int allowVarying, @AnyRes int resourceId, @Nullable String name) { // We allow preloading of resources even if they vary by font scale (which // doesn't impact resource selection) or density (which we handle specially by // simply turning off all preloading), as well as any other configs specified @@ -1104,7 +1110,7 @@ public class ResourcesImpl { return mAssets.getStyleAttributes(getAppliedStyleResId()); } - int getChangingConfigurations() { + @Config int getChangingConfigurations() { synchronized (mKey) { final int nativeChangingConfig = AssetManager.getThemeChangingConfigurations(mTheme); diff --git a/core/java/android/content/res/ThemedResourceCache.java b/core/java/android/content/res/ThemedResourceCache.java index 9a2d061474e6..f1b1e74a697e 100644 --- a/core/java/android/content/res/ThemedResourceCache.java +++ b/core/java/android/content/res/ThemedResourceCache.java @@ -18,6 +18,7 @@ package android.content.res; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.ActivityInfo.Config; import android.content.res.Resources.Theme; import android.content.res.Resources.ThemeKey; import android.util.LongSparseArray; @@ -115,7 +116,7 @@ abstract class ThemedResourceCache<T> { * * @param configChanges a bitmask of configuration changes */ - public void onConfigurationChange(int configChanges) { + public void onConfigurationChange(@Config int configChanges) { prune(configChanges); } @@ -192,7 +193,7 @@ abstract class ThemedResourceCache<T> { * simply prune missing weak references * @return {@code true} if the cache is completely empty after pruning */ - private boolean prune(int configChanges) { + private boolean prune(@Config int configChanges) { synchronized (this) { if (mThemedEntries != null) { for (int i = mThemedEntries.size() - 1; i >= 0; i--) { @@ -211,7 +212,7 @@ abstract class ThemedResourceCache<T> { } private boolean pruneEntriesLocked(@Nullable LongSparseArray<WeakReference<T>> entries, - int configChanges) { + @Config int configChanges) { if (entries == null) { return true; } @@ -226,7 +227,7 @@ abstract class ThemedResourceCache<T> { return entries.size() == 0; } - private boolean pruneEntryLocked(@Nullable T entry, int configChanges) { + private boolean pruneEntryLocked(@Nullable T entry, @Config int configChanges) { return entry == null || (configChanges != 0 && shouldInvalidateEntry(entry, configChanges)); } diff --git a/core/java/android/content/res/TypedArray.java b/core/java/android/content/res/TypedArray.java index 022bdfb9309e..f6ac0bac125a 100644 --- a/core/java/android/content/res/TypedArray.java +++ b/core/java/android/content/res/TypedArray.java @@ -20,6 +20,8 @@ import android.annotation.AnyRes; import android.annotation.ColorInt; import android.annotation.Nullable; import android.annotation.StyleableRes; +import android.content.pm.ActivityInfo; +import android.content.pm.ActivityInfo.Config; import android.graphics.drawable.Drawable; import android.os.StrictMode; import android.util.AttributeSet; @@ -252,7 +254,8 @@ public class TypedArray { * @throws RuntimeException if the TypedArray has already been recycled. * @hide */ - public String getNonConfigurationString(@StyleableRes int index, int allowedChangingConfigs) { + public String getNonConfigurationString(@StyleableRes int index, + @Config int allowedChangingConfigs) { if (mRecycled) { throw new RuntimeException("Cannot make calls to a recycled instance!"); } @@ -260,7 +263,9 @@ public class TypedArray { index *= AssetManager.STYLE_NUM_ENTRIES; final int[] data = mData; final int type = data[index+AssetManager.STYLE_TYPE]; - if ((data[index+AssetManager.STYLE_CHANGING_CONFIGURATIONS]&~allowedChangingConfigs) != 0) { + final @Config int changingConfigs = ActivityInfo.activityInfoConfigNativeToJava( + data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]); + if ((changingConfigs & ~allowedChangingConfigs) != 0) { return null; } if (type == TypedValue.TYPE_NULL) { @@ -1155,12 +1160,12 @@ public class TypedArray { * @throws RuntimeException if the TypedArray has already been recycled. * @see android.content.pm.ActivityInfo */ - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { if (mRecycled) { throw new RuntimeException("Cannot make calls to a recycled instance!"); } - int changingConfig = 0; + @Config int changingConfig = 0; final int[] data = mData; final int N = length(); @@ -1170,7 +1175,8 @@ public class TypedArray { if (type == TypedValue.TYPE_NULL) { continue; } - changingConfig |= data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]; + changingConfig |= ActivityInfo.activityInfoConfigNativeToJava( + data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]); } return changingConfig; } @@ -1185,7 +1191,8 @@ public class TypedArray { outValue.data = data[index+AssetManager.STYLE_DATA]; outValue.assetCookie = data[index+AssetManager.STYLE_ASSET_COOKIE]; outValue.resourceId = data[index+AssetManager.STYLE_RESOURCE_ID]; - outValue.changingConfigurations = data[index+AssetManager.STYLE_CHANGING_CONFIGURATIONS]; + outValue.changingConfigurations = ActivityInfo.activityInfoConfigNativeToJava( + data[index + AssetManager.STYLE_CHANGING_CONFIGURATIONS]); outValue.density = data[index+AssetManager.STYLE_DENSITY]; outValue.string = (type == TypedValue.TYPE_STRING) ? loadStringValueAt(index) : null; return true; diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java index 8724a96ee30a..38279a47f2a9 100644 --- a/core/java/android/hardware/camera2/CameraCaptureSession.java +++ b/core/java/android/hardware/camera2/CameraCaptureSession.java @@ -990,6 +990,30 @@ public abstract class CameraCaptureSession implements AutoCloseable { int sequenceId) { // default empty implementation } + + /** + * <p>This method is called if a single buffer for a capture could not be sent to its + * destination surface.</p> + * + * <p>If the whole capture failed, then {@link #onCaptureFailed} will be called instead. If + * some but not all buffers were captured but the result metadata will not be available, + * then onCaptureFailed will be invoked with {@link CaptureFailure#wasImageCaptured} + * returning true, along with one or more calls to {@link #onCaptureBufferLost} for the + * failed outputs.</p> + * + * @param session + * The session returned by {@link CameraDevice#createCaptureSession} + * @param request + * The request that was given to the CameraDevice + * @param target + * The target Surface that the buffer will not be produced for + * @param frameNumber + * The frame number for the request + */ + public void onCaptureBufferLost(@NonNull CameraCaptureSession session, + @NonNull CaptureRequest request, @NonNull Surface target, long frameNumber) { + // default empty implementation + } } /** diff --git a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java index 37d2ea2badfb..d84a6fcbd16f 100644 --- a/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java +++ b/core/java/android/hardware/camera2/impl/CameraDeviceImpl.java @@ -1116,6 +1116,11 @@ public class CameraDeviceImpl extends CameraDevice int sequenceId) { // default empty implementation } + + public void onCaptureBufferLost(CameraDevice camera, + CaptureRequest request, Surface target, long frameNumber) { + // default empty implementation + } } /** @@ -1887,48 +1892,66 @@ public class CameraDeviceImpl extends CameraDevice final CaptureRequest request = holder.getRequest(subsequenceId); - // No way to report buffer errors right now + Runnable failureDispatch = null; if (errorCode == ERROR_CAMERA_BUFFER) { - Log.e(TAG, String.format("Lost output buffer reported for frame %d", frameNumber)); - return; - } - - boolean mayHaveBuffers = (errorCode == ERROR_CAMERA_RESULT); - - // This is only approximate - exact handling needs the camera service and HAL to - // disambiguate between request failures to due abort and due to real errors. - // For now, assume that if the session believes we're mid-abort, then the error - // is due to abort. - int reason = (mCurrentSession != null && mCurrentSession.isAborting()) ? - CaptureFailure.REASON_FLUSHED : - CaptureFailure.REASON_ERROR; - - final CaptureFailure failure = new CaptureFailure( - request, - reason, - /*dropped*/ mayHaveBuffers, - requestId, - frameNumber); - - Runnable failureDispatch = new Runnable() { - @Override - public void run() { - if (!CameraDeviceImpl.this.isClosed()){ - holder.getCallback().onCaptureFailed( - CameraDeviceImpl.this, - request, - failure); - } + final Surface outputSurface = + mConfiguredOutputs.get(resultExtras.getErrorStreamId()).getSurface(); + if (DEBUG) { + Log.v(TAG, String.format("Lost output buffer reported for frame %d, target %s", + frameNumber, outputSurface)); } - }; - holder.getHandler().post(failureDispatch); + failureDispatch = new Runnable() { + @Override + public void run() { + if (!CameraDeviceImpl.this.isClosed()){ + holder.getCallback().onCaptureBufferLost( + CameraDeviceImpl.this, + request, + outputSurface, + frameNumber); + } + } + }; + } else { + boolean mayHaveBuffers = (errorCode == ERROR_CAMERA_RESULT); + + // This is only approximate - exact handling needs the camera service and HAL to + // disambiguate between request failures to due abort and due to real errors. For + // now, assume that if the session believes we're mid-abort, then the error is due + // to abort. + int reason = (mCurrentSession != null && mCurrentSession.isAborting()) ? + CaptureFailure.REASON_FLUSHED : + CaptureFailure.REASON_ERROR; + + final CaptureFailure failure = new CaptureFailure( + request, + reason, + /*dropped*/ mayHaveBuffers, + requestId, + frameNumber); + + failureDispatch = new Runnable() { + @Override + public void run() { + if (!CameraDeviceImpl.this.isClosed()){ + holder.getCallback().onCaptureFailed( + CameraDeviceImpl.this, + request, + failure); + } + } + }; - // Fire onCaptureSequenceCompleted if appropriate - if (DEBUG) { - Log.v(TAG, String.format("got error frame %d", frameNumber)); + // Fire onCaptureSequenceCompleted if appropriate + if (DEBUG) { + Log.v(TAG, String.format("got error frame %d", frameNumber)); + } + mFrameNumberTracker.updateTracker(frameNumber, /*error*/true, request.isReprocess()); + checkAndFireSequenceComplete(); } - mFrameNumberTracker.updateTracker(frameNumber, /*error*/true, request.isReprocess()); - checkAndFireSequenceComplete(); + + // Dispatch the failure callback + holder.getHandler().post(failureDispatch); } } // public class CameraDeviceCallbacks diff --git a/core/java/android/hardware/camera2/impl/CaptureResultExtras.java b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java index d859da77f82f..40535e23eaac 100644 --- a/core/java/android/hardware/camera2/impl/CaptureResultExtras.java +++ b/core/java/android/hardware/camera2/impl/CaptureResultExtras.java @@ -28,6 +28,7 @@ public class CaptureResultExtras implements Parcelable { private int precaptureTriggerId; private long frameNumber; private int partialResultCount; + private int errorStreamId; public static final Parcelable.Creator<CaptureResultExtras> CREATOR = new Parcelable.Creator<CaptureResultExtras>() { @@ -48,13 +49,14 @@ public class CaptureResultExtras implements Parcelable { public CaptureResultExtras(int requestId, int subsequenceId, int afTriggerId, int precaptureTriggerId, long frameNumber, - int partialResultCount) { + int partialResultCount, int errorStreamId) { this.requestId = requestId; this.subsequenceId = subsequenceId; this.afTriggerId = afTriggerId; this.precaptureTriggerId = precaptureTriggerId; this.frameNumber = frameNumber; this.partialResultCount = partialResultCount; + this.errorStreamId = errorStreamId; } @Override @@ -70,6 +72,7 @@ public class CaptureResultExtras implements Parcelable { dest.writeInt(precaptureTriggerId); dest.writeLong(frameNumber); dest.writeInt(partialResultCount); + dest.writeInt(errorStreamId); } public void readFromParcel(Parcel in) { @@ -79,6 +82,7 @@ public class CaptureResultExtras implements Parcelable { precaptureTriggerId = in.readInt(); frameNumber = in.readLong(); partialResultCount = in.readInt(); + errorStreamId = in.readInt(); } public int getRequestId() { @@ -104,4 +108,8 @@ public class CaptureResultExtras implements Parcelable { public int getPartialResultCount() { return partialResultCount; } + + public int getErrorStreamId() { + return errorStreamId; + } } diff --git a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java index 4c4adea838ef..661edd734a71 100644 --- a/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java +++ b/core/java/android/hardware/camera2/legacy/LegacyCameraDevice.java @@ -91,11 +91,11 @@ public class LegacyCameraDevice implements AutoCloseable { private CaptureResultExtras getExtrasFromRequest(RequestHolder holder) { if (holder == null) { return new CaptureResultExtras(ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, - ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE); + ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE, ILLEGAL_VALUE); } return new CaptureResultExtras(holder.getRequestId(), holder.getSubsequeceId(), /*afTriggerId*/0, /*precaptureTriggerId*/0, holder.getFrameNumber(), - /*partialResultCount*/1); + /*partialResultCount*/1, /*errorStreamId*/-1); } /** diff --git a/core/java/android/os/Binder.java b/core/java/android/os/Binder.java index d73deb6678eb..ea8ba2f1e6df 100644 --- a/core/java/android/os/Binder.java +++ b/core/java/android/os/Binder.java @@ -70,6 +70,9 @@ public class Binder implements IBinder { private static final boolean CHECK_PARCEL_SIZE = false; static final String TAG = "Binder"; + /** @hide */ + public static boolean LOG_RUNTIME_EXCEPTION = false; // DO NOT SUBMIT WITH TRUE + /** * Control whether dump() calls are allowed. */ @@ -560,17 +563,16 @@ public class Binder implements IBinder { // If the call was FLAG_ONEWAY then these exceptions disappear into the ether. try { res = onTransact(code, data, reply, flags); - } catch (RemoteException e) { - if ((flags & FLAG_ONEWAY) != 0) { - Log.w(TAG, "Binder call failed.", e); - } else { - reply.setDataPosition(0); - reply.writeException(e); + } catch (RemoteException|RuntimeException e) { + if (LOG_RUNTIME_EXCEPTION) { + Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e); } - res = true; - } catch (RuntimeException e) { if ((flags & FLAG_ONEWAY) != 0) { - Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e); + if (e instanceof RemoteException) { + Log.w(TAG, "Binder call failed.", e); + } else { + Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e); + } } else { reply.setDataPosition(0); reply.writeException(e); diff --git a/core/java/android/text/Hyphenator.java b/core/java/android/text/Hyphenator.java index 568b2671ad82..085613f18dad 100644 --- a/core/java/android/text/Hyphenator.java +++ b/core/java/android/text/Hyphenator.java @@ -185,7 +185,6 @@ public class Hyphenator { "de-1901", "de-1996", "de-CH-1901", "en-US", "es", - "eu", "hu", "hy", "nb", diff --git a/core/java/android/util/DisplayMetrics.java b/core/java/android/util/DisplayMetrics.java index a747f163fdca..d201adef2d4d 100644 --- a/core/java/android/util/DisplayMetrics.java +++ b/core/java/android/util/DisplayMetrics.java @@ -154,11 +154,11 @@ public class DisplayMetrics { public static final int DENSITY_DEVICE_STABLE = getDeviceDensity(); /** - * The absolute width of the display in pixels. + * The absolute width of the available display size in pixels. */ public int widthPixels; /** - * The absolute height of the display in pixels. + * The absolute height of the available display size in pixels. */ public int heightPixels; /** diff --git a/core/java/android/util/TypedValue.java b/core/java/android/util/TypedValue.java index 98aaa8149c1c..bd00aba325ea 100644 --- a/core/java/android/util/TypedValue.java +++ b/core/java/android/util/TypedValue.java @@ -17,6 +17,7 @@ package android.util; import android.annotation.AnyRes; +import android.content.pm.ActivityInfo.Config; /** * Container for a dynamically typed data value. Primarily used with @@ -183,9 +184,11 @@ public class TypedValue { @AnyRes public int resourceId; - /** If Value came from a resource, these are the configurations for which - * its contents can change. */ - public int changingConfigurations = -1; + /** + * If the value came from a resource, these are the configurations for + * which its contents can change. + */ + public @Config int changingConfigurations = -1; /** * If the Value came from a resource, this holds the corresponding pixel density. diff --git a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java index 60c727037379..dcf987bc3c12 100644 --- a/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java +++ b/core/java/android/util/apk/ApkSignatureSchemeV2Verifier.java @@ -84,8 +84,19 @@ public class ApkSignatureSchemeV2Verifier { if (fileSize > Integer.MAX_VALUE) { return false; } - MappedByteBuffer apkContents = - apk.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fileSize); + MappedByteBuffer apkContents; + try { + apkContents = apk.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fileSize); + } catch (IOException e) { + if (e.getCause() instanceof OutOfMemoryError) { + // TODO: Remove this temporary workaround once verifying large APKs is + // supported. Very large APKs cannot be memory-mapped. This verification code + // needs to change to use a different approach for verifying such APKs. + return false; // Pretend that this APK does not have a v2 signature. + } else { + throw new IOException("Failed to memory-map APK", e); + } + } // ZipUtils and APK Signature Scheme v2 verifier expect little-endian byte order. apkContents.order(ByteOrder.LITTLE_ENDIAN); @@ -134,11 +145,26 @@ public class ApkSignatureSchemeV2Verifier { if (fileSize > Integer.MAX_VALUE) { throw new IOException("File too large: " + apk.length() + " bytes"); } - MappedByteBuffer apkContents = - apk.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fileSize); - // Attempt to preload the contents into memory for faster overall verification (v2 and - // older) at the expense of somewhat increased latency for rejecting malformed APKs. - apkContents.load(); + MappedByteBuffer apkContents; + try { + apkContents = apk.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, fileSize); + // Attempt to preload the contents into memory for faster overall verification (v2 and + // older) at the expense of somewhat increased latency for rejecting malformed APKs. + apkContents.load(); + } catch (IOException e) { + if (e.getCause() instanceof OutOfMemoryError) { + // TODO: Remove this temporary workaround once verifying large APKs is supported. + // Very large APKs cannot be memory-mapped. This verification code needs to change + // to use a different approach for verifying such APKs. + // This workaround pretends that this APK does not have a v2 signature. This works + // fine provided the APK is not actually v2-signed. If the APK is v2 signed, v2 + // signature stripping protection inside v1 signature verification code will reject + // this APK. + throw new SignatureNotFoundException("Failed to memory-map APK", e); + } else { + throw new IOException("Failed to memory-map APK", e); + } + } return verify(apkContents); } diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java index 1269ad93d306..fb6a9d552c54 100644 --- a/core/java/android/view/Display.java +++ b/core/java/android/view/Display.java @@ -762,14 +762,23 @@ public final class Display { /** * Gets display metrics that describe the size and density of this display. + * The size returned by this method does not necessarily represent the + * actual raw size (native resolution) of the display. * <p> - * The size is adjusted based on the current rotation of the display. + * 1. The returned size may be adjusted to exclude certain system decor elements + * that are always visible. * </p><p> - * The size returned by this method does not necessarily represent the - * actual raw size (native resolution) of the display. The returned size may - * be adjusted to exclude certain system decor elements that are always visible. - * It may also be scaled to provide compatibility with older applications that + * 2. It may be scaled to provide compatibility with older applications that * were originally designed for smaller displays. + * </p><p> + * 3. It can be different depending on the WindowManager to which the display belongs. + * <pre> + * - If requested from non-Activity context (e.g. Application context via + * {@code (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)}) + * metrics will report real size of the display based on current rotation. + * - If requested from activity resulting metrics will correspond to current window metrics. + * In this case the size can be smaller than physical size in multi-window mode. + * </pre> * </p> * * @param outMetrics A {@link DisplayMetrics} object to receive the metrics. @@ -807,7 +816,7 @@ public final class Display { * The size is adjusted based on the current rotation of the display. * </p><p> * The real size may be smaller than the physical size of the screen when the - * window manager is emulating a smaller display (using adb shell am display-size). + * window manager is emulating a smaller display (using adb shell wm size). * </p> * * @param outMetrics A {@link DisplayMetrics} object to receive the metrics. @@ -816,8 +825,7 @@ public final class Display { synchronized (this) { updateDisplayInfoLocked(); mDisplayInfo.getLogicalMetrics(outMetrics, - CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, - mDisplayAdjustments.getConfiguration()); + CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); } } diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 9bd3df0c1a1f..57ab6d400cd9 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -17505,7 +17505,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * {@link SystemClock#uptimeMillis} timebase. */ @Override - public void scheduleDrawable(Drawable who, Runnable what, long when) { + public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { if (verifyDrawable(who) && what != null) { final long delay = when - SystemClock.uptimeMillis(); if (mAttachInfo != null) { @@ -17527,7 +17527,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @param what the action to cancel */ @Override - public void unscheduleDrawable(Drawable who, Runnable what) { + public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { if (verifyDrawable(who) && what != null) { if (mAttachInfo != null) { mAttachInfo.mViewRootImpl.mChoreographer.removeCallbacks( @@ -17637,7 +17637,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback, * @see #drawableStateChanged() */ @CallSuper - protected boolean verifyDrawable(Drawable who) { + protected boolean verifyDrawable(@NonNull Drawable who) { // Avoid verifying the scroll bar drawable so that we don't end up in // an invalidation loop. This effectively prevents the scroll bar // drawable from triggering invalidations and scheduling runnables. diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index d29bc21ce60b..56ee47895687 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -1382,6 +1382,13 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager if (mIsInterestedInDrag) { retval = true; } + + if (!retval) { + // Neither us nor any of our children are interested in this drag, so stop tracking + // the current drag event. + mCurrentDragStartEvent.recycle(); + mCurrentDragStartEvent = null; + } } break; case DragEvent.ACTION_DRAG_ENDED: { diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java index 0d05c542215d..69c30bac723a 100644 --- a/core/java/android/view/ViewOverlay.java +++ b/core/java/android/view/ViewOverlay.java @@ -170,7 +170,7 @@ public class ViewOverlay { } @Override - protected boolean verifyDrawable(Drawable who) { + protected boolean verifyDrawable(@NonNull Drawable who) { return super.verifyDrawable(who) || (mDrawables != null && mDrawables.contains(who)); } @@ -229,7 +229,7 @@ public class ViewOverlay { } @Override - public void invalidateDrawable(Drawable drawable) { + public void invalidateDrawable(@NonNull Drawable drawable) { invalidate(drawable.getBounds()); } diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index b011414bc556..34e81fcd074c 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -405,6 +405,12 @@ public interface WindowManagerPolicy { * not attached to any stack. */ int getStackId(); + + /** + * Returns true if the window is current in multi-windowing mode. i.e. it shares the + * screen with other application windows. + */ + public boolean inMultiWindowMode(); } /** diff --git a/core/java/android/view/animation/BaseInterpolator.java b/core/java/android/view/animation/BaseInterpolator.java index 9c0014c951c3..a78fa1eac039 100644 --- a/core/java/android/view/animation/BaseInterpolator.java +++ b/core/java/android/view/animation/BaseInterpolator.java @@ -16,22 +16,24 @@ package android.view.animation; +import android.content.pm.ActivityInfo.Config; + /** * An abstract class which is extended by default interpolators. */ abstract public class BaseInterpolator implements Interpolator { - private int mChangingConfiguration; + private @Config int mChangingConfiguration; /** * @hide */ - public int getChangingConfiguration() { + public @Config int getChangingConfiguration() { return mChangingConfiguration; } /** * @hide */ - void setChangingConfiguration(int changingConfiguration) { + void setChangingConfiguration(@Config int changingConfiguration) { mChangingConfiguration = changingConfiguration; } } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index d2aef0ac362c..7cbe8de67492 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -2864,7 +2864,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } @Override - public boolean verifyDrawable(Drawable dr) { + public boolean verifyDrawable(@NonNull Drawable dr) { return mSelector == dr || super.verifyDrawable(dr); } diff --git a/core/java/android/widget/AbsSeekBar.java b/core/java/android/widget/AbsSeekBar.java index 34f3a47393ba..878a9eb940cd 100644 --- a/core/java/android/widget/AbsSeekBar.java +++ b/core/java/android/widget/AbsSeekBar.java @@ -18,6 +18,7 @@ package android.widget; import com.android.internal.R; +import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.content.res.ColorStateList; @@ -485,7 +486,7 @@ public abstract class AbsSeekBar extends ProgressBar { } @Override - protected boolean verifyDrawable(Drawable who) { + protected boolean verifyDrawable(@NonNull Drawable who) { return who == mThumb || who == mTickMark || super.verifyDrawable(who); } diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java index 9f94005ff778..df506ca65da0 100644 --- a/core/java/android/widget/CheckedTextView.java +++ b/core/java/android/widget/CheckedTextView.java @@ -308,7 +308,7 @@ public class CheckedTextView extends TextView implements Checkable { } @Override - protected boolean verifyDrawable(Drawable who) { + protected boolean verifyDrawable(@NonNull Drawable who) { return who == mCheckMarkDrawable || super.verifyDrawable(who); } diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java index b19fe17054d7..5d7585f9d9e8 100644 --- a/core/java/android/widget/CompoundButton.java +++ b/core/java/android/widget/CompoundButton.java @@ -474,7 +474,7 @@ public abstract class CompoundButton extends Button implements Checkable { } @Override - protected boolean verifyDrawable(Drawable who) { + protected boolean verifyDrawable(@NonNull Drawable who) { return super.verifyDrawable(who) || who == mButtonDrawable; } diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java index f601f7df1fa8..3400873896f8 100644 --- a/core/java/android/widget/ImageView.java +++ b/core/java/android/widget/ImageView.java @@ -212,7 +212,7 @@ public class ImageView extends View { } @Override - protected boolean verifyDrawable(Drawable dr) { + protected boolean verifyDrawable(@NonNull Drawable dr) { return mDrawable == dr || super.verifyDrawable(dr); } @@ -223,7 +223,7 @@ public class ImageView extends View { } @Override - public void invalidateDrawable(Drawable dr) { + public void invalidateDrawable(@NonNull Drawable dr) { if (dr == mDrawable) { if (dr != null) { // update cached drawable dimensions if they've changed diff --git a/core/java/android/widget/ProgressBar.java b/core/java/android/widget/ProgressBar.java index 72a50ec1af90..ce948706542f 100644 --- a/core/java/android/widget/ProgressBar.java +++ b/core/java/android/widget/ProgressBar.java @@ -1229,7 +1229,7 @@ public class ProgressBar extends View { } @Override - protected boolean verifyDrawable(Drawable who) { + protected boolean verifyDrawable(@NonNull Drawable who) { return who == mProgressDrawable || who == mIndeterminateDrawable || super.verifyDrawable(who); } @@ -1692,7 +1692,7 @@ public class ProgressBar extends View { } @Override - public void invalidateDrawable(Drawable dr) { + public void invalidateDrawable(@NonNull Drawable dr) { if (!mInDrawing) { if (verifyDrawable(dr)) { final Rect dirty = dr.getBounds(); diff --git a/core/java/android/widget/ScrollBarDrawable.java b/core/java/android/widget/ScrollBarDrawable.java index 8880217d9461..11eab2adad30 100644 --- a/core/java/android/widget/ScrollBarDrawable.java +++ b/core/java/android/widget/ScrollBarDrawable.java @@ -18,6 +18,7 @@ package android.widget; import com.android.internal.widget.ScrollBarUtils; +import android.annotation.NonNull; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.PixelFormat; @@ -362,17 +363,17 @@ public class ScrollBarDrawable extends Drawable implements Drawable.Callback { } @Override - public void invalidateDrawable(Drawable who) { + public void invalidateDrawable(@NonNull Drawable who) { invalidateSelf(); } @Override - public void scheduleDrawable(Drawable who, Runnable what, long when) { + public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { scheduleSelf(what, when); } @Override - public void unscheduleDrawable(Drawable who, Runnable what) { + public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { unscheduleSelf(what); } diff --git a/core/java/android/widget/Switch.java b/core/java/android/widget/Switch.java index 434516da1346..c4a17715896c 100644 --- a/core/java/android/widget/Switch.java +++ b/core/java/android/widget/Switch.java @@ -18,6 +18,7 @@ package android.widget; import android.animation.ObjectAnimator; import android.annotation.DrawableRes; +import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.StyleRes; import android.content.Context; @@ -1371,7 +1372,7 @@ public class Switch extends CompoundButton { } @Override - protected boolean verifyDrawable(Drawable who) { + protected boolean verifyDrawable(@NonNull Drawable who) { return super.verifyDrawable(who) || who == mThumbDrawable || who == mTrackDrawable; } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index 0ce4a122d2ee..e971f865bf45 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -5470,7 +5470,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } @Override - protected boolean verifyDrawable(Drawable who) { + protected boolean verifyDrawable(@NonNull Drawable who) { final boolean verified = super.verifyDrawable(who); if (!verified && mDrawables != null) { for (Drawable dr : mDrawables.mShowing) { @@ -5495,7 +5495,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } @Override - public void invalidateDrawable(Drawable drawable) { + public void invalidateDrawable(@NonNull Drawable drawable) { boolean handled = false; if (verifyDrawable(drawable)) { diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl index b13be97dfb98..3a31b370a417 100644 --- a/core/java/com/android/internal/app/IAppOpsService.aidl +++ b/core/java/com/android/internal/app/IAppOpsService.aidl @@ -45,6 +45,6 @@ interface IAppOpsService { void setAudioRestriction(int code, int usage, int uid, int mode, in String[] exceptionPackages); void setUserRestrictions(in Bundle restrictions, IBinder token, int userHandle); - void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle); + void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, in String[] exceptionPackages); void removeUser(int userHandle); } diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java index 7a3c253a8544..90ee05ec944b 100644 --- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java +++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java @@ -505,7 +505,6 @@ public class InputMethodUtils { final int numSubtypes = subtypes.size(); // Handle overridesImplicitlyEnabledSubtype mechanism. - final String systemLanguage = systemLocales.get(0).getLanguage(); final HashMap<String, InputMethodSubtype> applicableModeAndSubtypesMap = new HashMap<>(); for (int i = 0; i < numSubtypes; ++i) { // scan overriding implicitly enabled subtypes. @@ -521,25 +520,20 @@ public class InputMethodUtils { return new ArrayList<>(applicableModeAndSubtypesMap.values()); } + final HashMap<String, ArrayList<InputMethodSubtype>> nonKeyboardSubtypesMap = + new HashMap<>(); final ArrayList<InputMethodSubtype> keyboardSubtypes = new ArrayList<>(); + for (int i = 0; i < numSubtypes; ++i) { final InputMethodSubtype subtype = subtypes.get(i); - if (TextUtils.equals(SUBTYPE_MODE_KEYBOARD, subtype.getMode())) { + final String mode = subtype.getMode(); + if (SUBTYPE_MODE_KEYBOARD.equals(mode)) { keyboardSubtypes.add(subtype); } else { - final Locale locale = subtype.getLocaleObject(); - final String mode = subtype.getMode(); - // TODO: Use LocaleUtils#filterByLanguage() instead. - if (locale != null && TextUtils.equals(locale.getLanguage(), systemLanguage)) { - final InputMethodSubtype applicableSubtype = - applicableModeAndSubtypesMap.get(mode); - // If more applicable subtypes are contained, skip. - if (applicableSubtype != null) { - if (systemLocale.equals(applicableSubtype.getLocaleObject())) continue; - if (!systemLocale.equals(locale)) continue; - } - applicableModeAndSubtypesMap.put(mode, subtype); + if (!nonKeyboardSubtypesMap.containsKey(mode)) { + nonKeyboardSubtypesMap.put(mode, new ArrayList<>()); } + nonKeyboardSubtypesMap.get(mode).add(subtype); } } @@ -578,7 +572,12 @@ public class InputMethodUtils { } } - applicableSubtypes.addAll(applicableModeAndSubtypesMap.values()); + // For each non-keyboard mode, extract subtypes with system locales. + for (final ArrayList<InputMethodSubtype> subtypeList : nonKeyboardSubtypesMap.values()) { + LocaleUtils.filterByLanguage(subtypeList, sSubtypeToLocale, systemLocales, + applicableSubtypes); + } + return applicableSubtypes; } diff --git a/core/java/com/android/internal/widget/ActionBarContainer.java b/core/java/com/android/internal/widget/ActionBarContainer.java index 398bbe7af73c..baf3188fb235 100644 --- a/core/java/com/android/internal/widget/ActionBarContainer.java +++ b/core/java/com/android/internal/widget/ActionBarContainer.java @@ -147,7 +147,7 @@ public class ActionBarContainer extends FrameLayout { } @Override - protected boolean verifyDrawable(Drawable who) { + protected boolean verifyDrawable(@NonNull Drawable who) { return (who == mBackground && !mIsSplit) || (who == mStackedBackground && mIsStacked) || (who == mSplitBackground && mIsSplit) || super.verifyDrawable(who); } diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java index 948a6bb42744..277fafd4adf7 100644 --- a/core/java/com/android/internal/widget/ViewPager.java +++ b/core/java/com/android/internal/widget/ViewPager.java @@ -17,6 +17,7 @@ package com.android.internal.widget; import android.annotation.DrawableRes; +import android.annotation.NonNull; import android.content.Context; import android.content.res.Resources; import android.content.res.TypedArray; @@ -746,7 +747,7 @@ public class ViewPager extends ViewGroup { } @Override - protected boolean verifyDrawable(Drawable who) { + protected boolean verifyDrawable(@NonNull Drawable who) { return super.verifyDrawable(who) || who == mMarginDrawable; } diff --git a/core/java/com/android/server/backup/SystemBackupAgent.java b/core/java/com/android/server/backup/SystemBackupAgent.java index cee98b8248e9..181ed5144310 100644 --- a/core/java/com/android/server/backup/SystemBackupAgent.java +++ b/core/java/com/android/server/backup/SystemBackupAgent.java @@ -70,6 +70,8 @@ public class SystemBackupAgent extends BackupAgentHelper { private static final String WALLPAPER_IMAGE_KEY = WallpaperBackupHelper.WALLPAPER_IMAGE_KEY; private static final String WALLPAPER_INFO_KEY = WallpaperBackupHelper.WALLPAPER_INFO_KEY; + private WallpaperBackupHelper mWallpaperHelper = null; + @Override public void onBackup(ParcelFileDescriptor oldState, BackupDataOutput data, ParcelFileDescriptor newState) throws IOException { @@ -121,13 +123,16 @@ public class SystemBackupAgent extends BackupAgentHelper { @Override public void onRestore(BackupDataInput data, int appVersionCode, ParcelFileDescriptor newState) throws IOException { - // On restore, we also support a previous data schema "system_files" - addHelper(WALLPAPER_HELPER, new WallpaperBackupHelper(this, + mWallpaperHelper = new WallpaperBackupHelper(this, new String[] { WALLPAPER_IMAGE, WALLPAPER_INFO }, - new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY} )); + new String[] { WALLPAPER_IMAGE_KEY, WALLPAPER_INFO_KEY} ); + addHelper(WALLPAPER_HELPER, mWallpaperHelper); + + // On restore, we also support a previous data schema "system_files" addHelper("system_files", new WallpaperBackupHelper(this, new String[] { WALLPAPER_IMAGE }, new String[] { WALLPAPER_IMAGE_KEY} )); + addHelper(SYNC_SETTINGS_HELPER, new AccountSyncSettingsBackupHelper(this)); addHelper(PREFERRED_HELPER, new PreferredActivityBackupHelper()); addHelper(NOTIFICATION_HELPER, new NotificationBackupHelper(this)); @@ -202,4 +207,9 @@ public class SystemBackupAgent extends BackupAgentHelper { } } } + + @Override + public void onRestoreFinished() { + mWallpaperHelper.onRestoreFinished(); + } } diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 2a04526ed3eb..798a6deb92f9 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -1184,8 +1184,7 @@ static int javaDetachThread(void) void** args = (void**) malloc(3 * sizeof(void*)); // javaThreadShell must free int result; - if (!threadName) - threadName = "unnamed thread"; + LOG_ALWAYS_FATAL_IF(threadName == nullptr, "threadName not provided to javaCreateThreadEtc"); args[0] = (void*) entryFunction; args[1] = userData; diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index fbc96c262cfc..6444c6c94dc4 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -1483,11 +1483,21 @@ <!-- Allows an application to manage access to documents, usually as part of a document picker. + <p>This permission should <em>only</em> be requested by the platform + document management app. This permission cannot be granted to + third-party apps. <p>Protection level: signature --> <permission android:name="android.permission.MANAGE_DOCUMENTS" android:protectionLevel="signature" /> + <!-- @hide Allows an application to cache content. + <p>Not for use by third-party applications. + <p>Protection level: signature + --> + <permission android:name="android.permission.CACHE_CONTENT" + android:protectionLevel="signature" /> + <!-- ================================== --> <!-- Permissions for screenlock --> <!-- ================================== --> diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml index 3c4ce89e5988..3953264e638f 100644 --- a/core/res/res/values-az-rAZ/strings.xml +++ b/core/res/res/values-az-rAZ/strings.xml @@ -1051,12 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Əlavə seçimlər üçün toxunun."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB sazlama qoşuludur"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB debaqı deaktivasiya etmək üçün toxunun."</string> - <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Baq hesabat verilir..."</string> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Baq hesabatı verilir..."</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Baq hesabatı paylaşılsın?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Baq hesabatı paylaşılır..."</string> - <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IT admininiz bu cihazda nasazlıqların aşkarlanması üçün baq hesabatı sorğusu göndərdi. Tətbiqlər və data paylaşıla bilər."</string> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"İT admininiz bu cihazda nasazlıqların aşkarlanması üçün baq hesabatı sorğusu göndərdi. Tətbiqlər və data paylaşıla bilər."</string> <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PAYLAŞIN"</string> - <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RƏDD ET"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RƏDD EDİN"</string> <string name="select_input_method" msgid="8547250819326693584">"Klaviaturanı dəyişin"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Klaviaturaları seçin"</string> <string name="show_ime" msgid="2506087537466597099">"Fiziki klaviatura aktiv olduğu halda ekranda saxlayın"</string> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index d44c07eb63fc..65f5f240d2d6 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -909,8 +909,8 @@ <string name="noApplications" msgid="2991814273936504689">"Ninguna aplicación puede realizar esta acción."</string> <string name="aerr_application" msgid="250320989337856518">"La aplicación <xliff:g id="APPLICATION">%1$s</xliff:g> ha dejado de funcionar"</string> <string name="aerr_process" msgid="6201597323218674729">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> ha dejado de funcionar"</string> - <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> sigue dejando de funcionar"</string> - <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> sigue dejando de funcionar"</string> + <string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> sigue sin funcionar"</string> + <string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> sigue sin funcionar"</string> <string name="aerr_restart" msgid="9001379185665886595">"Reiniciar aplicación"</string> <string name="aerr_reset" msgid="7645427603514220451">"Restablecer y reiniciar aplicación"</string> <string name="aerr_report" msgid="5371800241488400617">"Enviar sugerencias"</string> @@ -1135,7 +1135,7 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fondo de pantalla"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambiar fondo de pantalla"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Detector de notificaciones"</string> - <string name="vr_listener_binding_label" msgid="4316591939343607306">"Procesador de Realidad Virtual"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Procesador de RV"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Proveedor de condiciones"</string> <string name="notification_ranker_binding_label" msgid="774540592299064747">"Servicio de clasificación de notificaciones"</string> <string name="vpn_title" msgid="19615213552042827">"VPN activada"</string> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 8ac349061c5a..c79befabcc68 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -1151,7 +1151,7 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"טפט"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"שנה טפט"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"מאזין להתראות"</string> - <string name="vr_listener_binding_label" msgid="4316591939343607306">"מאזין VR"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR ליסנר"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"ספק תנאי"</string> <string name="notification_ranker_binding_label" msgid="774540592299064747">"שירות של דירוג הודעות"</string> <string name="vpn_title" msgid="19615213552042827">"VPN מופעל"</string> diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml index 24b5e07dea5b..6d31dd1f195d 100644 --- a/core/res/res/values-kk-rKZ/strings.xml +++ b/core/res/res/values-kk-rKZ/strings.xml @@ -1135,7 +1135,7 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Артқы фоны"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Артқы фонын өзгерту"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Хабар бақылағыш"</string> - <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR тыңдаушы"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Виртуалды шынайылық тыңдаушысы"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Шарт провайдері"</string> <string name="notification_ranker_binding_label" msgid="774540592299064747">"Хабарландыруларды жіктеу қызметі"</string> <string name="vpn_title" msgid="19615213552042827">"VPN белсенді"</string> diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml index fe89bf9237d8..3a30b55fb7a4 100644 --- a/core/res/res/values-ky-rKG/strings.xml +++ b/core/res/res/values-ky-rKG/strings.xml @@ -1136,7 +1136,7 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Тушкагаз"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Тушкагазды өзгөртүү"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Эскертүү тыңшагычы"</string> - <string name="vr_listener_binding_label" msgid="4316591939343607306">"Виртуалдык угуучу"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR режими"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Шарт түзүүчү"</string> <string name="notification_ranker_binding_label" msgid="774540592299064747">"Эскертмени баалоо кызматы"</string> <string name="vpn_title" msgid="19615213552042827">"VPN иштетилди"</string> diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml index 4ca18252352b..f95a37d62e05 100644 --- a/core/res/res/values-uz-rUZ/strings.xml +++ b/core/res/res/values-uz-rUZ/strings.xml @@ -1135,7 +1135,7 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fon rasmi"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Fon rasmini o‘zgartirish"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Bildirishnoma tinglovchisi"</string> - <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR tinglovchisi"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR rejimi"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Shartlarni taqdim etuvchi"</string> <string name="notification_ranker_binding_label" msgid="774540592299064747">"Bildirishnomalarni baholash xizmati"</string> <string name="vpn_title" msgid="19615213552042827">"VPN faollashtirildi"</string> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index ce5d07c1e6ed..01b2c4715a49 100644 --- a/core/res/res/values/config.xml +++ b/core/res/res/values/config.xml @@ -805,6 +805,13 @@ --> <integer name="config_longPressOnPowerBehavior">1</integer> + <!-- Control the behavior when the user long presses the back button. Non-zero values are only + valid for watches as part of CDD/CTS. + 0 - Nothing + 1 - Go to voice assist + --> + <integer name="config_longPressOnBackBehavior">0</integer> + <!-- Control the behavior when the user short presses the power button. 0 - Nothing 1 - Go to sleep (doze) @@ -1853,6 +1860,10 @@ <item>-1</item> </integer-array> + <!-- When true, local displays that do not contain any of their own content will automatically + mirror the content of the default display. --> + <bool name="config_localDisplaysMirrorContent">true</bool> + <!-- When true use the linux /dev/input/event subsystem to detect the switch changes on the headphone/microphone jack. When false use the older uevent framework. --> <bool name="config_useDevInputEventForAudioJack">false</bool> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index 70f4f54b1ffe..32a0131879b0 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -306,6 +306,7 @@ <java-symbol type="bool" name="config_freeformWindowManagement" /> <java-symbol type="bool" name="config_supportsMultiWindow" /> <java-symbol type="bool" name="config_guestUserEphemeral" /> + <java-symbol type="bool" name="config_localDisplaysMirrorContent" /> <java-symbol type="string" name="config_defaultPictureInPictureBounds" /> <java-symbol type="string" name="config_centeredPictureInPictureBounds" /> <java-symbol type="string" name="config_pictureInPictureBoundsInRecents" /> @@ -382,6 +383,7 @@ <java-symbol type="integer" name="config_extraFreeKbytesAbsolute" /> <java-symbol type="integer" name="config_immersive_mode_confirmation_panic" /> <java-symbol type="integer" name="config_longPressOnPowerBehavior" /> + <java-symbol type="integer" name="config_longPressOnBackBehavior" /> <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAdjust" /> <java-symbol type="integer" name="config_lowMemoryKillerMinFreeKbytesAbsolute" /> <java-symbol type="integer" name="config_max_pan_devices" /> diff --git a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java index c92863d93fda..b908d9267319 100644 --- a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java +++ b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java @@ -905,6 +905,10 @@ public class ValueAnimatorTests extends ActivityInstrumentationTestCase2<BasicAn a1.start(); a2.reverse(); a3.start(); + // Check that the animators' values are immediately set to end value in the case of + // 0-duration. + assertEquals(A1_END_VALUE, a1.getAnimatedValue()); + assertEquals(A2_START_VALUE, a2.getAnimatedValue()); } }); Thread.sleep(POLL_INTERVAL); @@ -951,6 +955,10 @@ public class ValueAnimatorTests extends ActivityInstrumentationTestCase2<BasicAn a1.start(); a2.start(); + + // In the case of 0 duration scale applied to a non-0 duration, check that the + // value is immediately set to the start value. + assertEquals(A2_START_VALUE, a2.getAnimatedValue()); } }); Thread.sleep(POLL_INTERVAL); @@ -962,6 +970,8 @@ public class ValueAnimatorTests extends ActivityInstrumentationTestCase2<BasicAn assertTrue(l2.startCalled); assertTrue(l1.endCalled); assertTrue(l2.endCalled); + assertEquals(A1_END_VALUE, a1.getAnimatedValue()); + assertEquals(A2_END_VALUE, a2.getAnimatedValue()); } }); diff --git a/core/tests/coretests/src/android/text/method/BackspaceTest.java b/core/tests/coretests/src/android/text/method/BackspaceTest.java index d2e811cd8ece..3be9cfc2d6e6 100644 --- a/core/tests/coretests/src/android/text/method/BackspaceTest.java +++ b/core/tests/coretests/src/android/text/method/BackspaceTest.java @@ -29,7 +29,8 @@ import android.widget.TextView.BufferType; /** * Test backspace key handling of {@link android.text.method.BaseKeyListner}. * - * TODO: Move some of test cases to the CTS. + * Only contains edge cases. For normal cases, see {@see android.text.method.cts.BackspaceTest}. + * TODO: introduce test cases for surrogate pairs and replacement span. */ public class BackspaceTest extends KeyListenerTestCase { private static final BaseKeyListener mKeyListener = new BaseKeyListener() { @@ -65,85 +66,9 @@ public class BackspaceTest extends KeyListenerTestCase { } @SmallTest - public void testSurrogatePairs() { - EditorState state = new EditorState(); - - state.setByString("U+1F441 |"); - backspace(state, 0); - state.assertEquals("|"); - - state.setByString("U+1F441 U+1F5E8 |"); - backspace(state, 0); - state.assertEquals("U+1F441 |"); - backspace(state, 0); - state.assertEquals("|"); - - // TODO: introduce edge cases. - } - - @SmallTest - public void testReplacementSpan() { - EditorState state = new EditorState(); - - // ReplacementSpan will be set to "()" region. - state.setByString("'abc' ( 'de' ) 'fg' |"); - backspace(state, 0); - state.assertEquals("'abc' ( 'de' ) 'f' |"); - backspace(state, 0); - state.assertEquals("'abc' ( 'de' ) |"); - backspace(state, 0); - state.assertEquals("'abc' |"); - backspace(state, 0); - state.assertEquals("'ab' |"); - backspace(state, 0); - state.assertEquals("'a' |"); - backspace(state, 0); - state.assertEquals("|"); - - state.setByString("'abc' [ ( 'de' ) ] 'fg'"); - backspace(state, 0); - state.assertEquals("'abc' | 'fg'"); - backspace(state, 0); - state.assertEquals("'ab' | 'fg'"); - backspace(state, 0); - state.assertEquals("'a' | 'fg'"); - backspace(state, 0); - state.assertEquals("| 'fg'"); - backspace(state, 0); - state.assertEquals("| 'fg'"); - - state.setByString("'ab' [ 'c' ( 'de' ) 'f' ] 'g'"); - backspace(state, 0); - state.assertEquals("'ab' | 'g'"); - backspace(state, 0); - state.assertEquals("'a' | 'g'"); - backspace(state, 0); - state.assertEquals("| 'g'"); - backspace(state, 0); - state.assertEquals("| 'g'"); - - // TODO: introduce edge cases. - } - - @SmallTest public void testCombiningEnclosingKeycaps() { EditorState state = new EditorState(); - // U+20E3 is COMBINING ENCLOSING KEYCAP. - state.setByString("'1' U+20E3 |"); - backspace(state, 0); - state.assertEquals("|"); - - // Variation selector before COMBINING ECLOSING KEYCAP - state.setByString("'1' U+FE0E U+20E3 |"); - backspace(state, 0); - state.assertEquals("|"); - - state.setByString("'1' U+E0101 U+20E3 |"); - backspace(state, 0); - state.assertEquals("|"); - - // Edge cases // multiple COMBINING ENCLOSING KEYCAP state.setByString("'1' U+20E3 U+20E3 |"); backspace(state, 0); @@ -168,17 +93,6 @@ public class BackspaceTest extends KeyListenerTestCase { public void testVariationSelector() { EditorState state = new EditorState(); - // U+FE0F is VARIATION SELECTOR-16. - state.setByString("'#' U+FE0F |"); - backspace(state, 0); - state.assertEquals("|"); - - // U+E0100 is VARIATION SELECTOR-17. - state.setByString("U+845B U+E0100 |"); - backspace(state, 0); - state.assertEquals("|"); - - // Edge cases // Isolated variation selector state.setByString("U+FE0F |"); backspace(state, 0); @@ -243,20 +157,6 @@ public class BackspaceTest extends KeyListenerTestCase { public void testEmojiZWJSequence() { EditorState state = new EditorState(); - // U+200D is ZERO WIDTH JOINER. - state.setByString("U+1F441 U+200D U+1F5E8 |"); - backspace(state, 0); - state.assertEquals("|"); - - state.setByString("U+1F441 U+200D U+1F5E8 U+FE0E |"); - backspace(state, 0); - state.assertEquals("|"); - - state.setByString("U+1F468 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F468 |"); - backspace(state, 0); - state.assertEquals("|"); - - // Edge cases // End with ZERO WIDTH JOINER state.setByString("U+1F441 U+200D |"); backspace(state, 0); @@ -307,35 +207,6 @@ public class BackspaceTest extends KeyListenerTestCase { public void testFlags() { EditorState state = new EditorState(); - // U+1F1FA is REGIONAL INDICATOR SYMBOL LETTER U. - // U+1F1F8 is REGIONAL INDICATOR SYMBOL LETTER S. - state.setByString("U+1F1FA U+1F1F8 |"); - backspace(state, 0); - state.assertEquals("|"); - - state.setByString("'a' U+1F1FA U+1F1F8 |"); - backspace(state, 0); - state.assertEquals("'a' |"); - backspace(state, 0); - state.assertEquals("|"); - - state.setByString("U+1F1FA U+1F1F8 U+1F1FA U+1F1F8 |"); - backspace(state, 0); - state.assertEquals("U+1F1FA U+1F1F8 |"); - backspace(state, 0); - state.assertEquals("|"); - - state.setByString("'a' U+1F1FA U+1F1F8 'b' U+1F1FA U+1F1F8 |"); - backspace(state, 0); - state.assertEquals("'a' U+1F1FA U+1F1F8 'b' |"); - backspace(state, 0); - state.assertEquals("'a' U+1F1FA U+1F1F8 |"); - backspace(state, 0); - state.assertEquals("'a' |"); - backspace(state, 0); - state.assertEquals("|"); - - // Edcae cases // Isolated regional indicator symbol state.setByString("U+1F1FA |"); backspace(state, 0); @@ -353,12 +224,6 @@ public class BackspaceTest extends KeyListenerTestCase { public void testEmojiModifier() { EditorState state = new EditorState(); - // U+1F3FB is EMOJI MODIFIER FITZPATRICK TYPE-1-2. - state.setByString("U+1F466 U+1F3FB |"); - backspace(state, 0); - state.assertEquals("|"); - - // Edge cases // Isolated emoji modifier state.setByString("U+1F3FB |"); backspace(state, 0); diff --git a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java index da17045d0855..f7dab2d7bdbf 100644 --- a/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java +++ b/core/tests/coretests/src/android/text/method/ForwardDeleteTest.java @@ -29,7 +29,8 @@ import android.widget.TextView.BufferType; /** * Test forward delete key handling of {@link android.text.method.BaseKeyListener}. * - * TODO: Move some of test cases to the CTS. + * Only contains edge cases. For normal cases, see {@see android.text.method.cts.ForwardDeleteTest}. + * TODO: introduce test cases for surrogate pairs and replacement span. */ public class ForwardDeleteTest extends KeyListenerTestCase { private static final BaseKeyListener mKeyListener = new BaseKeyListener() { @@ -65,73 +66,9 @@ public class ForwardDeleteTest extends KeyListenerTestCase { } @SmallTest - public void testSurrogatePairs() { - EditorState state = new EditorState(); - - // U+1F441 is EYE - state.setByString("| U+1F441"); - forwardDelete(state, 0); - state.assertEquals("|"); - - // U+1F5E8 is LEFT SPEECH BUBBLE - state.setByString("| U+1F441 U+1F5E8"); - forwardDelete(state, 0); - state.assertEquals("| U+1F5E8"); - forwardDelete(state, 0); - state.assertEquals("|"); - - // TODO: introduce edge cases. - } - - @SmallTest - public void testReplacementSpan() { - EditorState state = new EditorState(); - - state.setByString("| 'abc' ( 'de' ) 'fg'"); - forwardDelete(state, 0); - state.assertEquals("| 'bc' ( 'de' ) 'fg'"); - forwardDelete(state, 0); - state.assertEquals("| 'c' ( 'de' ) 'fg'"); - forwardDelete(state, 0); - state.assertEquals("| ( 'de' ) 'fg'"); - forwardDelete(state, 0); - state.assertEquals("| 'fg'"); - forwardDelete(state, 0); - state.assertEquals("| 'g'"); - forwardDelete(state, 0); - state.assertEquals("|"); - - state.setByString("'abc' [ ( 'de' ) ] 'fg'"); - forwardDelete(state, 0); - state.assertEquals("'abc' | 'fg'"); - forwardDelete(state, 0); - state.assertEquals("'abc' | 'g'"); - forwardDelete(state, 0); - state.assertEquals("'abc' |"); - forwardDelete(state, 0); - state.assertEquals("'abc' |"); - - state.setByString("'ab' [ 'c' ( 'de' ) 'f' ] 'g'"); - forwardDelete(state, 0); - state.assertEquals("'ab' | 'g'"); - forwardDelete(state, 0); - state.assertEquals("'ab' |"); - forwardDelete(state, 0); - state.assertEquals("'ab' |"); - - // TODO: introduce edge cases. - } - - @SmallTest public void testCombiningEnclosingKeycaps() { EditorState state = new EditorState(); - // U+20E3 is COMBINING ENCLOSING KEYCAP. - state.setByString("| '1' U+20E3"); - forwardDelete(state, 0); - state.assertEquals("|"); - - // Edge cases // multiple COMBINING ENCLOSING KEYCAP state.setByString("| '1' U+20E3 U+20E3"); forwardDelete(state, 0); @@ -152,17 +89,6 @@ public class ForwardDeleteTest extends KeyListenerTestCase { public void testVariationSelector() { EditorState state = new EditorState(); - // U+FE0F is VARIATION SELECTOR-16. - state.setByString("| '#' U+FE0F"); - forwardDelete(state, 0); - state.assertEquals("|"); - - // U+E0100 is VARIATION SELECTOR-17. - state.setByString("| U+845B U+E0100"); - forwardDelete(state, 0); - state.assertEquals("|"); - - // Edge cases // Isolated variation selectors state.setByString("| U+FE0F"); forwardDelete(state, 0); @@ -211,16 +137,6 @@ public class ForwardDeleteTest extends KeyListenerTestCase { public void testEmojiZeroWidthJoinerSequence() { EditorState state = new EditorState(); - // U+200D is ZERO WIDTH JOINER. - state.setByString("| U+1F441 U+200D U+1F5E8"); - forwardDelete(state, 0); - state.assertEquals("|"); - - state.setByString("| U+1F468 U+200D U+2764 U+FE0F U+200D U+1F48B U+200D U+1F468"); - forwardDelete(state, 0); - state.assertEquals("|"); - - // Edge cases // End with ZERO WIDTH JOINER state.setByString("| U+1F441 U+200D"); forwardDelete(state, 0); @@ -255,19 +171,6 @@ public class ForwardDeleteTest extends KeyListenerTestCase { public void testFlags() { EditorState state = new EditorState(); - // U+1F1FA is REGIONAL INDICATOR SYMBOL LETTER U. - // U+1F1F8 is REGIONAL INDICATOR SYMBOL LETTER S. - state.setByString("| U+1F1FA U+1F1F8"); - forwardDelete(state, 0); - state.assertEquals("|"); - - state.setByString("| U+1F1FA U+1F1F8 U+1F1FA U+1F1F8"); - forwardDelete(state, 0); - state.assertEquals("| U+1F1FA U+1F1F8"); - forwardDelete(state, 0); - state.assertEquals("|"); - - // Edge cases // Isolated regional indicator symbol state.setByString("| U+1F1FA"); forwardDelete(state, 0); @@ -285,12 +188,6 @@ public class ForwardDeleteTest extends KeyListenerTestCase { public void testEmojiModifier() { EditorState state = new EditorState(); - // U+1F3FB is EMOJI MODIFIER FITZPATRICK TYPE-1-2. - state.setByString("| U+1F466 U+1F3FB"); - forwardDelete(state, 0); - state.assertEquals("|"); - - // Edge cases // Isolated emoji modifier state.setByString("| U+1F3FB"); forwardDelete(state, 0); diff --git a/core/tests/coretests/src/android/transition/AutoTransitionTest.java b/core/tests/coretests/src/android/transition/AutoTransitionTest.java new file mode 100644 index 000000000000..834fb7aa72a5 --- /dev/null +++ b/core/tests/coretests/src/android/transition/AutoTransitionTest.java @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.transition; + +import android.support.test.runner.AndroidJUnit4; +import android.test.suitebuilder.annotation.SmallTest; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +@RunWith(AndroidJUnit4.class) +public class AutoTransitionTest { + @Test + @SmallTest + public void testFadeOutMoveFadeIn() throws Throwable { + AutoTransition autoTransition = new AutoTransition(); + assertEquals(3, autoTransition.getTransitionCount()); + Transition fadeOut = autoTransition.getTransitionAt(0); + assertNotNull(fadeOut); + assertTrue(fadeOut instanceof Fade); + assertEquals(Visibility.MODE_OUT, ((Fade)fadeOut).getMode()); + + Transition move = autoTransition.getTransitionAt(1); + assertNotNull(move); + assertTrue(move instanceof ChangeBounds); + + Transition fadeIn = autoTransition.getTransitionAt(2); + assertNotNull(fadeIn); + assertTrue(fadeIn instanceof Fade); + assertEquals(Visibility.MODE_IN, ((Fade)fadeIn).getMode()); + + assertEquals(TransitionSet.ORDERING_SEQUENTIAL, autoTransition.getOrdering()); + } +} diff --git a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java index 20e9165aa1b4..6b5e4adf9010 100644 --- a/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java +++ b/core/tests/coretests/src/com/android/internal/inputmethod/InputMethodUtilsTest.java @@ -219,12 +219,28 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { final InputMethodSubtype nonAutoHi = createDummyInputMethodSubtype("hi", SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE); + final InputMethodSubtype nonAutoSrCyrl = createDummyInputMethodSubtype("sr", + "sr-Cyrl", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE, + !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE); + final InputMethodSubtype nonAutoSrLatn = createDummyInputMethodSubtype("sr_ZZ", + "sr-Latn", SUBTYPE_MODE_KEYBOARD, !IS_AUX, + !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, IS_ASCII_CAPABLE, + !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE); final InputMethodSubtype nonAutoHandwritingEn = createDummyInputMethodSubtype("en", SUBTYPE_MODE_HANDWRITING, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE); final InputMethodSubtype nonAutoHandwritingFr = createDummyInputMethodSubtype("fr", SUBTYPE_MODE_HANDWRITING, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE, !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE); + final InputMethodSubtype nonAutoHandwritingSrCyrl = createDummyInputMethodSubtype("sr", + "sr-Cyrl", SUBTYPE_MODE_HANDWRITING, !IS_AUX, + !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE, + !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE); + final InputMethodSubtype nonAutoHandwritingSrLatn = createDummyInputMethodSubtype("sr_ZZ", + "sr-Latn", SUBTYPE_MODE_HANDWRITING, !IS_AUX, + !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE, + !IS_ENABLED_WHEN_DEFAULT_IS_NOT_ASCII_CAPABLE); final InputMethodSubtype nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype = createDummyInputMethodSubtype("zz", SUBTYPE_MODE_KEYBOARD, !IS_AUX, !IS_OVERRIDES_IMPLICITLY_ENABLED_SUBTYPE, !IS_ASCII_CAPABLE, @@ -430,6 +446,85 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { verifyEquality(nonAutoEnUS, result.get(0)); } + // Make sure that both language and script are taken into account to find the best matching + // subtype. + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>(); + subtypes.add(nonAutoEnUS); + subtypes.add(nonAutoSrCyrl); + subtypes.add(nonAutoSrLatn); + subtypes.add(nonAutoHandwritingEn); + subtypes.add(nonAutoHandwritingFr); + subtypes.add(nonAutoHandwritingSrCyrl); + subtypes.add(nonAutoHandwritingSrLatn); + final InputMethodInfo imi = createDummyInputMethodInfo( + "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT, + subtypes); + final ArrayList<InputMethodSubtype> result = + InputMethodUtils.getImplicitlyApplicableSubtypesLocked( + getResourcesForLocales(Locale.forLanguageTag("sr-Latn-RS")), imi); + assertEquals(2, result.size()); + assertThat(nonAutoSrLatn, isIn(result)); + assertThat(nonAutoHandwritingSrLatn, isIn(result)); + } + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>(); + subtypes.add(nonAutoEnUS); + subtypes.add(nonAutoSrCyrl); + subtypes.add(nonAutoSrLatn); + subtypes.add(nonAutoHandwritingEn); + subtypes.add(nonAutoHandwritingFr); + subtypes.add(nonAutoHandwritingSrCyrl); + subtypes.add(nonAutoHandwritingSrLatn); + final InputMethodInfo imi = createDummyInputMethodInfo( + "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT, + subtypes); + final ArrayList<InputMethodSubtype> result = + InputMethodUtils.getImplicitlyApplicableSubtypesLocked( + getResourcesForLocales(Locale.forLanguageTag("sr-Cyrl-RS")), imi); + assertEquals(2, result.size()); + assertThat(nonAutoSrCyrl, isIn(result)); + assertThat(nonAutoHandwritingSrCyrl, isIn(result)); + } + + // Make sure that secondary locales are taken into account to find the best matching + // subtype. + { + final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>(); + subtypes.add(nonAutoEnUS); + subtypes.add(nonAutoEnGB); + subtypes.add(nonAutoSrCyrl); + subtypes.add(nonAutoSrLatn); + subtypes.add(nonAutoFr); + subtypes.add(nonAutoFrCA); + subtypes.add(nonAutoHandwritingEn); + subtypes.add(nonAutoHandwritingFr); + subtypes.add(nonAutoHandwritingSrCyrl); + subtypes.add(nonAutoHandwritingSrLatn); + final InputMethodInfo imi = createDummyInputMethodInfo( + "com.android.apps.inputmethod.latin", + "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT, + subtypes); + final ArrayList<InputMethodSubtype> result = + InputMethodUtils.getImplicitlyApplicableSubtypesLocked( + getResourcesForLocales( + Locale.forLanguageTag("sr-Latn-RS-x-android"), + Locale.forLanguageTag("ja-JP"), + Locale.forLanguageTag("fr-FR"), + Locale.forLanguageTag("en-GB"), + Locale.forLanguageTag("en-US")), + imi); + assertEquals(6, result.size()); + assertThat(nonAutoEnGB, isIn(result)); + assertThat(nonAutoFr, isIn(result)); + assertThat(nonAutoSrLatn, isIn(result)); + assertThat(nonAutoHandwritingEn, isIn(result)); + assertThat(nonAutoHandwritingFr, isIn(result)); + assertThat(nonAutoHandwritingSrLatn, isIn(result)); + } + // Make sure that 3-letter language code can be handled. { final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>(); @@ -778,7 +873,15 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { private static InputMethodSubtype createDummyInputMethodSubtype(String locale, String mode, boolean isAuxiliary, boolean overridesImplicitlyEnabledSubtype, boolean isAsciiCapable, boolean isEnabledWhenDefaultIsNotAsciiCapable) { + return createDummyInputMethodSubtype(locale, null /* languageTag */, mode, isAuxiliary, + overridesImplicitlyEnabledSubtype, isAsciiCapable, + isEnabledWhenDefaultIsNotAsciiCapable); + } + private static InputMethodSubtype createDummyInputMethodSubtype(String locale, + String languageTag, String mode, boolean isAuxiliary, + boolean overridesImplicitlyEnabledSubtype, boolean isAsciiCapable, + boolean isEnabledWhenDefaultIsNotAsciiCapable) { final StringBuilder subtypeExtraValue = new StringBuilder(); if (isEnabledWhenDefaultIsNotAsciiCapable) { subtypeExtraValue.append(EXTRA_VALUE_PAIR_SEPARATOR); @@ -796,6 +899,7 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { .setSubtypeNameResId(0) .setSubtypeIconResId(0) .setSubtypeLocale(locale) + .setLanguageTag(languageTag) .setSubtypeMode(mode) .setSubtypeExtraValue(subtypeExtraValue.toString()) .setIsAuxiliary(isAuxiliary) diff --git a/data/fonts/Android.mk b/data/fonts/Android.mk index de741b376d16..dc85046f518e 100644 --- a/data/fonts/Android.mk +++ b/data/fonts/Android.mk @@ -95,3 +95,14 @@ $(foreach f, $(font_src_files), $(call build-one-font-module, $(f))) build-one-font-module := font_src_files := + + +# Run sanity tests on fonts on checkbuild +checkbuild: fontchain_lint + +FONTCHAIN_LINTER := frameworks/base/tools/fonts/fontchain_lint.py + +.PHONY: fontchain_lint +fontchain_lint: $(FONTCHAIN_LINTER) $(TARGET_OUT)/etc/fonts.xml + PYTHONPATH=$$PYTHONPATH:external/fonttools/Lib \ + python $(FONTCHAIN_LINTER) $(TARGET_OUT)
\ No newline at end of file diff --git a/graphics/java/android/graphics/Outline.java b/graphics/java/android/graphics/Outline.java index 99fa9fe2b3b2..d3124545ae84 100644 --- a/graphics/java/android/graphics/Outline.java +++ b/graphics/java/android/graphics/Outline.java @@ -32,13 +32,15 @@ import android.graphics.drawable.Drawable; * @see Drawable#getOutline(Outline) */ public final class Outline { + private static final float RADIUS_UNDEFINED = -1.0f; + /** @hide */ public Path mPath; /** @hide */ public Rect mRect; /** @hide */ - public float mRadius; + public float mRadius = RADIUS_UNDEFINED; /** @hide */ public float mAlpha; @@ -63,7 +65,7 @@ public final class Outline { public void setEmpty() { mPath = null; mRect = null; - mRadius = 0; + mRadius = RADIUS_UNDEFINED; } /** @@ -223,6 +225,7 @@ public final class Outline { mPath.reset(); mPath.addOval(left, top, right, bottom, Path.Direction.CW); mRect = null; + mRadius = RADIUS_UNDEFINED; } /** @@ -249,7 +252,7 @@ public final class Outline { mPath.set(convexPath); mRect = null; - mRadius = -1.0f; + mRadius = RADIUS_UNDEFINED; } /** diff --git a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java index 219bca82b702..437ebaab7fd7 100644 --- a/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java +++ b/graphics/java/android/graphics/drawable/AnimatedVectorDrawable.java @@ -27,6 +27,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityThread; import android.app.Application; +import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.Resources.Theme; @@ -230,7 +231,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | mAnimatedVectorState.getChangingConfigurations(); } @@ -260,6 +261,13 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { return mAnimatedVectorState.mVectorDrawable.setLayoutDirection(layoutDirection); } + /** + * AnimatedVectorDrawable is running on render thread now. Therefore, if the root alpha is being + * animated, then the root alpha value we get from this call could be out of sync with alpha + * value used in the render thread. Otherwise, the root alpha should be always the same value. + * + * @return the containing vector drawable's root alpha value. + */ @Override public int getAlpha() { return mAnimatedVectorState.mVectorDrawable.getAlpha(); @@ -276,6 +284,11 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { } @Override + public ColorFilter getColorFilter() { + return mAnimatedVectorState.mVectorDrawable.getColorFilter(); + } + + @Override public void setTintList(ColorStateList tint) { mAnimatedVectorState.mVectorDrawable.setTintList(tint); } @@ -437,7 +450,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { } private static class AnimatedVectorDrawableState extends ConstantState { - int mChangingConfigurations; + @Config int mChangingConfigurations; VectorDrawable mVectorDrawable; /** Animators that require a theme before inflation. */ @@ -501,7 +514,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations; } @@ -703,17 +716,17 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { private final Callback mCallback = new Callback() { @Override - public void invalidateDrawable(Drawable who) { + public void invalidateDrawable(@NonNull Drawable who) { invalidateSelf(); } @Override - public void scheduleDrawable(Drawable who, Runnable what, long when) { + public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { scheduleSelf(what, when); } @Override - public void unscheduleDrawable(Drawable who, Runnable what) { + public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { unscheduleSelf(what); } }; diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index bffbc751ee83..9d8ede048924 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -17,6 +17,7 @@ package android.graphics.drawable; import android.annotation.NonNull; +import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.Resources.Theme; @@ -454,7 +455,7 @@ public class BitmapDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | mBitmapState.getChangingConfigurations(); } @@ -910,7 +911,7 @@ public class BitmapDrawable extends Drawable { int mTargetDensity = DisplayMetrics.DENSITY_DEFAULT; boolean mAutoMirrored = false; - int mChangingConfigurations; + @Config int mChangingConfigurations; boolean mRebuildShader; BitmapState(Bitmap bitmap) { @@ -958,7 +959,7 @@ public class BitmapDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations | (mTint != null ? mTint.getChangingConfigurations() : 0); } diff --git a/graphics/java/android/graphics/drawable/ColorDrawable.java b/graphics/java/android/graphics/drawable/ColorDrawable.java index 5ad31f75f20a..7524cac47491 100644 --- a/graphics/java/android/graphics/drawable/ColorDrawable.java +++ b/graphics/java/android/graphics/drawable/ColorDrawable.java @@ -18,6 +18,7 @@ package android.graphics.drawable; import android.annotation.ColorInt; import android.annotation.NonNull; +import android.content.pm.ActivityInfo.Config; import android.graphics.*; import android.graphics.PorterDuff.Mode; import android.content.res.ColorStateList; @@ -70,7 +71,7 @@ public class ColorDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | mColorState.getChangingConfigurations(); } @@ -292,7 +293,7 @@ public class ColorDrawable extends Drawable { int mBaseColor; // base color, independent of setAlpha() @ViewDebug.ExportedProperty int mUseColor; // basecolor modulated by setAlpha() - int mChangingConfigurations; + @Config int mChangingConfigurations; ColorStateList mTint = null; Mode mTintMode = DEFAULT_TINT_MODE; @@ -326,7 +327,7 @@ public class ColorDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations | (mTint != null ? mTint.getChangingConfigurations() : 0); } diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 3d8437d66848..391598447573 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -19,6 +19,7 @@ package android.graphics.drawable; import android.annotation.ColorInt; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.Resources.Theme; @@ -134,7 +135,7 @@ public abstract class Drawable { private int[] mStateSet = StateSet.WILD_CARD; private int mLevel = 0; - private int mChangingConfigurations = 0; + private @Config int mChangingConfigurations = 0; private Rect mBounds = ZERO_BOUNDS_RECT; // lazily becomes a new Rect() private WeakReference<Callback> mCallback = null; private boolean mVisible = true; @@ -249,7 +250,7 @@ public abstract class Drawable { * * @see android.content.pm.ActivityInfo */ - public void setChangingConfigurations(int configs) { + public void setChangingConfigurations(@Config int configs) { mChangingConfigurations = configs; } @@ -266,7 +267,7 @@ public abstract class Drawable { * * @see android.content.pm.ActivityInfo */ - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations; } @@ -308,7 +309,7 @@ public abstract class Drawable { * to supply your implementation of the interface to the drawable; it uses * this interface to schedule and execute animation changes. */ - public static interface Callback { + public interface Callback { /** * Called when the drawable needs to be redrawn. A view at this point * should invalidate itself (or at least the part of itself where the @@ -316,7 +317,7 @@ public abstract class Drawable { * * @param who The drawable that is requesting the update. */ - public void invalidateDrawable(Drawable who); + void invalidateDrawable(@NonNull Drawable who); /** * A Drawable can call this to schedule the next frame of its @@ -330,7 +331,7 @@ public abstract class Drawable { * @param when The time (in milliseconds) to run. The timebase is * {@link android.os.SystemClock#uptimeMillis} */ - public void scheduleDrawable(Drawable who, Runnable what, long when); + void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when); /** * A Drawable can call this to unschedule an action previously @@ -342,7 +343,7 @@ public abstract class Drawable { * @param who The drawable being unscheduled. * @param what The action being unscheduled. */ - public void unscheduleDrawable(Drawable who, Runnable what); + void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what); } /** @@ -1294,7 +1295,7 @@ public abstract class Drawable { * Return a bit mask of configuration changes that will impact * this drawable (and thus require completely reloading it). */ - public abstract int getChangingConfigurations(); + public abstract @Config int getChangingConfigurations(); /** * @return Total pixel count diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java index 3b0e7e8c704e..42f48633eacb 100644 --- a/graphics/java/android/graphics/drawable/DrawableContainer.java +++ b/graphics/java/android/graphics/drawable/DrawableContainer.java @@ -17,6 +17,7 @@ package android.graphics.drawable; import android.annotation.NonNull; +import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.Resources.Theme; @@ -87,7 +88,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | mDrawableContainerState.getChangingConfigurations(); } @@ -373,21 +374,21 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } @Override - public void invalidateDrawable(Drawable who) { + public void invalidateDrawable(@NonNull Drawable who) { if (who == mCurrDrawable && getCallback() != null) { getCallback().invalidateDrawable(this); } } @Override - public void scheduleDrawable(Drawable who, Runnable what, long when) { + public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { if (who == mCurrDrawable && getCallback() != null) { getCallback().scheduleDrawable(this, what, when); } } @Override - public void unscheduleDrawable(Drawable who, Runnable what) { + public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { if (who == mCurrDrawable && getCallback() != null) { getCallback().unscheduleDrawable(this, what); } @@ -649,8 +650,8 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { Resources mSourceRes; int mDensity = DisplayMetrics.DENSITY_DEFAULT; - int mChangingConfigurations; - int mChildrenChangingConfigurations; + @Config int mChangingConfigurations; + @Config int mChildrenChangingConfigurations; SparseArray<ConstantState> mDrawableFutures; Drawable[] mDrawables; @@ -781,7 +782,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations | mChildrenChangingConfigurations; } @@ -804,6 +805,7 @@ public class DrawableContainer extends Drawable implements Drawable.Callback { mConstantPadding = null; mCheckedPadding = false; mCheckedConstantSize = false; + mCheckedConstantState = false; return pos; } diff --git a/graphics/java/android/graphics/drawable/DrawableWrapper.java b/graphics/java/android/graphics/drawable/DrawableWrapper.java index c42787000c49..5abfc54bfce3 100644 --- a/graphics/java/android/graphics/drawable/DrawableWrapper.java +++ b/graphics/java/android/graphics/drawable/DrawableWrapper.java @@ -23,6 +23,7 @@ import org.xmlpull.v1.XmlPullParserException; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.Resources.Theme; @@ -198,7 +199,7 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb } @Override - public void invalidateDrawable(Drawable who) { + public void invalidateDrawable(@NonNull Drawable who) { final Callback callback = getCallback(); if (callback != null) { callback.invalidateDrawable(this); @@ -206,7 +207,7 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb } @Override - public void scheduleDrawable(Drawable who, Runnable what, long when) { + public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { final Callback callback = getCallback(); if (callback != null) { callback.scheduleDrawable(this, what, when); @@ -214,7 +215,7 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb } @Override - public void unscheduleDrawable(Drawable who, Runnable what) { + public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { final Callback callback = getCallback(); if (callback != null) { callback.unscheduleDrawable(this, what); @@ -229,7 +230,7 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | (mState != null ? mState.getChangingConfigurations() : 0) | mDrawable.getChangingConfigurations(); @@ -444,7 +445,7 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb abstract static class DrawableWrapperState extends Drawable.ConstantState { private int[] mThemeAttrs; - int mChangingConfigurations; + @Config int mChangingConfigurations; int mDensity = DisplayMetrics.DENSITY_DEFAULT; Drawable.ConstantState mDrawableState; @@ -524,7 +525,7 @@ public abstract class DrawableWrapper extends Drawable implements Drawable.Callb public abstract Drawable newDrawable(@Nullable Resources res); @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations | (mDrawableState != null ? mDrawableState.getChangingConfigurations() : 0); } diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java index 7b1e62a6390d..bcc354c5b736 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -20,6 +20,7 @@ import android.annotation.ColorInt; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.Resources.Theme; @@ -958,7 +959,7 @@ public class GradientDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | mGradientState.getChangingConfigurations(); } @@ -1734,7 +1735,7 @@ public class GradientDrawable extends Drawable { } final static class GradientState extends ConstantState { - public int mChangingConfigurations; + public @Config int mChangingConfigurations; public @Shape int mShape = RECTANGLE; public @GradientType int mGradient = LINEAR_GRADIENT; public int mAngle = 0; @@ -1962,7 +1963,7 @@ public class GradientDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations | (mStrokeColors != null ? mStrokeColors.getChangingConfigurations() : 0) | (mSolidColors != null ? mSolidColors.getChangingConfigurations() : 0) diff --git a/graphics/java/android/graphics/drawable/LayerDrawable.java b/graphics/java/android/graphics/drawable/LayerDrawable.java index e2150c02c0e6..8417a406f0b0 100644 --- a/graphics/java/android/graphics/drawable/LayerDrawable.java +++ b/graphics/java/android/graphics/drawable/LayerDrawable.java @@ -18,6 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.Resources.Theme; @@ -944,17 +945,17 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { } @Override - public void invalidateDrawable(Drawable who) { + public void invalidateDrawable(@NonNull Drawable who) { invalidateSelf(); } @Override - public void scheduleDrawable(Drawable who, Runnable what, long when) { + public void scheduleDrawable(@NonNull Drawable who, @NonNull Runnable what, long when) { scheduleSelf(what, when); } @Override - public void unscheduleDrawable(Drawable who, Runnable what) { + public void unscheduleDrawable(@NonNull Drawable who, @NonNull Runnable what) { unscheduleSelf(what); } @@ -971,7 +972,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | mLayerState.getChangingConfigurations(); } @@ -1864,8 +1865,8 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { int mPaddingEnd = -1; int mOpacityOverride = PixelFormat.UNKNOWN; - int mChangingConfigurations; - int mChildrenChangingConfigurations; + @Config int mChangingConfigurations; + @Config int mChildrenChangingConfigurations; private boolean mHaveOpacity; private int mOpacity; @@ -1989,7 +1990,7 @@ public class LayerDrawable extends Drawable implements Drawable.Callback { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations | mChildrenChangingConfigurations; } diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index 681653967aa1..fd3b9b47fe1a 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -18,6 +18,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.Resources.Theme; @@ -260,7 +261,7 @@ public class NinePatchDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | mNinePatchState.getChangingConfigurations(); } @@ -575,7 +576,7 @@ public class NinePatchDrawable extends Drawable { } final static class NinePatchState extends ConstantState { - int mChangingConfigurations; + @Config int mChangingConfigurations; // Values loaded during inflation. NinePatch mNinePatch = null; @@ -651,7 +652,7 @@ public class NinePatchDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations | (mTint != null ? mTint.getChangingConfigurations() : 0); } diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java index ee0861ae60f5..caf2e7a4cb4c 100644 --- a/graphics/java/android/graphics/drawable/RippleDrawable.java +++ b/graphics/java/android/graphics/drawable/RippleDrawable.java @@ -23,6 +23,7 @@ import org.xmlpull.v1.XmlPullParserException; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.Resources.Theme; @@ -1033,7 +1034,7 @@ public class RippleDrawable extends LayerDrawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | (mColor != null ? mColor.getChangingConfigurations() : 0); } diff --git a/graphics/java/android/graphics/drawable/ShapeDrawable.java b/graphics/java/android/graphics/drawable/ShapeDrawable.java index 30b588e1b4b7..fe82a93cf5b5 100644 --- a/graphics/java/android/graphics/drawable/ShapeDrawable.java +++ b/graphics/java/android/graphics/drawable/ShapeDrawable.java @@ -16,6 +16,7 @@ package android.graphics.drawable; +import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.Resources; import android.content.res.TypedArray; @@ -260,7 +261,7 @@ public class ShapeDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | mShapeState.getChangingConfigurations(); } @@ -526,7 +527,7 @@ public class ShapeDrawable extends Drawable { */ final static class ShapeState extends ConstantState { int[] mThemeAttrs; - int mChangingConfigurations; + @Config int mChangingConfigurations; Paint mPaint; Shape mShape; ColorStateList mTint = null; @@ -571,7 +572,7 @@ public class ShapeDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations | (mTint != null ? mTint.getChangingConfigurations() : 0); } diff --git a/graphics/java/android/graphics/drawable/TransitionDrawable.java b/graphics/java/android/graphics/drawable/TransitionDrawable.java index e5c235efaba5..0122338a7255 100644 --- a/graphics/java/android/graphics/drawable/TransitionDrawable.java +++ b/graphics/java/android/graphics/drawable/TransitionDrawable.java @@ -16,6 +16,7 @@ package android.graphics.drawable; +import android.content.pm.ActivityInfo.Config; import android.content.res.Resources; import android.graphics.Canvas; import android.os.SystemClock; @@ -259,7 +260,7 @@ public class TransitionDrawable extends LayerDrawable implements Drawable.Callba } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations; } } diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java index 44a91fefc4a0..ae98c22dd4b0 100644 --- a/graphics/java/android/graphics/drawable/VectorDrawable.java +++ b/graphics/java/android/graphics/drawable/VectorDrawable.java @@ -16,6 +16,7 @@ package android.graphics.drawable; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.pm.ActivityInfo.Config; import android.content.res.ColorStateList; import android.content.res.ComplexColor; import android.content.res.GradientColor; @@ -686,7 +687,7 @@ public class VectorDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | mVectorState.getChangingConfigurations(); } @@ -714,7 +715,7 @@ public class VectorDrawable extends Drawable { static class VectorDrawableState extends ConstantState { // Variables below need to be copied (deep copy if applicable) for mutation. int[] mThemeAttrs; - int mChangingConfigurations; + @Config int mChangingConfigurations; ColorStateList mTint = null; Mode mTintMode = DEFAULT_TINT_MODE; boolean mAutoMirrored; @@ -823,7 +824,7 @@ public class VectorDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations | (mTint != null ? mTint.getChangingConfigurations() : 0); } @@ -923,7 +924,7 @@ public class VectorDrawable extends Drawable { // mLocalMatrix is updated based on the update of transformation information, // either parsed from the XML or by animation. - private int mChangingConfigurations; + private @Config int mChangingConfigurations; private int[] mThemeAttrs; private String mGroupName = null; @@ -1169,7 +1170,7 @@ public class VectorDrawable extends Drawable { protected PathParser.PathData mPathData = null; String mPathName; - int mChangingConfigurations; + @Config int mChangingConfigurations; public VPath() { // Empty constructor. diff --git a/graphics/java/android/graphics/drawable/shapes/ArcShape.java b/graphics/java/android/graphics/drawable/shapes/ArcShape.java index 84731b0d3819..c4b239f20da4 100644 --- a/graphics/java/android/graphics/drawable/shapes/ArcShape.java +++ b/graphics/java/android/graphics/drawable/shapes/ArcShape.java @@ -17,6 +17,7 @@ package android.graphics.drawable.shapes; import android.graphics.Canvas; +import android.graphics.Outline; import android.graphics.Paint; /** @@ -46,5 +47,11 @@ public class ArcShape extends RectShape { public void draw(Canvas canvas, Paint paint) { canvas.drawArc(rect(), mStart, mSweep, true, paint); } + + @Override + public void getOutline(Outline outline) { + // Since we don't support concave outlines, arc shape does not attempt + // to provide an outline. + } } diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index 936c7e86d58f..f6e3b5035be2 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -240,6 +240,7 @@ LOCAL_SRC_FILES += \ tests/unit/DamageAccumulatorTests.cpp \ tests/unit/DeviceInfoTests.cpp \ tests/unit/FatVectorTests.cpp \ + tests/unit/GlopBuilderTests.cpp \ tests/unit/GpuMemoryTrackerTests.cpp \ tests/unit/LayerUpdateQueueTests.cpp \ tests/unit/LinearAllocatorTests.cpp \ diff --git a/libs/hwui/FloatColor.h b/libs/hwui/FloatColor.h index 97dec88e709b..9a39ec28aa3d 100644 --- a/libs/hwui/FloatColor.h +++ b/libs/hwui/FloatColor.h @@ -17,6 +17,7 @@ #define FLOATCOLOR_H #include "utils/Macros.h" +#include "utils/MathUtils.h" #include <stdint.h> @@ -38,6 +39,17 @@ struct FloatColor { || b > 0.0f; } + bool operator==(const FloatColor& other) const { + return MathUtils::areEqual(r, other.r) + && MathUtils::areEqual(g, other.g) + && MathUtils::areEqual(b, other.b) + && MathUtils::areEqual(a, other.a); + } + + bool operator!=(const FloatColor& other) const { + return !(*this == other); + } + float r; float g; float b; diff --git a/libs/hwui/Glop.h b/libs/hwui/Glop.h index e72f39621d57..704bd69056fe 100644 --- a/libs/hwui/Glop.h +++ b/libs/hwui/Glop.h @@ -81,8 +81,10 @@ namespace TransformFlags { * vertex/index/Texture/RoundRectClipState pointers prevent this from * being safe. */ -// TODO: PREVENT_COPY_AND_ASSIGN(...) or similar struct Glop { + PREVENT_COPY_AND_ASSIGN(Glop); +public: + Glop() { } struct Mesh { GLuint primitiveMode; // GL_TRIANGLES and GL_TRIANGLE_STRIP supported @@ -149,7 +151,7 @@ struct Glop { } } transform; - const RoundRectClipState* roundRectClipState; + const RoundRectClipState* roundRectClipState = nullptr; /** * Blending to be used by this draw - both GL_NONE if blending is disabled. @@ -165,7 +167,7 @@ struct Glop { * Bounds of the drawing command in layer space. Only mapped into layer * space once GlopBuilder::build() is called. */ - Rect bounds; + Rect bounds; // TODO: remove for HWUI_NEW_OPS /** * Additional render state to enumerate: diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp index 45fc16cc3136..2799def16b98 100644 --- a/libs/hwui/GlopBuilder.cpp +++ b/libs/hwui/GlopBuilder.cpp @@ -676,8 +676,11 @@ void GlopBuilder::dump(const Glop& glop) { fill.skiaShaderData.skiaShaderType); ALOGD("Glop transform"); - glop.transform.modelView.dump("model view"); - glop.transform.canvas.dump("canvas"); + glop.transform.modelView.dump(" model view"); + glop.transform.canvas.dump(" canvas"); + ALOGD_IF(glop.transform.transformFlags, " transformFlags 0x%x", glop.transform.transformFlags); + + ALOGD_IF(glop.roundRectClipState, "Glop RRCS %p", glop.roundRectClipState); ALOGD("Glop blend %d %d", glop.blend.src, glop.blend.dst); ALOGD("Glop bounds " RECT_STRING, RECT_ARGS(glop.bounds)); diff --git a/libs/hwui/tests/unit/GlopBuilderTests.cpp b/libs/hwui/tests/unit/GlopBuilderTests.cpp new file mode 100644 index 000000000000..949c541830df --- /dev/null +++ b/libs/hwui/tests/unit/GlopBuilderTests.cpp @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <gtest/gtest.h> + +#include "BakedOpRenderer.h" +#include "Glop.h" +#include "GlopBuilder.h" +#include "Rect.h" +#include "tests/common/TestUtils.h" +#include "utils/Color.h" + +#include <SkPaint.h> + +using namespace android::uirenderer; + +static void expectFillEq(Glop::Fill& expectedFill, Glop::Fill& builtFill) { + EXPECT_EQ(expectedFill.colorEnabled, builtFill.colorEnabled); + if (expectedFill.colorEnabled) + EXPECT_EQ(expectedFill.color, builtFill.color); + + EXPECT_EQ(expectedFill.filterMode, builtFill.filterMode); + if (expectedFill.filterMode == ProgramDescription::ColorFilterMode::Blend) { + EXPECT_EQ(expectedFill.filter.color, builtFill.filter.color); + } else if (expectedFill.filterMode == ProgramDescription::ColorFilterMode::Matrix) { + Glop::Fill::Filter::Matrix& expectedMatrix = expectedFill.filter.matrix; + Glop::Fill::Filter::Matrix& builtMatrix = expectedFill.filter.matrix; + EXPECT_TRUE(std::memcmp(expectedMatrix.matrix, builtMatrix.matrix, + sizeof(Glop::Fill::Filter::Matrix::matrix))); + EXPECT_TRUE(std::memcmp(expectedMatrix.vector, builtMatrix.vector, + sizeof(Glop::Fill::Filter::Matrix::vector))); + } + EXPECT_EQ(expectedFill.skiaShaderData.skiaShaderType, builtFill.skiaShaderData.skiaShaderType); + EXPECT_EQ(expectedFill.texture.clamp, builtFill.texture.clamp); + EXPECT_EQ(expectedFill.texture.filter, builtFill.texture.filter); + EXPECT_EQ(expectedFill.texture.target, builtFill.texture.target); + EXPECT_EQ(expectedFill.texture.textureTransform, builtFill.texture.textureTransform); +} + +static void expectBlendEq(Glop::Blend& expectedBlend, Glop::Blend& builtBlend) { + EXPECT_EQ(expectedBlend.src, builtBlend.src); + EXPECT_EQ(expectedBlend.dst, builtBlend.dst); +} + +static void expectMeshEq(Glop::Mesh& expectedMesh, Glop::Mesh& builtMesh) { + EXPECT_EQ(expectedMesh.elementCount, builtMesh.elementCount); + EXPECT_EQ(expectedMesh.primitiveMode, builtMesh.primitiveMode); + EXPECT_EQ(expectedMesh.indices.indices, builtMesh.indices.indices); + EXPECT_EQ(expectedMesh.indices.bufferObject, builtMesh.indices.bufferObject); + EXPECT_EQ(expectedMesh.vertices.attribFlags, builtMesh.vertices.attribFlags); + EXPECT_EQ(expectedMesh.vertices.bufferObject, builtMesh.vertices.bufferObject); + EXPECT_EQ(expectedMesh.vertices.color, builtMesh.vertices.color); + EXPECT_EQ(expectedMesh.vertices.position, builtMesh.vertices.position); + EXPECT_EQ(expectedMesh.vertices.stride, builtMesh.vertices.stride); + EXPECT_EQ(expectedMesh.vertices.texCoord, builtMesh.vertices.texCoord); + + if (builtMesh.vertices.position) { + for (int i = 0; i < 4; i++) { + TextureVertex& expectedVertex = expectedMesh.mappedVertices[i]; + TextureVertex& builtVertex = builtMesh.mappedVertices[i]; + EXPECT_EQ(expectedVertex.u, builtVertex.u); + EXPECT_EQ(expectedVertex.v, builtVertex.v); + EXPECT_EQ(expectedVertex.x, builtVertex.x); + EXPECT_EQ(expectedVertex.y, builtVertex.y); + } + } +} + +static void expectTransformEq(Glop::Transform& expectedTransform, Glop::Transform& builtTransform) { + EXPECT_EQ(expectedTransform.canvas, builtTransform.canvas); + EXPECT_EQ(expectedTransform.modelView, builtTransform.modelView); + EXPECT_EQ(expectedTransform.transformFlags, expectedTransform.transformFlags); +} + +static void expectGlopEq(Glop& expectedGlop, Glop& builtGlop) { + EXPECT_EQ(expectedGlop.bounds, builtGlop.bounds); + expectBlendEq(expectedGlop.blend, builtGlop.blend); + expectFillEq(expectedGlop.fill, builtGlop.fill); + expectMeshEq(expectedGlop.mesh, builtGlop.mesh); + expectTransformEq(expectedGlop.transform, builtGlop.transform); +} + +static std::unique_ptr<Glop> blackUnitQuadGlop(RenderState& renderState) { + std::unique_ptr<Glop> glop(new Glop()); + glop->blend = { GL_ZERO, GL_ZERO }; + glop->mesh.elementCount = 4; + glop->mesh.primitiveMode = GL_TRIANGLE_STRIP; + glop->mesh.indices.indices = nullptr; + glop->mesh.indices.bufferObject = GL_ZERO; + glop->mesh.vertices = { + renderState.meshState().getUnitQuadVBO(), + VertexAttribFlags::None, + nullptr, nullptr, nullptr, + kTextureVertexStride }; + glop->transform.modelView.loadIdentity(); + glop->fill.colorEnabled = true; + glop->fill.color.set(Color::Black); + glop->fill.skiaShaderData.skiaShaderType = kNone_SkiaShaderType; + glop->fill.filterMode = ProgramDescription::ColorFilterMode::None; + glop->fill.texture = { nullptr, GL_INVALID_ENUM, GL_INVALID_ENUM, GL_INVALID_ENUM, nullptr }; + return glop; +} + +RENDERTHREAD_TEST(GlopBuilder, rectSnapTest) { + RenderState& renderState = renderThread.renderState(); + Caches& caches = Caches::getInstance(); + SkPaint paint; + Rect dest(1, 1, 100, 100); + Matrix4 simpleTranslate; + simpleTranslate.loadTranslate(0.7, 0.7, 0); + Glop glop; + GlopBuilder(renderState, caches, &glop) + .setRoundRectClipState(nullptr) + .setMeshUnitQuad() + .setFillPaint(paint, 1.0f) + .setTransform(simpleTranslate, TransformFlags::None) + .setModelViewMapUnitToRectSnap(dest) + .build(); + + std::unique_ptr<Glop> goldenGlop(blackUnitQuadGlop(renderState)); + // Rect(1,1,100,100) is the set destination, + // so unit quad should be translated by (1,1) and scaled by (99, 99) + // Tricky part: because translate (0.7, 0.7) and snapping were set in glopBuilder, + // unit quad also should be translate by additional (0.3, 0.3) to snap to exact pixels. + goldenGlop->transform.modelView.loadTranslate(1.3, 1.3, 0); + goldenGlop->transform.modelView.scale(99, 99, 1); + goldenGlop->bounds = android::uirenderer::Rect(1.70, 1.70, 100.70, 100.70); + goldenGlop->transform.canvas = simpleTranslate; + goldenGlop->fill.texture.filter = GL_NEAREST; + expectGlopEq(*goldenGlop, glop); +} diff --git a/media/java/android/media/audiopolicy/AudioMix.java b/media/java/android/media/audiopolicy/AudioMix.java index 55fb82bbdcc5..56d3c9987bc1 100644 --- a/media/java/android/media/audiopolicy/AudioMix.java +++ b/media/java/android/media/audiopolicy/AudioMix.java @@ -17,7 +17,9 @@ package android.media.audiopolicy; import android.annotation.IntDef; +import android.annotation.NonNull; import android.annotation.SystemApi; +import android.media.AudioDeviceInfo; import android.media.AudioFormat; import android.media.AudioSystem; @@ -36,19 +38,28 @@ public class AudioMix { private int mRouteFlags; private String mRegistrationId; private int mMixType = MIX_TYPE_INVALID; + + // written by AudioPolicy int mMixState = MIX_STATE_DISABLED; int mCallbackFlags; + // initialized in constructor, read by AudioPolicyConfig + final int mDeviceId; + final String mDeviceAddress; + /** * All parameters are guaranteed valid through the Builder. */ - private AudioMix(AudioMixingRule rule, AudioFormat format, int routeFlags, int callbackFlags) { + private AudioMix(AudioMixingRule rule, AudioFormat format, int routeFlags, int callbackFlags, + int deviceId, String deviceAddress) { mRule = rule; mFormat = format; mRouteFlags = routeFlags; mRegistrationId = null; mMixType = rule.getTargetMixType(); mCallbackFlags = callbackFlags; + mDeviceId = deviceId; + mDeviceAddress = deviceAddress; } // CALLBACK_FLAG_* values: keep in sync with AudioMix::kCbFlag* values defined @@ -74,6 +85,8 @@ public class AudioMix { @SystemApi public static final int ROUTE_FLAG_LOOP_BACK = 0x1 << 1; + private static final int ROUTE_FLAG_SUPPORTED = ROUTE_FLAG_RENDER | ROUTE_FLAG_LOOP_BACK; + // MIX_TYPE_* values to keep in sync with frameworks/av/include/media/AudioPolicy.h /** * @hide @@ -172,6 +185,8 @@ public class AudioMix { private AudioFormat mFormat = null; private int mRouteFlags = 0; private int mCallbackFlags = 0; + private int mDeviceId = -1; + private String mDeviceAddress = null; /** * @hide @@ -200,7 +215,7 @@ public class AudioMix { * @return the same Builder instance. * @throws IllegalArgumentException */ - public Builder setMixingRule(AudioMixingRule rule) + Builder setMixingRule(AudioMixingRule rule) throws IllegalArgumentException { if (rule == null) { throw new IllegalArgumentException("Illegal null AudioMixingRule argument"); @@ -216,7 +231,7 @@ public class AudioMix { * @return the same Builder instance. * @throws IllegalArgumentException */ - public Builder setCallbackFlags(int flags) throws IllegalArgumentException { + Builder setCallbackFlags(int flags) throws IllegalArgumentException { if ((flags != 0) && ((flags & CALLBACK_FLAGS_ALL) == 0)) { throw new IllegalArgumentException("Illegal callback flags 0x" + Integer.toHexString(flags).toUpperCase()); @@ -226,6 +241,19 @@ public class AudioMix { } /** + * @hide + * Only used by AudioPolicyConfig, not a public API. + * @param deviceId + * @param address + * @return the same Builder instance. + */ + Builder setDevice(int deviceId, String address) { + mDeviceId = deviceId; + mDeviceAddress = address; + return this; + } + + /** * Sets the {@link AudioFormat} for the mix. * @param format a non-null {@link AudioFormat} instance. * @return the same Builder instance. @@ -242,7 +270,8 @@ public class AudioMix { } /** - * Sets the routing behavior for the mix. + * Sets the routing behavior for the mix. If not set, routing behavior will default to + * {@link AudioMix#ROUTE_FLAG_LOOP_BACK}. * @param routeFlags one of {@link AudioMix#ROUTE_FLAG_LOOP_BACK}, * {@link AudioMix#ROUTE_FLAG_RENDER} * @return the same Builder instance. @@ -254,15 +283,41 @@ public class AudioMix { if (routeFlags == 0) { throw new IllegalArgumentException("Illegal empty route flags"); } - if ((routeFlags & (ROUTE_FLAG_LOOP_BACK | ROUTE_FLAG_RENDER)) == 0) { + if ((routeFlags & ROUTE_FLAG_SUPPORTED) == 0) { throw new IllegalArgumentException("Invalid route flags 0x" - + Integer.toHexString(routeFlags) + "when creating an AudioMix"); + + Integer.toHexString(routeFlags) + "when configuring an AudioMix"); + } + if ((routeFlags & ~ROUTE_FLAG_SUPPORTED) != 0) { + throw new IllegalArgumentException("Unknown route flags 0x" + + Integer.toHexString(routeFlags) + "when configuring an AudioMix"); } mRouteFlags = routeFlags; return this; } /** + * Sets the audio device used for playback. Cannot be used in the context of an audio + * policy used to inject audio to be recorded, or in a mix whose route flags doesn't + * specify {@link AudioMix#ROUTE_FLAG_RENDER}. + * @param device a non-null AudioDeviceInfo describing the audio device to play the output + * of this mix. + * @return the same Builder instance + * @throws IllegalArgumentException + */ + @SystemApi + public Builder setDevice(@NonNull AudioDeviceInfo device) throws IllegalArgumentException { + if (device == null) { + throw new IllegalArgumentException("Illegal null AudioDeviceInfo argument"); + } + if (!device.isSink()) { + throw new IllegalArgumentException("Unsupported device type on mix, not a sink"); + } + mDeviceId = device.getId(); + mDeviceAddress = device.getAddress(); + return this; + } + + /** * Combines all of the settings and return a new {@link AudioMix} object. * @return a new {@link AudioMix} object * @throws IllegalArgumentException if no {@link AudioMixingRule} has been set. @@ -273,8 +328,13 @@ public class AudioMix { throw new IllegalArgumentException("Illegal null AudioMixingRule"); } if (mRouteFlags == 0) { - // no route flags set, use default - mRouteFlags = ROUTE_FLAG_RENDER; + // no route flags set, use default as described in Builder.setRouteFlags(int) + mRouteFlags = ROUTE_FLAG_LOOP_BACK; + } + // can't do loop back AND render at same time in this implementation + if (mRouteFlags == (ROUTE_FLAG_RENDER | ROUTE_FLAG_LOOP_BACK)) { + throw new IllegalArgumentException("Unsupported route behavior combination 0x" + + Integer.toHexString(mRouteFlags)); } if (mFormat == null) { // FIXME Can we eliminate this? Will AudioMix work with an unspecified sample rate? @@ -284,7 +344,22 @@ public class AudioMix { } mFormat = new AudioFormat.Builder().setSampleRate(rate).build(); } - return new AudioMix(mRule, mFormat, mRouteFlags, mCallbackFlags); + if (mDeviceId != -1) { + if ((mRouteFlags & ROUTE_FLAG_RENDER) == 0) { + throw new IllegalArgumentException( + "Can't have audio device without flag ROUTE_FLAG_RENDER"); + } + if (mRule.getTargetMixType() != AudioMix.MIX_TYPE_PLAYERS) { + throw new IllegalArgumentException("Unsupported device on non-playback mix"); + } + } else { + if ((mRouteFlags & ROUTE_FLAG_RENDER) == ROUTE_FLAG_RENDER) { + throw new IllegalArgumentException( + "Can't have flag ROUTE_FLAG_RENDER without an audio device"); + } + } + return new AudioMix(mRule, mFormat, mRouteFlags, mCallbackFlags, mDeviceId, + mDeviceAddress); } } } diff --git a/media/java/android/media/audiopolicy/AudioPolicyConfig.java b/media/java/android/media/audiopolicy/AudioPolicyConfig.java index 5d2bac02a5e0..3af3ae71a734 100644 --- a/media/java/android/media/audiopolicy/AudioPolicyConfig.java +++ b/media/java/android/media/audiopolicy/AudioPolicyConfig.java @@ -17,6 +17,8 @@ package android.media.audiopolicy; import android.media.AudioFormat; +import android.media.AudioManager; +import android.media.AudioPatch; import android.media.audiopolicy.AudioMixingRule.AudioMixMatchCriterion; import android.os.Parcel; import android.os.Parcelable; @@ -81,6 +83,9 @@ public class AudioPolicyConfig implements Parcelable { dest.writeInt(mix.getRouteFlags()); // write callback flags dest.writeInt(mix.mCallbackFlags); + // write device information + dest.writeInt(mix.mDeviceId); + dest.writeString(mix.mDeviceAddress); // write mix format dest.writeInt(mix.getFormat().getSampleRate()); dest.writeInt(mix.getFormat().getEncoding()); @@ -104,6 +109,8 @@ public class AudioPolicyConfig implements Parcelable { mixBuilder.setRouteFlags(routeFlags); // read callback flags mixBuilder.setCallbackFlags(in.readInt()); + // read device information + mixBuilder.setDevice(in.readInt(), in.readString()); // read mix format int sampleRate = in.readInt(); int encoding = in.readInt(); @@ -197,8 +204,14 @@ public class AudioPolicyConfig implements Parcelable { int mixIndex = 0; for (AudioMix mix : mMixes) { if (!mRegistrationId.isEmpty()) { - mix.setRegistration(mRegistrationId + "mix" + mixTypeId(mix.getMixType()) + ":" - + mixIndex++); + if ((mix.getRouteFlags() & AudioMix.ROUTE_FLAG_LOOP_BACK) == + AudioMix.ROUTE_FLAG_LOOP_BACK) { + mix.setRegistration(mRegistrationId + "mix" + mixTypeId(mix.getMixType()) + ":" + + mixIndex++); + } else if ((mix.getRouteFlags() & AudioMix.ROUTE_FLAG_RENDER) == + AudioMix.ROUTE_FLAG_RENDER) { + mix.setRegistration(mix.mDeviceAddress); + } } else { mix.setRegistration(""); } diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml index 6f38e25e7158..6fe239e400dc 100644 --- a/packages/DocumentsUI/AndroidManifest.xml +++ b/packages/DocumentsUI/AndroidManifest.xml @@ -5,6 +5,8 @@ <uses-permission android:name="android.permission.MANAGE_DOCUMENTS" /> <uses-permission android:name="android.permission.REMOVE_TASKS" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> + <uses-permission android:name="android.permission.CACHE_CONTENT" /> + <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <application android:name=".DocumentsApplication" @@ -105,6 +107,12 @@ </intent-filter> </receiver> + <receiver android:name=".BootReceiver"> + <intent-filter> + <action android:name="android.intent.action.BOOT_COMPLETED" /> + </intent-filter> + </receiver> + <service android:name=".services.FileOperationService" android:exported="false"> diff --git a/packages/DocumentsUI/res/animator/dir_enter.xml b/packages/DocumentsUI/res/animator/dir_enter.xml index 7f547f135cd6..43c50bd6d4d9 100644 --- a/packages/DocumentsUI/res/animator/dir_enter.xml +++ b/packages/DocumentsUI/res/animator/dir_enter.xml @@ -13,10 +13,24 @@ limitations under the License. --> -<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" - android:valueFrom="1" - android:valueTo="0" - android:propertyName="position" - android:valueType="floatType" - android:duration="@android:integer/config_mediumAnimTime" - android:interpolator="@android:interpolator/decelerate_quad" /> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:ordering="together"> + + <objectAnimator + android:valueFrom="0f" + android:valueTo="1f" + android:propertyName="alpha" + android:valueType="floatType" + android:duration="@android:integer/config_mediumAnimTime" + android:interpolator="@android:interpolator/decelerate_quad" /> + + <!-- position property maps to AnimationView.setPosition --> + <objectAnimator + android:propertyName="position" + android:valueFrom="1" + android:valueTo="0" + android:valueType="floatType" + android:duration="@android:integer/config_mediumAnimTime" + android:interpolator="@android:interpolator/decelerate_quad" /> + +</set> diff --git a/packages/DocumentsUI/res/animator/dir_frozen.xml b/packages/DocumentsUI/res/animator/dir_frozen.xml deleted file mode 100644 index b541d137c5d9..000000000000 --- a/packages/DocumentsUI/res/animator/dir_frozen.xml +++ /dev/null @@ -1,21 +0,0 @@ -<!-- Copyright (C) 2013 The Android Open Source Project - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You 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. ---> - -<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" - android:valueFrom="0" - android:valueTo="0" - android:propertyName="position" - android:valueType="floatType" - android:duration="@android:integer/config_mediumAnimTime" /> diff --git a/packages/DocumentsUI/res/animator/dir_leave.xml b/packages/DocumentsUI/res/animator/dir_leave.xml index fda0faf4eff3..75746556d1aa 100644 --- a/packages/DocumentsUI/res/animator/dir_leave.xml +++ b/packages/DocumentsUI/res/animator/dir_leave.xml @@ -13,10 +13,24 @@ limitations under the License. --> -<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" - android:valueFrom="0" - android:valueTo="1" - android:propertyName="position" - android:valueType="floatType" - android:duration="@android:integer/config_mediumAnimTime" - android:interpolator="@android:interpolator/accelerate_quad" /> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:ordering="together"> + + <objectAnimator + android:valueFrom="1f" + android:valueTo="0f" + android:propertyName="alpha" + android:valueType="floatType" + android:duration="@android:integer/config_mediumAnimTime" + android:interpolator="@android:interpolator/decelerate_quad" /> + + <!-- position property maps to AnimationView.setPosition --> + <objectAnimator + android:valueFrom="0" + android:valueTo="1" + android:propertyName="position" + android:valueType="floatType" + android:duration="@android:integer/config_mediumAnimTime" + android:interpolator="@android:interpolator/accelerate_quad" /> + +</set>
\ No newline at end of file diff --git a/packages/DocumentsUI/res/animator-ldrtl/dir_enter.xml b/packages/DocumentsUI/res/animator/fade_in.xml index 6c7e2244c712..3ce012b96f64 100644 --- a/packages/DocumentsUI/res/animator-ldrtl/dir_enter.xml +++ b/packages/DocumentsUI/res/animator/fade_in.xml @@ -14,9 +14,9 @@ --> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" - android:valueFrom="-1" - android:valueTo="0" - android:propertyName="position" + android:valueFrom="0f" + android:valueTo="1f" + android:propertyName="alpha" android:valueType="floatType" android:duration="@android:integer/config_mediumAnimTime" android:interpolator="@android:interpolator/decelerate_quad" /> diff --git a/packages/DocumentsUI/res/animator-ldrtl/dir_leave.xml b/packages/DocumentsUI/res/animator/fade_out.xml index 8e2925c9760d..8d02c77fc345 100644 --- a/packages/DocumentsUI/res/animator-ldrtl/dir_leave.xml +++ b/packages/DocumentsUI/res/animator/fade_out.xml @@ -14,9 +14,9 @@ --> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" - android:valueFrom="0" - android:valueTo="-1" - android:propertyName="position" + android:valueFrom="1f" + android:valueTo="0f" + android:propertyName="alpha" android:valueType="floatType" android:duration="@android:integer/config_mediumAnimTime" - android:interpolator="@android:interpolator/accelerate_quad" /> + android:interpolator="@android:interpolator/decelerate_quad" /> diff --git a/packages/DocumentsUI/res/layout/fragment_directory.xml b/packages/DocumentsUI/res/layout/fragment_directory.xml index 03c6a833ca7d..8eb46ddffe48 100644 --- a/packages/DocumentsUI/res/layout/fragment_directory.xml +++ b/packages/DocumentsUI/res/layout/fragment_directory.xml @@ -14,7 +14,8 @@ limitations under the License. --> -<com.android.documentsui.DirectoryView xmlns:android="http://schemas.android.com/apk/res/android" +<com.android.documentsui.dirlist.AnimationView + xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/directory_background" @@ -99,4 +100,4 @@ </FrameLayout> -</com.android.documentsui.DirectoryView> +</com.android.documentsui.dirlist.AnimationView> diff --git a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java index c9d18b3791e6..1a8ce18ce03d 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/BaseActivity.java @@ -18,10 +18,6 @@ package com.android.documentsui; import static com.android.documentsui.Shared.DEBUG; import static com.android.documentsui.State.MODE_GRID; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_ENTER; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_LEAVE; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_SIDE; import android.app.Activity; import android.app.Fragment; @@ -48,6 +44,7 @@ import android.widget.Spinner; import com.android.documentsui.SearchViewManager.SearchManagerListener; import com.android.documentsui.State.ViewMode; +import com.android.documentsui.dirlist.AnimationView; import com.android.documentsui.dirlist.DirectoryFragment; import com.android.documentsui.dirlist.Model; import com.android.documentsui.model.DocumentInfo; @@ -225,7 +222,7 @@ public abstract class BaseActivity extends Activity // Otherwise we delegate loading data from disk to a task // to ensure a responsive ui. if (mRoots.isRecentsRoot(root)) { - refreshCurrentRootAndDirectory(ANIM_NONE); + refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE); } else { new PickRootTask(this, root).executeOnExecutor(getExecutorForCurrentDirectory()); } @@ -327,7 +324,7 @@ public abstract class BaseActivity extends Activity // previous directory. Especially after opening a root document, pressing // back, wouldn't go to the previous root, but close the activity. final int anim = (mState.hasLocationChanged() && mState.stack.size() > 1) - ? ANIM_ENTER : ANIM_NONE; + ? AnimationView.ANIM_ENTER : AnimationView.ANIM_NONE; refreshCurrentRootAndDirectory(anim); } @@ -543,7 +540,7 @@ public abstract class BaseActivity extends Activity // Update the restored stack to ensure we have freshest data stack.updateDocuments(getContentResolver()); mState.setStack(stack); - refreshCurrentRootAndDirectory(ANIM_SIDE); + refreshCurrentRootAndDirectory(AnimationView.ANIM_SIDE); } catch (FileNotFoundException e) { Log.w(mTag, "Failed to restore stack: " + e); @@ -644,7 +641,7 @@ public abstract class BaseActivity extends Activity private boolean popDir() { if (mState.stack.size() > 1) { mState.stack.pop(); - refreshCurrentRootAndDirectory(ANIM_LEAVE); + refreshCurrentRootAndDirectory(AnimationView.ANIM_LEAVE); return true; } return false; diff --git a/packages/DocumentsUI/src/com/android/documentsui/BootReceiver.java b/packages/DocumentsUI/src/com/android/documentsui/BootReceiver.java new file mode 100644 index 000000000000..cdea9d75fd82 --- /dev/null +++ b/packages/DocumentsUI/src/com/android/documentsui/BootReceiver.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.documentsui; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +/** + * Prime {@link RootsCache} when the system is booted. + */ +public class BootReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + // We already spun up our application object before getting here, which + // kicked off a task to load roots, so this broadcast is finished once + // that first pass is done. + DocumentsApplication.getRootsCache(context).setBootCompletedResult(goAsync()); + } +} diff --git a/packages/DocumentsUI/src/com/android/documentsui/DirectoryView.java b/packages/DocumentsUI/src/com/android/documentsui/DirectoryView.java deleted file mode 100644 index 000b92a0b1a5..000000000000 --- a/packages/DocumentsUI/src/com/android/documentsui/DirectoryView.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.documentsui; - -import android.content.Context; -import android.util.AttributeSet; -import android.widget.LinearLayout; - -public class DirectoryView extends LinearLayout { - private float mPosition = 0f; - - private int mWidth; - - public DirectoryView(Context context) { - super(context); - } - - public DirectoryView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - mWidth = w; - setPosition(mPosition); - } - - public float getPosition() { - return mPosition; - } - - public void setPosition(float position) { - mPosition = position; - setX((mWidth > 0) ? (mPosition * mWidth) : 0); - - if (mPosition != 0) { - setTranslationZ(getResources().getDimensionPixelSize(R.dimen.dir_elevation)); - } else { - setTranslationZ(0); - } - } -} diff --git a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java index f8b32a035539..ba593dc370bc 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/DocumentsActivity.java @@ -22,7 +22,6 @@ import static com.android.documentsui.State.ACTION_GET_CONTENT; import static com.android.documentsui.State.ACTION_OPEN; import static com.android.documentsui.State.ACTION_OPEN_TREE; import static com.android.documentsui.State.ACTION_PICK_COPY_DESTINATION; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE; import android.app.Activity; import android.app.Fragment; @@ -46,6 +45,7 @@ import android.view.MenuItem; import com.android.documentsui.RecentsProvider.RecentColumns; import com.android.documentsui.RecentsProvider.ResumeColumns; +import com.android.documentsui.dirlist.AnimationView; import com.android.documentsui.dirlist.DirectoryFragment; import com.android.documentsui.dirlist.Model; import com.android.documentsui.model.DocumentInfo; @@ -492,7 +492,7 @@ public class DocumentsActivity extends BaseActivity { protected void finish(Void result) { mState.restored = true; mState.external = mExternal; - mOwner.refreshCurrentRootAndDirectory(ANIM_NONE); + mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE); } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java index 573e4f3f5e74..99f306a44020 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java +++ b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java @@ -18,7 +18,6 @@ package com.android.documentsui; import static com.android.documentsui.OperationDialogFragment.DIALOG_TYPE_UNKNOWN; import static com.android.documentsui.Shared.DEBUG; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE; import android.app.Activity; import android.app.FragmentManager; @@ -39,6 +38,7 @@ import android.view.MenuItem; import com.android.documentsui.OperationDialogFragment.DialogType; import com.android.documentsui.RecentsProvider.ResumeColumns; +import com.android.documentsui.dirlist.AnimationView; import com.android.documentsui.dirlist.DirectoryFragment; import com.android.documentsui.dirlist.Model; import com.android.documentsui.model.DocumentInfo; @@ -97,7 +97,7 @@ public class FilesActivity extends BaseActivity { if (DEBUG) Log.d(TAG, "Launching with non-empty stack."); assert(uri == null || uri.getAuthority() == null || LauncherActivity.isLaunchUri(uri)); - refreshCurrentRootAndDirectory(ANIM_NONE); + refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE); } else if (intent.getAction() == Intent.ACTION_VIEW) { assert(uri != null); new OpenUriForViewTask(this).executeOnExecutor( @@ -283,10 +283,16 @@ public class FilesActivity extends BaseActivity { */ private void openDocument(DocumentInfo doc, Model model) { - // Provide specialized handling of downloaded APKs This sends the APK - // details off to get extra security information added, and finally - // to be handled by the package manager. - if (MimePredicate.isApkType(doc.mimeType)) { + // Anything on downloads goes through the back through downloads manager + // (that's the MANAGE_DOCUMENT bit). + // This is done for two reasons: + // 1) The file in question might be a failed/queued or otherwise have some + // specialized download handling. + // 2) For APKs, the download manager will add on some important security stuff + // like origin URL. + // All other files not on downloads, event APKs, would get no benefit from this + // treatment, thusly the "isDownloads" check. + if (getCurrentRoot().isDownloads()) { // First try managing the document; we expect manager to filter // based on authority, so we don't grant. final Intent manage = new Intent(DocumentsContract.ACTION_MANAGE_DOCUMENT); @@ -470,7 +476,7 @@ public class FilesActivity extends BaseActivity { @Override protected void finish(Void result) { - mOwner.refreshCurrentRootAndDirectory(ANIM_NONE); + mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE); } } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java b/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java index c5202042de69..30c1020d0dbd 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java +++ b/packages/DocumentsUI/src/com/android/documentsui/NavigationView.java @@ -19,7 +19,6 @@ package com.android.documentsui; import static android.view.View.GONE; import static android.view.View.VISIBLE; import static com.android.documentsui.Shared.DEBUG; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_LEAVE; import android.annotation.Nullable; import android.graphics.drawable.Drawable; @@ -30,10 +29,10 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.BaseAdapter; -import android.widget.ImageView; import android.widget.Spinner; import android.widget.TextView; +import com.android.documentsui.dirlist.AnimationView; import com.android.documentsui.model.DocumentInfo; import com.android.documentsui.model.RootInfo; @@ -105,7 +104,7 @@ class NavigationView { while (mState.stack.size() > position + 1) { mState.popDocument(); } - mEnv.refreshCurrentRootAndDirectory(ANIM_LEAVE); + mEnv.refreshCurrentRootAndDirectory(AnimationView.ANIM_LEAVE); } void update() { diff --git a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java index 2b7294a6e6d8..6efe9c8fae83 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java +++ b/packages/DocumentsUI/src/com/android/documentsui/RootsCache.java @@ -18,6 +18,7 @@ package com.android.documentsui; import static com.android.documentsui.Shared.DEBUG; +import android.content.BroadcastReceiver.PendingResult; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.Context; @@ -30,6 +31,7 @@ import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; +import android.os.Bundle; import android.os.Handler; import android.os.SystemClock; import android.provider.DocumentsContract; @@ -40,11 +42,11 @@ import android.util.Log; import com.android.documentsui.model.RootInfo; import com.android.internal.annotations.GuardedBy; +import libcore.io.IoUtils; + import com.google.common.collect.ArrayListMultimap; import com.google.common.collect.Multimap; -import libcore.io.IoUtils; - import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -63,6 +65,8 @@ public class RootsCache { private static final String TAG = "RootsCache"; + private static final boolean ENABLE_SYSTEM_CACHE = true; + private final Context mContext; private final ContentObserver mObserver; private OnCacheUpdateListener mCacheUpdateListener; @@ -73,6 +77,11 @@ public class RootsCache { private final CountDownLatch mFirstLoad = new CountDownLatch(1); @GuardedBy("mLock") + private boolean mFirstLoadDone; + @GuardedBy("mLock") + private PendingResult mBootCompletedResult; + + @GuardedBy("mLock") private Multimap<String, RootInfo> mRoots = ArrayListMultimap.create(); @GuardedBy("mLock") private HashSet<String> mStoppedAuthorities = new HashSet<>(); @@ -118,7 +127,7 @@ public class RootsCache { public void updateAsync() { // NOTE: This method is called when the UI language changes. - // For that reason we upadte our RecentsRoot to reflect + // For that reason we update our RecentsRoot to reflect // the current language. mRecentsRoot.title = mContext.getString(R.string.root_recent); @@ -152,7 +161,25 @@ public class RootsCache { } } - private void waitForFirstLoad() { + public void setBootCompletedResult(PendingResult result) { + synchronized (mLock) { + // Quickly check if we've already finished loading, otherwise hang + // out until first pass is finished. + if (mFirstLoadDone) { + result.finish(); + } else { + mBootCompletedResult = result; + } + } + } + + /** + * Block until the first {@link UpdateTask} pass has finished. + * + * @return {@code true} if cached roots is ready to roll, otherwise + * {@code false} if we timed out while waiting. + */ + private boolean waitForFirstLoad() { boolean success = false; try { success = mFirstLoad.await(15, TimeUnit.SECONDS); @@ -161,6 +188,7 @@ public class RootsCache { if (!success) { Log.w(TAG, "Timeout waiting for first update"); } + return success; } /** @@ -222,9 +250,11 @@ public class RootsCache { final long start = SystemClock.elapsedRealtime(); if (mFilterPackage != null) { - // Need at least first load, since we're going to be using - // previously cached values for non-matching packages. - waitForFirstLoad(); + // We must have previously cached values to fill in non-matching + // packages, so wait around for successful first load. + if (!waitForFirstLoad()) { + return null; + } } mTaskRoots.put(mRecentsRoot.authority, mRecentsRoot); @@ -243,6 +273,11 @@ public class RootsCache { if (DEBUG) Log.d(TAG, "Update found " + mTaskRoots.size() + " roots in " + delta + "ms"); synchronized (mLock) { + mFirstLoadDone = true; + if (mBootCompletedResult != null) { + mBootCompletedResult.finish(); + mBootCompletedResult = null; + } mRoots = mTaskRoots; mStoppedAuthorities = mTaskStoppedAuthorities; } @@ -300,9 +335,18 @@ public class RootsCache { } } - final List<RootInfo> roots = new ArrayList<>(); final Uri rootsUri = DocumentsContract.buildRootsUri(authority); + if (ENABLE_SYSTEM_CACHE) { + // Look for roots data that we might have cached for ourselves in the + // long-lived system process. + final Bundle systemCache = resolver.getCache(rootsUri); + if (systemCache != null) { + if (DEBUG) Log.d(TAG, "System cache hit for " + authority); + return systemCache.getParcelableArrayList(TAG); + } + } + final ArrayList<RootInfo> roots = new ArrayList<>(); ContentProviderClient client = null; Cursor cursor = null; try { @@ -318,6 +362,16 @@ public class RootsCache { IoUtils.closeQuietly(cursor); ContentProviderClient.releaseQuietly(client); } + + if (ENABLE_SYSTEM_CACHE) { + // Cache these freshly parsed roots over in the long-lived system + // process, in case our process goes away. The system takes care of + // invalidating the cache if the package or Uri changes. + final Bundle systemCache = new Bundle(); + systemCache.putParcelableArrayList(TAG, roots); + resolver.putCache(rootsUri, systemCache); + } + return roots; } diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/AnimationView.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/AnimationView.java new file mode 100644 index 000000000000..a66645655619 --- /dev/null +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/AnimationView.java @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.documentsui.dirlist; + +import android.annotation.IntDef; +import android.app.FragmentTransaction; +import android.content.Context; +import android.os.Bundle; +import android.util.AttributeSet; +import android.widget.LinearLayout; + +import com.android.documentsui.R; +import com.android.documentsui.Shared; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * This class exists solely to support animated transition of our directory fragment. + * The structure of this class is tightly coupled with the static animations defined in + * res/animator, specifically the "position" property referenced by + * res/animator/dir_{enter,leave}.xml. + */ +public class AnimationView extends LinearLayout { + + @IntDef(flag = true, value = { + ANIM_NONE, + ANIM_SIDE, + ANIM_LEAVE, + ANIM_ENTER + }) + @Retention(RetentionPolicy.SOURCE) + public @interface AnimationType {} + public static final int ANIM_NONE = 1; + public static final int ANIM_SIDE = 2; + public static final int ANIM_LEAVE = 3; + public static final int ANIM_ENTER = 4; + + private float mPosition = 0f; + + // The distance the animation will cover...currently matches the height of the + // content area. + private int mSpan; + + public AnimationView(Context context) { + super(context); + } + + public AnimationView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + mSpan = h; + setPosition(mPosition); + } + + public float getPosition() { + return mPosition; + } + + public void setPosition(float position) { + mPosition = position; + // Warning! If we ever decide to switch this to setX (slide left/right) + // please remember to add RLT variations of the animations under res/animator-ldrtl. + setY((mSpan > 0) ? (mPosition * mSpan) : 0); + + if (mPosition != 0) { + setTranslationZ(getResources().getDimensionPixelSize(R.dimen.dir_elevation)); + } else { + setTranslationZ(0); + } + } + + /** + * Configures custom animations on the transaction according to the specified + * @AnimationType. + */ + static void setupAnimations( + FragmentTransaction ft, @AnimationType int anim, Bundle args) { + switch (anim) { + case AnimationView.ANIM_SIDE: + args.putBoolean(Shared.EXTRA_IGNORE_STATE, true); + break; + case AnimationView.ANIM_ENTER: + // TODO: Document which behavior is being tailored + // by passing this bit. Remove if possible. + args.putBoolean(Shared.EXTRA_IGNORE_STATE, true); + ft.setCustomAnimations(R.animator.dir_enter, R.animator.fade_out); + break; + case AnimationView.ANIM_LEAVE: + ft.setCustomAnimations(R.animator.fade_in, R.animator.dir_leave); + break; + } + } +} diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java index 461bade4ae83..bfc8d71c3fdf 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DirectoryFragment.java @@ -84,7 +84,6 @@ import com.android.documentsui.Events; import com.android.documentsui.Events.MotionInputEvent; import com.android.documentsui.Menus; import com.android.documentsui.MessageBar; -import com.android.documentsui.MimePredicate; import com.android.documentsui.R; import com.android.documentsui.RecentsLoader; import com.android.documentsui.RootsCache; @@ -125,19 +124,6 @@ public class DirectoryFragment extends Fragment public static final int TYPE_RECENT_OPEN = 2; @IntDef(flag = true, value = { - ANIM_NONE, - ANIM_SIDE, - ANIM_LEAVE, - ANIM_ENTER - }) - @Retention(RetentionPolicy.SOURCE) - public @interface AnimationType {} - public static final int ANIM_NONE = 1; - public static final int ANIM_SIDE = 2; - public static final int ANIM_LEAVE = 3; - public static final int ANIM_ENTER = 4; - - @IntDef(flag = true, value = { REQUEST_COPY_DESTINATION }) @Retention(RetentionPolicy.SOURCE) @@ -1485,18 +1471,7 @@ public class DirectoryFragment extends Fragment args.putParcelable(Shared.EXTRA_SELECTION, new Selection()); final FragmentTransaction ft = fm.beginTransaction(); - switch (anim) { - case ANIM_SIDE: - args.putBoolean(Shared.EXTRA_IGNORE_STATE, true); - break; - case ANIM_ENTER: - args.putBoolean(Shared.EXTRA_IGNORE_STATE, true); - ft.setCustomAnimations(R.animator.dir_enter, R.animator.dir_frozen); - break; - case ANIM_LEAVE: - ft.setCustomAnimations(R.animator.dir_frozen, R.animator.dir_leave); - break; - } + AnimationView.setupAnimations(ft, anim, args); final DirectoryFragment fragment = new DirectoryFragment(); fragment.setArguments(args); diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java index 3eaf10a18a0f..3960475f5ecd 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java +++ b/packages/DocumentsUI/src/com/android/documentsui/model/RootInfo.java @@ -55,7 +55,7 @@ public class RootInfo implements Durable, Parcelable, Comparable<RootInfo> { private static final int VERSION_DROP_TYPE = 2; // The values of these constants determine the sort order of various roots in the RootsFragment. - @IntDef(flag = true, value = { + @IntDef(flag = false, value = { TYPE_IMAGES, TYPE_VIDEO, TYPE_AUDIO, diff --git a/packages/DocumentsUI/tests/AndroidManifest.xml b/packages/DocumentsUI/tests/AndroidManifest.xml index a3124275a6ad..b9862858558f 100644 --- a/packages/DocumentsUI/tests/AndroidManifest.xml +++ b/packages/DocumentsUI/tests/AndroidManifest.xml @@ -2,6 +2,8 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.documentsui.tests"> + <uses-permission android:name="android.permission.INTERNET" /> + <application> <uses-library android:name="android.test.runner" /> <provider diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java index 056e6ed87759..59dc2328efa5 100644 --- a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java +++ b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java @@ -19,10 +19,17 @@ package com.android.documentsui; import static com.android.documentsui.StubProvider.ROOT_0_ID; import static com.android.documentsui.StubProvider.ROOT_1_ID; +import android.app.DownloadManager; +import android.app.DownloadManager.Request; +import android.content.Context; +import android.net.Uri; import android.os.RemoteException; +import android.support.test.uiautomator.Configurator; +import android.support.test.uiautomator.UiObject; import android.test.suitebuilder.annotation.LargeTest; import android.test.suitebuilder.annotation.Suppress; import android.view.KeyEvent; +import android.view.MotionEvent; import com.android.documentsui.model.RootInfo; @@ -173,4 +180,37 @@ public class FilesActivityUiTest extends ActivityTest<FilesActivity> { bots.roots.assertHasFocus(); } } + + // We don't really need to test the entirety of download support + // since downloads is (almost) just another provider. + public void testDownload_Queued() throws Exception { + DownloadManager dm = (DownloadManager) context.getSystemService( + Context.DOWNLOAD_SERVICE); + // This downloads ends up being queued (because DNS can't be resolved). + // We'll still see an entry in the downloads UI with a "Queued" label. + dm.enqueue(new Request(Uri.parse("http://hammychamp.toodles"))); + + bots.roots.openRoot("Downloads"); + bots.directory.assertDocumentsPresent("Queued"); + } + + public void testDownload_RetryUnsuccessful() throws Exception { + DownloadManager dm = (DownloadManager) context.getSystemService( + Context.DOWNLOAD_SERVICE); + // This downloads fails! But it'll still show up. + dm.enqueue(new Request(Uri.parse("http://www.google.com/hamfancy"))); + + bots.roots.openRoot("Downloads"); + UiObject doc = bots.directory.findDocument("Unsuccessful"); + doc.waitForExists(TIMEOUT); + + int toolType = Configurator.getInstance().getToolType(); + Configurator.getInstance().setToolType(MotionEvent.TOOL_TYPE_FINGER); + doc.click(); + Configurator.getInstance().setToolType(toolType); + + assertTrue(bots.main.findDownloadRetryDialog().exists()); + + device.pressBack(); // to clear the dialog. + } } diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/UiBot.java b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/UiBot.java index 11f519411448..5b53cafd843d 100644 --- a/packages/DocumentsUI/tests/src/com/android/documentsui/bots/UiBot.java +++ b/packages/DocumentsUI/tests/src/com/android/documentsui/bots/UiBot.java @@ -173,6 +173,13 @@ public class UiBot extends BaseBot { return findObject("android:id/content", "android:id/text1"); } + public UiObject findDownloadRetryDialog() { + UiSelector selector = new UiSelector().text("Couldn't download"); + UiObject title = mDevice.findObject(selector); + title.waitForExists(mTimeout); + return title; + } + public UiObject findDialogOkButton() { UiObject object = findObject("android:id/content", "android:id/button1"); object.waitForExists(mTimeout); diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java index 72ad2f6a629e..8c73211cccf1 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java @@ -830,11 +830,21 @@ class MtpDatabase { if (info.getFormat() == MtpConstants.FORMAT_ASSOCIATION) { return DocumentsContract.Document.MIME_TYPE_DIR; } + final String formatCodeMimeType = MediaFile.getMimeTypeForFormatCode(info.getFormat()); + final String mediaFileMimeType = MediaFile.getMimeTypeForFile(info.getName()); + + // Format code can be mapped with multiple mime types, e.g. FORMAT_MPEG is mapped with + // audio/mp4 and video/mp4. + // As file extension contains more information than format code, returns mime type obtained + // from file extension if it is consistent with format code. + if (mediaFileMimeType != null && + MediaFile.getFormatCode("", mediaFileMimeType) == info.getFormat()) { + return mediaFileMimeType; + } if (formatCodeMimeType != null) { return formatCodeMimeType; } - final String mediaFileMimeType = MediaFile.getMimeTypeForFile(info.getName()); if (mediaFileMimeType != null) { return mediaFileMimeType; } diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java index e49a93594edb..b74069ae36bb 100644 --- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java +++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java @@ -17,6 +17,8 @@ package com.android.mtp; import android.database.Cursor; +import android.media.MediaFile; +import android.media.MediaFile.MediaFileType; import android.mtp.MtpConstants; import android.mtp.MtpObjectInfo; import android.net.Uri; @@ -1081,6 +1083,43 @@ public class MtpDatabaseTest extends AndroidTestCase { } } + public void testFormatCodeForMpeg() throws FileNotFoundException { + addTestDevice(); + addTestStorage("1"); + mDatabase.getMapper().startAddingDocuments("2"); + mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] { + createDocument(100, "audio.m4a", MtpConstants.FORMAT_MPEG, 1000), + createDocument(101, "video.m4v", MtpConstants.FORMAT_MPEG, 1000), + createDocument(102, "unknown.mp4", MtpConstants.FORMAT_MPEG, 1000), + createDocument(103, "inconsistent.txt", MtpConstants.FORMAT_MPEG, 1000), + createDocument(104, "noext", MtpConstants.FORMAT_UNDEFINED, 1000), + }); + mDatabase.getMapper().stopAddingDocuments("2"); + try (final Cursor cursor = mDatabase.queryChildDocuments( + strings(COLUMN_DISPLAY_NAME, COLUMN_MIME_TYPE), + "2")) { + assertEquals(5, cursor.getCount()); + cursor.moveToNext(); + assertEquals("audio.m4a", cursor.getString(0)); + assertEquals("audio/mp4", cursor.getString(1)); + cursor.moveToNext(); + assertEquals("video.m4v", cursor.getString(0)); + assertEquals("video/mp4", cursor.getString(1)); + cursor.moveToNext(); + // Assume that the file is video as we don't have any hints to find out if the file is + // video or audio. + assertEquals("unknown.mp4", cursor.getString(0)); + assertEquals("video/mp4", cursor.getString(1)); + // Don't return mime type that is inconsistent with format code. + cursor.moveToNext(); + assertEquals("inconsistent.txt", cursor.getString(0)); + assertEquals("video/mp4", cursor.getString(1)); + cursor.moveToNext(); + assertEquals("noext", cursor.getString(0)); + assertEquals("application/octet-stream", cursor.getString(1)); + } + } + private void addTestDevice() throws FileNotFoundException { TestUtil.addTestDevice(mDatabase); } diff --git a/packages/PrintSpooler/res/values-es/strings.xml b/packages/PrintSpooler/res/values-es/strings.xml index a0ce57afe569..dba0491fe70a 100644 --- a/packages/PrintSpooler/res/values-es/strings.xml +++ b/packages/PrintSpooler/res/values-es/strings.xml @@ -66,8 +66,8 @@ <string name="print_no_print_services" msgid="8561247706423327966">"No hay servicios de impresión habilitados"</string> <string name="print_no_printers" msgid="4869403323900054866">"No se encontraron impresoras"</string> <string name="cannot_add_printer" msgid="7840348733668023106">"No se pueden añadir impresoras"</string> - <string name="select_to_add_printers" msgid="3800709038689830974">"Seleccionar para añadir una impresora"</string> - <string name="enable_print_service" msgid="3482815747043533842">"Seleccionar para habilitar"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Selecciona para añadir una impresora"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Selecciona para habilitar"</string> <string name="enabled_services_title" msgid="7036986099096582296">"Servicios habilitados"</string> <string name="recommended_services_title" msgid="3799434882937956924">"Servicios recomendados"</string> <string name="disabled_services_title" msgid="7313253167968363211">"Servicios inhabilitados"</string> diff --git a/packages/PrintSpooler/res/values-ne-rNP/strings.xml b/packages/PrintSpooler/res/values-ne-rNP/strings.xml index e12c8dfc4ef7..5af3a04ed698 100644 --- a/packages/PrintSpooler/res/values-ne-rNP/strings.xml +++ b/packages/PrintSpooler/res/values-ne-rNP/strings.xml @@ -68,7 +68,7 @@ <string name="cannot_add_printer" msgid="7840348733668023106">"प्रिन्टरहरू थप्न सक्दैन"</string> <string name="select_to_add_printers" msgid="3800709038689830974">"प्रिन्टर थप्नका लागि चयन गर्नुहोस्"</string> <string name="enable_print_service" msgid="3482815747043533842">"सक्षम गर्नका लागि चयन गर्नुहोस्"</string> - <string name="enabled_services_title" msgid="7036986099096582296">"सेवाहरूलाई सक्षम गर्नुहोस्"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"सक्षम गरिएका सेवाहरू"</string> <string name="recommended_services_title" msgid="3799434882937956924">"सिफारिस गरिएका सेवाहरू"</string> <string name="disabled_services_title" msgid="7313253167968363211">"असक्षम गरिएका सेवाहरू"</string> <string name="all_services_title" msgid="5578662754874906455">"सबै सेवाहरू"</string> diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml index ee6266fc6a33..a6af5bd4ab31 100644 --- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml +++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml @@ -61,7 +61,7 @@ </plurals> <string name="printer_extended_description_template" msgid="1366699227703381874">"<xliff:g id="PRINT_SERVICE_LABEL">%1$s</xliff:g> – <xliff:g id="PRINTER_DESCRIPTION">%2$s</xliff:g>"</string> <string name="printer_info_desc" msgid="7181988788991581654">"Printer haqida batafsil ma’lumot"</string> - <string name="print_services_disabled_toast" msgid="9089060734685174685">"Bir qancha chop etish xizmatlari o‘chirilgan"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Ayrim chop etish xizmatlari o‘chirib qo‘yilgan"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Printerlar qidirilmoqda"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Hech qaysi chop etish xizmati yoqilmagan"</string> <string name="print_no_printers" msgid="4869403323900054866">"Printerlar topilmadi"</string> @@ -70,7 +70,7 @@ <string name="enable_print_service" msgid="3482815747043533842">"Yoqish uchun tanlang"</string> <string name="enabled_services_title" msgid="7036986099096582296">"Yoqilgan xizmatlar"</string> <string name="recommended_services_title" msgid="3799434882937956924">"Tavsiya etilgan xizmatlar"</string> - <string name="disabled_services_title" msgid="7313253167968363211">"O‘chirilgan xizmatlar"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"O‘chirib qo‘yilgan xizmatlar"</string> <string name="all_services_title" msgid="5578662754874906455">"Barcha xizmatlar"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Chop etilmoqda: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> bekor qilinmoqda"</string> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index 1b49eed4985c..e4c2cbc92702 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -625,7 +625,7 @@ <!-- UI debug setting: force allow apps on external storage [CHAR LIMIT=50] --> <string name="force_allow_on_external">Force allow apps on external</string> <!-- UI debug setting: force allow on external summary [CHAR LIMIT=150] --> - <string name="force_allow_on_external_summary">Makes any app elligible to be written to external storage, regardless of manifest values</string> + <string name="force_allow_on_external_summary">Makes any app eligible to be written to external storage, regardless of manifest values</string> <!-- UI debug setting: force all activites to be resizable for multiwindow [CHAR LIMIT=50] --> <string name="force_resizable_activities">Force activities to be resizable</string> diff --git a/packages/Shell/res/values-am/strings.xml b/packages/Shell/res/values-am/strings.xml index fae820ce84e0..b0d3de08fe42 100644 --- a/packages/Shell/res/values-am/strings.xml +++ b/packages/Shell/res/values-am/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"ቀፎ"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"የሳንካ ሪፖርት <xliff:g id="ID">#%d</xliff:g> እየተመነጨ ነው"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"የሳንካ ሪፖርት <xliff:g id="ID">#%d</xliff:g> ተወስዷል"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"የሳንካ ሪፖርት <xliff:g id="ID">#%d</xliff:g> ፎቶ ተነስቷል፣ ነገር ግን ቅጽበታዊ ገጽ ማያ በመጠባበቅ ላይ ነው"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"ዝርዝሮችን ወደ የሳንካ ሪፖርቱ በማከል ላይ"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"እባክዎ ይጠብቁ…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"የሳንካ ሪፖርትዎን ለማጋራት ወደ ግራ ያንሸራትቱ"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"የሳንካ ሪፖርትዎን ለማጋራት መታ ያድርጉ"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"የእርስዎን የሳንካ ሪፖርት ያለ ቅጽበታዊ ማያ ገጽ ለማጋራት መታ ያድርጉ ወይም ቅጽበታዊ ማያ ገጹ እስኪጨርስ ይጠብቁ"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"የእርስዎን የሳንካ ሪፖርት ያለ ቅጽበታዊ ማያ ገጽ ለማጋራት መታ ያድርጉ ወይም ቅጽበታዊ ማያ ገጹ እስኪጨርስ ይጠብቁ"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"የሳንካ ሪፖርቶች የግል መረጃን ጨምሮ ከበርካታ የስርዓቱ ምዝግብ ማስታወሻዎች የመጣ ውሂብን ይዟል። የሳንካ ሪፖርቶች ለሚያምኗቸው መተግበሪያዎችን እና ሰዎችን ብቻ ያጋሩ።"</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ይህን መልዕክት በሚቀጥለው ጊዜ አሳይ"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"የሳንካ ሪፖርቶች"</string> diff --git a/packages/Shell/res/values-az-rAZ/strings.xml b/packages/Shell/res/values-az-rAZ/strings.xml index 6172e7d559d1..22791a6ef639 100644 --- a/packages/Shell/res/values-az-rAZ/strings.xml +++ b/packages/Shell/res/values-az-rAZ/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Baq hesabatı <xliff:g id="ID">#%d</xliff:g> yaradıldı"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Baq hesabatı <xliff:g id="ID">#%d</xliff:g> alındı"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"<xliff:g id="ID">#%d</xliff:g> baq hesabatı çəkildi, amma skrinşot hələ gözlənilir"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Detallar baq hesabatına əlavə olunur"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Lütfən, gözləyin..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Baq raportunu paylaşmaq üçün sola sürüşdürün"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Baq hesabatınızı paylaşmaq üçün tıklayın"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"baq hesabatınızı skrinşot olmadan paylaşmaq üçün tıklayın, skrinşotun tamamlanması üçün isə gözləyin"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"baq hesabatınızı skrinşot olmadan paylaşmaq üçün tıklayın, skrinşotun tamamlanması üçün isə gözləyin"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Baq raportları sistemin müxtəlif jurnal fayllarından data içərir ki, buna şəxsi və konfidensial məlumatlar da aiddir. Yalnız inandığınız adamlarla baq raportlarını paylaşın."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bu mesajı növbəti dəfə göstər"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Baq hesabatları"</string> diff --git a/packages/Shell/res/values-bg/strings.xml b/packages/Shell/res/values-bg/strings.xml index 6a69f7de5b29..0f8676f1787c 100644 --- a/packages/Shell/res/values-bg/strings.xml +++ b/packages/Shell/res/values-bg/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Команден ред"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Сигналът за програмна грешка „<xliff:g id="ID">#%d</xliff:g>“ се генерира"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Сигналът за програмна грешка „<xliff:g id="ID">#%d</xliff:g>“ е заснет"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Сигналът (<xliff:g id="ID">#%d</xliff:g>) е заснет, но екр. снимка не е готова"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Подробностите се добавят към сигнала за пр. грешка"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Моля, изчакайте…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Прекарайте пръст наляво, за да споделите сигнала си за програмна грешка"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Докоснете, за да споделите сигнала си за програмна грешка"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Докоснете, за да споделите сигнала за прогр. грешка без екранна снимка, или изчакайте завършването й"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Докоснете, за да споделите сигнала за прогр. грешка без екранна снимка, или изчакайте завършването й"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Отчетите за програмни грешки съдържат данни от различни регистрационни файлове на системата, включително лична и поверителна информация. Споделяйте ги само с приложения и хора, на които имате доверие."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Това съобщение да се показва следващия път"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Отчети за прогр. грешки"</string> diff --git a/packages/Shell/res/values-bs-rBA/strings.xml b/packages/Shell/res/values-bs-rBA/strings.xml index a38be0e29a80..f4d71e910676 100644 --- a/packages/Shell/res/values-bs-rBA/strings.xml +++ b/packages/Shell/res/values-bs-rBA/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Ljuska"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Izvještaj o grešci <xliff:g id="ID">#%d</xliff:g> se generira"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Izvještaj o grešci <xliff:g id="ID">#%d</xliff:g> je snimljen"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Izvještaj o greškama <xliff:g id="ID">#%d</xliff:g> snimljen, čeka se snim. ekr."</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodavanje detalja u izvještaj o greškama"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Pričekajte..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Prevucite lijevo da podijelite izvještaj o greškama"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste podijelili izvještaj o grešci"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite da podijelite izveštaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite da podijelite izveštaj o greškama bez snimka ekrana ili sačekajte da snimak bude gotov"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Izvještaji o greškama sadrže podatke iz raznih zapisnika sistema, uključujući lične i privatne informacije. Podijelite izvještaje o greškama samo sa aplikacijama i osobama kojima vjerujete."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Pokaži ovu poruku sljedeći put"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Izvještaji o greškama"</string> diff --git a/packages/Shell/res/values-ca/strings.xml b/packages/Shell/res/values-ca/strings.xml index c246ec400dcf..3efb53b99cc3 100644 --- a/packages/Shell/res/values-ca/strings.xml +++ b/packages/Shell/res/values-ca/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Protecció"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"S\'està generant l\'informe d\'errors <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"S\'ha capturat l\'informe d\'errors <xliff:g id="ID">#%d</xliff:g>"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"L\'informe d\'errors <xliff:g id="ID">#%d</xliff:g> s\'ha capturat (captura pendent)"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"S\'estan afegint detalls a l\'informe d\'errors"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Espera…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Llisca cap a l\'esquerra per compartir l\'informe d\'errors."</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toca per compartir l\'informe d\'errors"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toca per compartir l\'informe d\'errors sense captura de pantalla o espera que es creï la captura"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toca per compartir l\'informe d\'errors sense captura de pantalla o espera que es creï la captura"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Els informes d\'error contenen dades dels diferents fitxers de registre del sistema, inclosa informació privada i personal. Comparteix els informes d\'error només amb les aplicacions i amb les persones en qui confies."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostra aquest missatge la propera vegada"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes d\'error"</string> diff --git a/packages/Shell/res/values-cs/strings.xml b/packages/Shell/res/values-cs/strings.xml index ebd9b5303175..afb6f9e8b5cb 100644 --- a/packages/Shell/res/values-cs/strings.xml +++ b/packages/Shell/res/values-cs/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Zpráva o chybě <xliff:g id="ID">#%d</xliff:g> se vytváří"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Zpráva o chybě <xliff:g id="ID">#%d</xliff:g> byla vytvořena"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Zpráva o chybě <xliff:g id="ID">#%d</xliff:g> byla vytvořena, čeká se na snímek"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Přidávání podrobností do zprávy o chybě"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Čekejte prosím…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Chcete-li hlášení chyby sdílet, přejeďte doleva."</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Zprávu o chybě můžete sdílet klepnutím"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Klepnutím můžete zprávu o chybě sdílet bez snímku obrazovky, nebo vyčkejte, než se snímek připraví"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Klepnutím můžete zprávu o chybě sdílet bez snímku obrazovky, nebo vyčkejte, než se snímek připraví"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Chybová hlášení obsahují data z různých souborů protokolů systému včetně osobních a soukromých informací. Chybová hlášení sdílejte pouze s aplikacemi a uživateli, kterým důvěřujete."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Zobrazit tuto zprávu příště"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Zprávy o chybách"</string> diff --git a/packages/Shell/res/values-es-rUS/strings.xml b/packages/Shell/res/values-es-rUS/strings.xml index 3f7f4d60fba7..307548a75140 100644 --- a/packages/Shell/res/values-es-rUS/strings.xml +++ b/packages/Shell/res/values-es-rUS/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Se está generando el informe de errores <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Se capturó el informe de errores <xliff:g id="ID">#%d</xliff:g>"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Informe de errores <xliff:g id="ID">#%d</xliff:g> capturado (captura pendiente)"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Agregando detalles al informe de errores"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Espera…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Desliza el dedo hacia la izquierda para compartir el informe de errores."</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toca para compartir el informe de errores"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toca para compartir tu informe de errores sin una captura de pantalla o espera a que finalice"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toca para compartir tu informe de errores sin una captura de pantalla o espera a que finalice"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Los informes de errores contienen datos de los distintos archivos de registro del sistema, incluida la información personal y privada. Comparte los informes de errores únicamente con aplicaciones y personas en las que confíes."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar este mensaje la próxima vez"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes de errores"</string> diff --git a/packages/Shell/res/values-eu-rES/strings.xml b/packages/Shell/res/values-eu-rES/strings.xml index 8f4d219796a1..7946f67aee92 100644 --- a/packages/Shell/res/values-eu-rES/strings.xml +++ b/packages/Shell/res/values-eu-rES/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell-interfazea"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Akatsen <xliff:g id="ID">#%d</xliff:g> txostena egiten ari gara"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Akatsen <xliff:g id="ID">#%d</xliff:g> txostena egin da"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Egin da <xliff:g id="ID">#%d</xliff:g> txostena. Pantaila-argazkia falta da."</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Akatsen txostenean xehetasunak gehitzen"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Itxaron, mesedez…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Programa-akatsen txostena partekatzeko, pasatu hatza ezkerrera"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Sakatu akatsen txostena partekatzeko"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Sakatu akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Sakatu akatsen txostena argazkirik gabe partekatzeko edo itxaron pantaila-argazkia atera arte"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Akatsen txostenek sistemaren erregistro-fitxategietako datuak dauzkate, informazio pertsonala eta pribatua barne. Akatsen txostenak partekatzen badituzu, partekatu soilik aplikazio eta pertsona fidagarriekin."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Erakutsi mezu hau hurrengoan"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Akatsen txostenak"</string> diff --git a/packages/Shell/res/values-fa/strings.xml b/packages/Shell/res/values-fa/strings.xml index c0f4d2adcae2..ecadf1a8fac6 100644 --- a/packages/Shell/res/values-fa/strings.xml +++ b/packages/Shell/res/values-fa/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"گزارش اشکال <xliff:g id="ID">#%d</xliff:g> در حال ایجاد شدن است"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"گزارش اشکال <xliff:g id="ID">#%d</xliff:g> ثبت شد"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"گزارش اشکال <xliff:g id="ID">#%d</xliff:g> گرفته شد اما عکس از صفحهنمایش هنوز نه"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"اضافه کردن جزئیات به گزارش اشکال"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"لطفاً منتظر بمانید..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"برای اشتراکگذاری گزارش اشکال، به تندی آن را به چپ بکشید"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"برای به اشتراک گذاشتن گزارش اشکال، ضربه بزنید"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"برای اشتراکگذاری گزارش مشکل بدون عکس صفحهنمایش، ضربه بزنید یا صبر کنید تا عکس صفحهنمایش گرفته شود."</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"برای اشتراکگذاری گزارش مشکل بدون عکس صفحهنمایش، ضربه بزنید یا صبر کنید تا عکس صفحهنمایش گرفته شود."</string> <string name="bugreport_confirm" msgid="5130698467795669780">"گزارشهای اشکال حاوی دادههایی از فایلهای گزارش مختلف در سیستم هستند، شامل اطلاعات شخصی و خصوصی. گزارشهای اشکال را فقط با افراد و برنامههای مورد اعتماد خود به اشتراک بگذارید."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"دفعه بعد این پیام نشان داده شود"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"گزارش اشکال"</string> diff --git a/packages/Shell/res/values-fi/strings.xml b/packages/Shell/res/values-fi/strings.xml index 64245aa5e005..b5ae006a8487 100644 --- a/packages/Shell/res/values-fi/strings.xml +++ b/packages/Shell/res/values-fi/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Komentotulkki"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Luodaan virheraporttia <xliff:g id="ID">#%d</xliff:g>."</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Virheraportti <xliff:g id="ID">#%d</xliff:g> tallennettu"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Virheraportti <xliff:g id="ID">#%d</xliff:g> tallennettu, kuvakaappaus odottaa."</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Lisätään tietoja virheraporttiin"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Odota…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Jaa virheraportti pyyhkäisemällä vasemmalle"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Jaa virheraportti napauttamalla."</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Jaa virheraportti ilman kuvakaappausta napauttamalla tai odota, että kuvakaappaus latautuu."</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Jaa virheraportti ilman kuvakaappausta napauttamalla tai odota, että kuvakaappaus latautuu."</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Virheraportit sisältävät järjestelmän lokitietoja, ja niihin voi sisältyä henkilökohtaisia ja yksityisiä tietoja. Jaa virheraportteja vain luotettaville sovelluksille ja käyttäjille."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Näytä tämä viesti seuraavalla kerralla"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Virheraportit"</string> diff --git a/packages/Shell/res/values-fr-rCA/strings.xml b/packages/Shell/res/values-fr-rCA/strings.xml index 9575273b2033..6c40edd4cea3 100644 --- a/packages/Shell/res/values-fr-rCA/strings.xml +++ b/packages/Shell/res/values-fr-rCA/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Rapport de bogue <xliff:g id="ID">#%d</xliff:g> généré"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Rapport de bogue <xliff:g id="ID">#%d</xliff:g> enregistré"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Rap. bogue <xliff:g id="ID">#%d</xliff:g> enreg., mais attente de saisie d\'écran"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Ajout de détails au rapport de bogue"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Veuillez patienter…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Faites glisser le doigt vers la gauche pour partager votre rapport de bogue."</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Touchez ici pour partager votre rapport de bogue"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Touchez pour partager le rapport de bogue sans saisie d\'écran ou attendez que la saisie soit prête"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Touchez pour partager le rapport de bogue sans saisie d\'écran ou attendez que la saisie soit prête"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Les rapports de bogue contiennent des données des fichiers journaux du système, y compris des informations personnelles et privées. Ne partagez les rapports de bogue qu\'avec les applications et les personnes que vous estimez fiables."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afficher ce message la prochaine fois"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapports de bogues"</string> diff --git a/packages/Shell/res/values-fr/strings.xml b/packages/Shell/res/values-fr/strings.xml index 83d30e6c861b..54f0b98c08f3 100644 --- a/packages/Shell/res/values-fr/strings.xml +++ b/packages/Shell/res/values-fr/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Le rapport de bug \"<xliff:g id="ID">#%d</xliff:g>\" est en cours de création"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Le rapport de bug \"<xliff:g id="ID">#%d</xliff:g>\" a bien été enregistré"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Rapport bug \"<xliff:g id="ID">#%d</xliff:g>\" enregistré, mais attente capt. écran"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Ajout d\'informations au rapport de bug"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Veuillez patienter…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Faites glisser le doigt vers la gauche pour partager votre rapport d\'erreur."</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Appuyer pour partager votre rapport de bug"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Appuyer pour partager rapport de bug sans capture d\'écran ou attendre finalisation capture d\'écran"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Appuyer pour partager rapport de bug sans capture d\'écran ou attendre finalisation capture d\'écran"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Les rapports de bug contiennent des données des fichiers journaux du système, y compris des informations personnelles et privées. Ne partagez les rapports de bug qu\'avec les applications et les personnes que vous estimez fiables."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afficher ce message la prochaine fois"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapports d\'erreur"</string> diff --git a/packages/Shell/res/values-hy-rAM/strings.xml b/packages/Shell/res/values-hy-rAM/strings.xml index 3cfe2f7c9903..c9351c2de692 100644 --- a/packages/Shell/res/values-hy-rAM/strings.xml +++ b/packages/Shell/res/values-hy-rAM/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Խեցի"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"<xliff:g id="ID">#%d</xliff:g> վրիպակի զեկույցը ստեղծվում է"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"<xliff:g id="ID">#%d</xliff:g> վրիպակի զեկույցը գրանցվեց"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"<xliff:g id="ID">#%d</xliff:g> վրիպակի զեկույցը ստեղծվել է, սակայն էկրանի պատկերը դեռ չի ստացվել"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Տվյալների ավելացում վրիպակի զեկույցում"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Խնդրում ենք սպասել…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Սահեցրեք ձախ՝ սխալի հաշվետվությունը համօգտագործելու համար"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Հպեք՝ վրիպակի զեկույցը տրամադրելու համար"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Հպեք՝ վրիպակի զեկույցն առանց էկրանի պատկերի ուղարկելու համար կամ սպասեք էկրանի պատկերի ստեղծմանը"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Հպեք՝ վրիպակի զեկույցն առանց էկրանի պատկերի ուղարկելու համար կամ սպասեք էկրանի պատկերի ստեղծմանը"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Վրիպակի զեկույցները պարունակում են տվյալներ համակարգի տարբեր մուտքի ֆայլերից, այդ թվում նաև անհատական և գաղտնի տեղեկություններ: Վրիպակի զեկույցները կիսեք միայն այն հավելվածների և մարդկանց հետ, որոնց վստահում եք:"</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Այս հաղորդագրությունը ցույց տալ հաջորդ անգամ"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Վրիպակների հաշվետվություններ"</string> diff --git a/packages/Shell/res/values-ja/strings.xml b/packages/Shell/res/values-ja/strings.xml index 33ddec97abf7..a6ff33eef24f 100644 --- a/packages/Shell/res/values-ja/strings.xml +++ b/packages/Shell/res/values-ja/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"シェル"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"バグレポート <xliff:g id="ID">#%d</xliff:g> の生成中"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"バグレポート <xliff:g id="ID">#%d</xliff:g> の記録完了"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"バグレポート <xliff:g id="ID">#%d</xliff:g> 記録完了: スクリーンショット待ち"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"バグレポートに詳細情報を追加しています"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"お待ちください…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"バグレポートを共有するには左にスワイプ"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"バグレポートを共有するにはタップします"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"タップしてバグレポートをスクリーンショットなしで共有するか、スクリーンショット完成までお待ちください"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"タップしてバグレポートをスクリーンショットなしで共有するか、スクリーンショット完成までお待ちください"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"バグレポートには、個人の非公開情報など、システムのさまざまなログファイルのデータが含まれます。共有する場合は信頼するアプリとユーザーのみを選択してください。"</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"このメッセージを次回も表示する"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"バグレポート"</string> diff --git a/packages/Shell/res/values-ka-rGE/strings.xml b/packages/Shell/res/values-ka-rGE/strings.xml index 61bdff7c8cb5..119c360e2c06 100644 --- a/packages/Shell/res/values-ka-rGE/strings.xml +++ b/packages/Shell/res/values-ka-rGE/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"გარეკანი"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ხარვეზების შესახებ ანგარიში <xliff:g id="ID">#%d</xliff:g> გენერირდება"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"ხარვეზების შესახებ ანგარიში <xliff:g id="ID">#%d</xliff:g> აღბეჭდილია"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"ხარვეზის ანგარიში <xliff:g id="ID">#%d</xliff:g> მზადაა. იქმნება ეკრანის ანაბეჭდი"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"ხარვეზის შესახებ ანგარიშს დეტალები ემატება"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"გთხოვთ, მოითმინოთ..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"გაასრიალეთ მარცხნივ თქვენი ხარვეზის შეტყობინების გასაზიარებლად"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"შეეხეთ ხარვეზების შესახებ ანგარიშის გასაზიარებლად"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"შეეხეთ ხარვეზის შესახებ ანგარიშის ეკრანის ანაბეჭდის გარეშე გასაზიარებლად, ან დაელოდეთ მის შექმნას"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"შეეხეთ ხარვეზის შესახებ ანგარიშის ეკრანის ანაბეჭდის გარეშე გასაზიარებლად, ან დაელოდეთ მის შექმნას"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"ხარვეზის ანგარიშები მოიცავს მონაცემებს სხვადასხვა სისტემური ჟურნალის ფაილებიდან, მათ შორის პირად და კონფიდენციალურ ინფორმაციას."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"შემდგომში აჩვენე ეს შეტყობინება"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"შეცდომების ანგარიშები"</string> diff --git a/packages/Shell/res/values-kk-rKZ/strings.xml b/packages/Shell/res/values-kk-rKZ/strings.xml index 403615a4dc2c..9c2e4e73f346 100644 --- a/packages/Shell/res/values-kk-rKZ/strings.xml +++ b/packages/Shell/res/values-kk-rKZ/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Қабыршық"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"<xliff:g id="ID">#%d</xliff:g> қате туралы есебі жасалуда"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"<xliff:g id="ID">#%d</xliff:g> қате туралы есебі жазып алынды"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"<xliff:g id="ID">#%d</xliff:g> қате туралы есебі жазып алынды, бірақ скриншот күтуде"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Қате туралы есепке мәліметтер қосылуда"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Күте тұрыңыз…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Қате туралы есепті бөлісу үшін солға жанаңыз"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Қате туралы есепті бөлісу үшін түртіңіз"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Қате туралы есепті скриншотсыз бөлісу үшін түртіңіз немесе скриншоттың аяқталуын күтіңіз"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Қате туралы есепті скриншотсыз бөлісу үшін түртіңіз немесе скриншоттың аяқталуын күтіңіз"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Вирус туралы баянатта жүйеде тіркелген әртүрлі файлдар туралы деректер болады, оған жеке және құпия ақпарат та кіреді. Вирус баянаттарын сенімді қолданбалар және сенімді адамдармен ғана бөлісіңіз."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Бұл хабарды келесі жолы көрсетіңіз"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Қате туралы баяндамалар"</string> diff --git a/packages/Shell/res/values-km-rKH/strings.xml b/packages/Shell/res/values-km-rKH/strings.xml index 05f5cc5c14b7..d5fc400c46bb 100644 --- a/packages/Shell/res/values-km-rKH/strings.xml +++ b/packages/Shell/res/values-km-rKH/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"សែល"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"<xliff:g id="ID">#%d</xliff:g> របាយការណ៍កំហុសកំពុងត្រូវបានបង្កើត"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"<xliff:g id="ID">#%d</xliff:g> របាយការណ៍កំហុសត្រូវបានថត"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"<xliff:g id="ID">#%d</xliff:g> របាយការណ៍កំហុសត្រូវបានថត ប៉ុន្តែរូបថតអេក្រង់មិនទាន់បានថតនៅឡើយទេ"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"កំពុងបន្ថែមព័ត៌មានលម្អិតទៅរបាយការណ៍កំហុស"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"សូមរង់ចាំ…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"អូសទៅឆ្វេង ដើម្បីចែករំលែករបាយការណ៍កំហុសរបស់អ្នក"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"ប៉ះដើម្បីចែករំលែករបាយការណ៍កំហុសរបស់អ្នក"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"ប៉ះដើម្បីចែករំលែករបាយការណ៍កំហុសរបស់អ្នកដោយមិនចាំបាច់មានរូបថតអេក្រង់ ឬរង់ចាំការបញ្ចប់ការថតអេក្រង់"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ប៉ះដើម្បីចែករំលែករបាយការណ៍កំហុសរបស់អ្នកដោយមិនចាំបាច់មានរូបថតអេក្រង់ ឬរង់ចាំការបញ្ចប់ការថតអេក្រង់"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"របាយការណ៍កំហុសរួមមានឯកសារកំណត់ហេតុផ្សេងៗរបស់ប្រព័ន្ធ រួមមានព័ត៌មានផ្ទាល់ខ្លួន និងឯកជន។ ចែករំលែករបាយការណ៍កំហុសជាមួយកម្មវិធី និងមនុស្សដែលអ្នកទុកចិត្ត។"</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"បង្ហាញសារនេះពេលក្រោយ"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"រាយការណ៍ពីកំហុស"</string> diff --git a/packages/Shell/res/values-ko/strings.xml b/packages/Shell/res/values-ko/strings.xml index 808730485abe..4c0a16988eff 100644 --- a/packages/Shell/res/values-ko/strings.xml +++ b/packages/Shell/res/values-ko/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"셸"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"버그 신고 <xliff:g id="ID">#%d</xliff:g> 생성 중"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"버그 신고 <xliff:g id="ID">#%d</xliff:g> 캡처됨"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"버그 신고 <xliff:g id="ID">#%d</xliff:g>이(가) 캡처되었으나 스크린샷 대기 중"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"세부정보를 버그 보고서에 추가"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"잠시 기다려 주세요..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"왼쪽으로 스와이프하여 버그 신고서를 공유하세요."</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"버그 신고를 공유하려면 탭하세요."</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"스크린샷 없이 버그 신고서를 공유하려면 탭하고 그렇지 않으면 스크린샷이 완료될 때까지 기다려 주세요."</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"스크린샷 없이 버그 신고서를 공유하려면 탭하고 그렇지 않으면 스크린샷이 완료될 때까지 기다려 주세요."</string> <string name="bugreport_confirm" msgid="5130698467795669780">"버그 신고서는 시스템의 다양한 로그 파일 데이터(예: 개인 및 비공개 정보)를 포함합니다. 신뢰할 수 있는 앱과 사용자에게만 버그 신고서를 공유하세요."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"다음에 이 메시지 표시"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"버그 신고"</string> diff --git a/packages/Shell/res/values-ky-rKG/strings.xml b/packages/Shell/res/values-ky-rKG/strings.xml index cc5b2e502e11..e4039fe8c78e 100644 --- a/packages/Shell/res/values-ky-rKG/strings.xml +++ b/packages/Shell/res/values-ky-rKG/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Командалык кабык"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Мүчүлүштүк тууралуу билдирүү <xliff:g id="ID">#%d</xliff:g> түзүлүүдө"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Мүчүлүштүк тууралуу билдирүү <xliff:g id="ID">#%d</xliff:g> жаздырылды"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Мүчүлүштүк тууралуу билдирүү <xliff:g id="ID">#%d</xliff:g> жаздырылды, бирок скриншот күтүлүүдө"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Мүчүлүштүк жөнүндө кабардын чоо-жайы кошулууда"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Күтө туруңуз…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Ката жөнүндө кабар менен бөлүшүү үчүн солго серпип коюңуз"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Мүчүлүштүк тууралуу билдирүүңүздү бөлүшүү үчүн таптап коюңуз"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Мүчүлүштүк тууралуу билдирүүңүздү скриншотсуз бөлүшүү үчүн таптап коюңуз же скриншот даяр болгуча күтө туруңуз"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Мүчүлүштүк тууралуу билдирүүңүздү скриншотсуз бөлүшүү үчүн таптап коюңуз же скриншот даяр болгуча күтө туруңуз"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Ката тууралуу билдирүүлөр системанын ар кандай лог файлдарынын берилиштерин камтыйт, аларга өздүк жана купуя маалыматтар дагы кирет. Ката тууралуу билдирүүлөрдү сиз ишенген колдонмолор жана адамдар менен гана бөлүшүңүз."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Бул билдирүү кийин көрсөтүлсүн"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Мүчүлүштүктөрдү кабарлоолор"</string> diff --git a/packages/Shell/res/values-lo-rLA/strings.xml b/packages/Shell/res/values-lo-rLA/strings.xml index 7685d4431c5f..28045286ec89 100644 --- a/packages/Shell/res/values-lo-rLA/strings.xml +++ b/packages/Shell/res/values-lo-rLA/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ກຳລັງສ້າງລາຍງານຂໍ້ຜິດພາດ <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"ບັນທຶກລາຍງານຂໍ້ຜິດພາດ <xliff:g id="ID">#%d</xliff:g> ແລ້ວ"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"ບັນທຶກລາຍງານຂໍ້ຜິດພາດ <xliff:g id="ID">#%d</xliff:g> ແລ້ວແຕ່ກຳລັງລໍຖ້າຮູບໜ້າຈໍຢູ່"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"ກຳລັງເພີ່ມລາຍລະອຽດໃສ່ລາຍງານຂໍ້ຜິດພາດ"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"ກະລຸນາລໍຖ້າ..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"ປັດໄປຊ້າຍເພື່ອສົ່ງລາຍງານຂໍ້ຜິດພາດຂອງທ່ານ"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"ແຕະເພື່ອແບ່ງປັນລາຍງານຂໍ້ຜິດພາດຂອງທ່ານ"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"ແຕະເພື່ອແບ່ງປັນລາຍງານຂໍ້ຜິດພາດຂອງທ່ານໂດຍບໍ່ໃຊ້ຮູບໜ້າຈໍ ຫຼື ລໍຖ້າໃຫ້ຮູບໜ້າຈໍແລ້ວໆ"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ແຕະເພື່ອແບ່ງປັນລາຍງານຂໍ້ຜິດພາດຂອງທ່ານໂດຍບໍ່ໃຊ້ຮູບໜ້າຈໍ ຫຼື ລໍຖ້າໃຫ້ຮູບໜ້າຈໍແລ້ວໆ"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"ການລາຍງານຂໍ້ຜິດພາດປະກອບມີ ຂໍ້ມູນຈາກໄຟລ໌ບັນທຶກຂອງລະບົບຫຼາຍໄຟລ໌, ຮວມທັງຂໍ້ມູນສ່ວນໂຕນຳ. ທ່ານຕ້ອງແບ່ງປັນລາຍງານຂໍ້ຜິດພາດໃຫ້ແອັບຯ ແລະຄົນທີ່ທ່ານເຊື່ອຖືໄດ້ເທົ່ານັ້ນ."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ສະແດງຂໍ້ຄວາມນີ້ອີກໃນເທື່ອຕໍ່ໄປ"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"ລາຍງານບັນຫາ"</string> diff --git a/packages/Shell/res/values-lt/strings.xml b/packages/Shell/res/values-lt/strings.xml index 202401ad873d..a8468cfadcee 100644 --- a/packages/Shell/res/values-lt/strings.xml +++ b/packages/Shell/res/values-lt/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Apvalkalas"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Pranešimas apie riktą (<xliff:g id="ID">#%d</xliff:g>) generuojamas"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Pranešimas apie riktą (<xliff:g id="ID">#%d</xliff:g>) užfiksuotas"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Pranešimas apie riktą (<xliff:g id="ID">#%d</xliff:g>) užfiksuotas, bet laukiama ekrano kopijos"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Pridedama informacijos prie pranešimo apie riktą"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Palaukite…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Perbraukite kairėn, kad bendrintumėte rikto ataskaitą"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Palieskite, kad bendrintumėte pranešimą apie riktą"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Palieskite ir bendrinkite pranešimą apie riktą be ekrano kopijos arba palaukite, kol ji bus sukurta"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Palieskite ir bendrinkite pranešimą apie riktą be ekrano kopijos arba palaukite, kol ji bus sukurta"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Riktų ataskaitose pateikiami duomenys iš įvairių sistemos žurnalo failų, įskaitant asmeninę ir privačią informaciją. Riktų ataskaitas bendrinkite tik su patikimomis programomis ir žmonėmis."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Rodyti šį pranešimą kitą kartą"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Riktų ataskaitos"</string> diff --git a/packages/Shell/res/values-lv/strings.xml b/packages/Shell/res/values-lv/strings.xml index 93de35d94fa4..08e25be530da 100644 --- a/packages/Shell/res/values-lv/strings.xml +++ b/packages/Shell/res/values-lv/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Aizsargs"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Kļūdas pārskats <xliff:g id="ID">#%d</xliff:g> tiek ģenerēts"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Kļūdas pārskats <xliff:g id="ID">#%d</xliff:g> reģistrēts"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Kļūdas pārskats <xliff:g id="ID">#%d</xliff:g> izveidots; gaida ekrānuzņēmumu"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Informācijas pievienošana kļūdas pārskatam"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Lūdzu, uzgaidiet..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Velciet pa kreisi, lai kopīgotu savu kļūdu ziņojumu."</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Pieskarieties, lai kopīgotu kļūdas pārskatu."</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Pieskarieties, lai kopīgotu kļūdas pārskatu bez ekrānuzņēmuma vai gaidiet ekrānuzņēmumu."</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Pieskarieties, lai kopīgotu kļūdas pārskatu bez ekrānuzņēmuma vai gaidiet ekrānuzņēmumu."</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Kļūdu pārskatā ir iekļauti dati no dažādiem sistēmas žurnālfailiem, tostarp personas dati un privāta informācija. Kļūdu pārskatus ieteicams kopīgot tikai ar uzticamām lietotnēm un lietotājiem."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Rādīt šo ziņojumu nākamajā reizē"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Kļūdu ziņojumi"</string> diff --git a/packages/Shell/res/values-mk-rMK/strings.xml b/packages/Shell/res/values-mk-rMK/strings.xml index f274f6d954f1..3f879b7e7c43 100644 --- a/packages/Shell/res/values-mk-rMK/strings.xml +++ b/packages/Shell/res/values-mk-rMK/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Обвивка"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Се генерира извештајот за грешки <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Извештајот за грешки <xliff:g id="ID">#%d</xliff:g> е снимен"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Извештајот за грешка <xliff:g id="ID">#%d</xliff:g> е снимен. Се чека на сликата"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Се додаваат детали на извештајот за грешка"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Почекајте..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Повлечете налево за да споделите пријава за грешка"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Допрете за да го споделите извештајот за грешки"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Допрете за споделување извештај за грешки без слика од екранот или почекајте да се подготви сликата"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Допрете за споделување извештај за грешки без слика од екранот или почекајте да се подготви сликата"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Извештаите за грешка содржат податоци од разни датотеки за евиденција на системот, вклучувајќи лични и приватни информации. Извештаите за грешка споделувајте ги само со апликации и луѓе на коишто им верувате."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Прикажи ја поракава следниот пат"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Извештаи за грешки"</string> diff --git a/packages/Shell/res/values-ml-rIN/strings.xml b/packages/Shell/res/values-ml-rIN/strings.xml index d5d2e4e5e372..3bb715d822d1 100644 --- a/packages/Shell/res/values-ml-rIN/strings.xml +++ b/packages/Shell/res/values-ml-rIN/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"ഷെൽ"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ബഗ് റിപ്പോർട്ട് <xliff:g id="ID">#%d</xliff:g> സൃഷ്ടിക്കുന്നു"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"ബഗ് റിപ്പോർട്ട് <xliff:g id="ID">#%d</xliff:g> ക്യാപ്ചർ ചെയ്തു"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"ബഗ് റിപ്പോർട്ട് <xliff:g id="ID">#%d</xliff:g> ക്യാപ്ചർ ചെയ്തു, എന്നാൽ സ്ക്രീൻഷോട്ട് ശേഷിക്കുന്നു"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"ബഗ് റിപ്പോർട്ടിലേക്ക് വിശദാംശങ്ങൾ ചേർക്കുന്നു"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"കാത്തിരിക്കുക..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടുന്നതിന് ഇടത്തേയ്ക്ക് സ്വൈപ്പുചെയ്യുക"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"സ്ക്രീൻഷോട്ട് കൂടാതെയോ സ്ക്രീൻഷോട്ട് പൂർത്തിയാകുന്നതിന് കാക്കാതെയോ നിങ്ങളുടെ ബഗ് റിപ്പോർട്ട് പങ്കിടാൻ ടാപ്പുചെയ്യുക"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"വ്യക്തിഗതവും സ്വകാര്യവുമായ വിവരങ്ങൾ ഉൾപ്പെടെ, സിസ്റ്റത്തിന്റെ നിരവധി ലോഗ് ഫയലുകളിൽ നിന്നുള്ള ഡാറ്റ, ബഗ് റിപ്പോർട്ടുകളിൽ അടങ്ങിയിരിക്കുന്നു. നിങ്ങൾ വിശ്വസിക്കുന്ന അപ്ലിക്കേഷനുകൾക്കും ആളുകൾക്കും മാത്രം ബഗ് റിപ്പോർട്ടുകൾ പങ്കിടുക."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ഈ സന്ദേശം അടുത്ത തവണ ദൃശ്യമാക്കുക"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"ബഗ് റിപ്പോർട്ടുകൾ"</string> diff --git a/packages/Shell/res/values-mn-rMN/strings.xml b/packages/Shell/res/values-mn-rMN/strings.xml index cce21078b147..296afabf8ff5 100644 --- a/packages/Shell/res/values-mn-rMN/strings.xml +++ b/packages/Shell/res/values-mn-rMN/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Шел"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Програмд гарсан алдааны мэдээллийн <xliff:g id="ID">#%d</xliff:g> үүсгэгдэж байна"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Програмд гарсан алдааны мэдээллийн <xliff:g id="ID">#%d</xliff:g>-г бүртгэгдлээ"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Алдааны тайлан <xliff:g id="ID">#%d</xliff:g>-г илрүүлсэн хэдий ч дэлгэцээс авсан зураг хүлээгдэж байна"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Алдааны тайланд дэлгэрэнгүй мэдээлэл нэмж байна"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Түр хүлээнэ үү..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Өөрийн согог репортыг хуваалцахын тулд зүүн шудрана уу"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Програмд гарсан алдааны мэдээллээ хуваалцах бол дарна уу"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Алдааны тайлангаа дэлгэцээс авсан зураггүйгээр хуваалцах бол дарж, эсвэл дэлгэцээс авсан зургийг бэлэн болтол нь хүлээнэ үү"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Алдааны тайлангаа дэлгэцээс авсан зураггүйгээр хуваалцах бол дарж, эсвэл дэлгэцээс авсан зургийг бэлэн болтол нь хүлээнэ үү"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Алдааны репорт нь хувийн болон нууц мэдээлэл зэргийг агуулсан системийн төрөл бүрийн лог файлын датаг агуулна. Алдааны репортыг зөвхөн итгэлтэй апп болон хүмүүст хуваалцана уу."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Энэ мессежийг дараагийн удаа харуулах"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Гэмтлийн тухай тайлан"</string> diff --git a/packages/Shell/res/values-ms-rMY/strings.xml b/packages/Shell/res/values-ms-rMY/strings.xml index b23a382a4519..e758745f4e78 100644 --- a/packages/Shell/res/values-ms-rMY/strings.xml +++ b/packages/Shell/res/values-ms-rMY/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Laporan pepijat <xliff:g id="ID">#%d</xliff:g> sedang dijana"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Laporan pepijat <xliff:g id="ID">#%d</xliff:g> telah ditangkap"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Laporan pepijat <xliff:g id="ID">#%d</xliff:g> ditangkap, menunggu tngkpn skrin"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Menambahkan butiran pada laporan pepijat"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Sila tunggu…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Leret ke kiri untuk berkongsi laporan pepijat anda"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Ketik untuk berkongsi laporan pepijat anda"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Ketik untuk berkongsi laporan pepijat anda tanpa tangkapan skrin atau tunggu sehingga tangkapan skrin selesai"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Ketik untuk berkongsi laporan pepijat anda tanpa tangkapan skrin atau tunggu sehingga tangkapan skrin selesai"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Laporan pepijat mengandungi data dari pelbagai fail log sistem, termasuk maklumat peribadi dan sulit. Kongsikan laporan pepijat hanya dengan apl dan orang yang anda percayai."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tunjukkan mesej ini pada masa akan datang"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Laporan pepijat"</string> diff --git a/packages/Shell/res/values-my-rMM/strings.xml b/packages/Shell/res/values-my-rMM/strings.xml index cecd20fcf27a..6f02e70a3cdc 100644 --- a/packages/Shell/res/values-my-rMM/strings.xml +++ b/packages/Shell/res/values-my-rMM/strings.xml @@ -19,13 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"အခွံ"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"ချွတ်ယွင်းမှုအစီရင်ခံချက် <xliff:g id="ID">#%d</xliff:g> ကိုထုတ်နေပါသည်"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"ချွတ်ယွင်းမှုအစီရင်ခံချက် <xliff:g id="ID">#%d</xliff:g> ကိုရယူထားပြီးပါပြီ"</string> - <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"ချွတ်ယွင်းချက် အစီရင်ခံစာ <xliff:g id="ID">#%d</xliff:g> ဖမ်းယူထားသည် သို့သော် မျက်နှာပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း စောင့်ဆိုင်းနေသည်"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"ချွတ်ယွင်းချက် အစီရင်ခံစာ <xliff:g id="ID">#%d</xliff:g> ဖမ်းယူထားသည် သို့သော် ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း စောင့်ဆိုင်းနေသည်"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"ချွတ်ယွင်းချက်အစီရင်ခံချက်သို့ အသေးစိတ်များပေါင်းထည့်ရန်"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"ခေတ္တစောင့်ပါ..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"သင်၏ ဘာဂ် အစီရင်ခံစာကို မျှပေးရန် ဘယ်ဘက်သို့ ပွတ်ဆွဲရန်"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"သင့်ချွတ်ယွင်းမှုအစီရင်ခံချက်ကို မျှဝေရန် တို့ပါ"</string> - <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"ချွတ်ယွင်းချက်အစီရင်ခံချက်ကို မျက်နှာပြင်ဓတ်ပုံမှတ်တမ်း မပါဘဲမျှဝေရန် တို့ပါ သို့မဟုတ် မျက်နှာပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း ပြီးဆုံးသည်အထိ စောင့်ပါ"</string> - <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ချွတ်ယွင်းချက်အစီရင်ခံချက်ကို မျက်နှာပြင်ဓတ်ပုံမှတ်တမ်း မပါဘဲမျှဝေရန် တို့ပါ သို့မဟုတ် မျက်နှာပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း ပြီးဆုံးသည်အထိ စောင့်ပါ"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"ချွတ်ယွင်းချက်အစီရင်ခံစာကို ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းမပါဘဲ မျှဝေရန် တို့ပါ သို့မဟုတ် ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း ပြီးဆုံးသည်အထိ စောင့်ပါ"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"ချွတ်ယွင်းချက်အစီရင်ခံစာကို ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းမပါဘဲ မျှဝေရန် တို့ပါ သို့မဟုတ် ဖန်သားပြင်ဓာတ်ပုံမှတ်တမ်းတင်ခြင်း ပြီးဆုံးသည်အထိ စောင့်ပါ"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"အမှားအယွင်း မှတ်တမ်းမှာ ပါရှိသော အချက်အလက်များမှာ ကိုယ်ရေးကိုယ်တာ နဲ့ လုံခြုံရေး အချက်အလက်များပါဝင်သော စနစ်မှ ပြုလုပ်မှု မှတ်တမ်းများ ဖြစ်ပါသည်၊ အမှားအယွင်း မှတ်တမ်းများကို ယုံကြည်ရသော အပလီကေးရှင်းများနဲ့ လူများကိုသာ ပေးဝေပြသမှု လုပ်ပါရန်။"</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"ဤစာတန်းကို နောက်တစ်ခါတွင် ပြရန်"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"ချို့ယွင်းမှု အစီရင်ခံစာများ"</string> diff --git a/packages/Shell/res/values-pt-rBR/strings.xml b/packages/Shell/res/values-pt-rBR/strings.xml index 438c031a0d8f..2306c39ac414 100644 --- a/packages/Shell/res/values-pt-rBR/strings.xml +++ b/packages/Shell/res/values-pt-rBR/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"O relatório do bug <xliff:g id="ID">#%d</xliff:g> está sendo gerado"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Relatório do bug <xliff:g id="ID">#%d</xliff:g> capturado"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Relatório do bug <xliff:g id="ID">#%d</xliff:g> capturado, captura pendente"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Adicionando detalhes ao relatório do bug"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Aguarde…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Deslize para a esquerda para compartilhar seu relatório de bugs"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toque para compartilhar seu relatório do bug"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toque para compartilhar seu relatório de bug sem captura de tela ou aguarde a conclusão"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toque para compartilhar seu relatório de bug sem captura de tela ou aguarde a conclusão"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de bugs contêm dados de diversos arquivos de registro do sistema, inclusive informações pessoais e particulares. Compartilhe relatórios de bugs somente com apps e pessoas nos quais você confia."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensagem da próxima vez"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Relatórios de bugs"</string> diff --git a/packages/Shell/res/values-pt/strings.xml b/packages/Shell/res/values-pt/strings.xml index 438c031a0d8f..2306c39ac414 100644 --- a/packages/Shell/res/values-pt/strings.xml +++ b/packages/Shell/res/values-pt/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"O relatório do bug <xliff:g id="ID">#%d</xliff:g> está sendo gerado"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Relatório do bug <xliff:g id="ID">#%d</xliff:g> capturado"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Relatório do bug <xliff:g id="ID">#%d</xliff:g> capturado, captura pendente"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Adicionando detalhes ao relatório do bug"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Aguarde…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Deslize para a esquerda para compartilhar seu relatório de bugs"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toque para compartilhar seu relatório do bug"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toque para compartilhar seu relatório de bug sem captura de tela ou aguarde a conclusão"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toque para compartilhar seu relatório de bug sem captura de tela ou aguarde a conclusão"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de bugs contêm dados de diversos arquivos de registro do sistema, inclusive informações pessoais e particulares. Compartilhe relatórios de bugs somente com apps e pessoas nos quais você confia."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensagem da próxima vez"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Relatórios de bugs"</string> diff --git a/packages/Shell/res/values-ro/strings.xml b/packages/Shell/res/values-ro/strings.xml index 43366f812080..9529ade5295a 100644 --- a/packages/Shell/res/values-ro/strings.xml +++ b/packages/Shell/res/values-ro/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Raportul de eroare <xliff:g id="ID">#%d</xliff:g> se generează"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Raportul de eroare <xliff:g id="ID">#%d</xliff:g> a fost creat"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Raport eroare <xliff:g id="ID">#%d</xliff:g> creat, captură ecran în așteptare"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Se adaugă detaliile la raportul de eroare"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Așteptați…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Glisați la stânga pentru a trimite raportul de erori"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Atingeți pentru a trimite raportul de eroare"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Atingeți ca să trimiteți raportul de eroare fără captură de ecran sau așteptați finalizarea acesteia"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Atingeți ca să trimiteți raportul de eroare fără captură de ecran sau așteptați finalizarea acesteia"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Rapoartele despre erori conțin date din diferite fișiere de jurnal ale sistemului, inclusiv informații private și personale. Permiteți accesul la rapoartele despre erori numai aplicațiilor și persoanelor în care aveți încredere."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Afișați acest mesaj data viitoare"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapoarte de erori"</string> diff --git a/packages/Shell/res/values-ru/strings.xml b/packages/Shell/res/values-ru/strings.xml index e22ad2e8e0d5..4aafbba425b9 100644 --- a/packages/Shell/res/values-ru/strings.xml +++ b/packages/Shell/res/values-ru/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Оболочка"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Создание отчета об ошибке <xliff:g id="ID">#%d</xliff:g>…"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Отчет об ошибке <xliff:g id="ID">#%d</xliff:g> сохранен"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Отчет об ошибке (<xliff:g id="ID">#%d</xliff:g>) готов, ожидается скриншот"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Добавление данных в отчет об ошибке"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Подождите…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Проведите влево, чтобы отправить отчет"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Нажмите, чтобы отправить отчет об ошибке."</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Нажмите, чтобы отправить отчет об ошибке сразу, или подождите, пока будет сохранен скриншот."</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Нажмите, чтобы отправить отчет об ошибке сразу, или подождите, пока будет сохранен скриншот."</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Отчеты об ошибках содержат данные различных системных журналов и могут включать личную информацию. Рекомендуем открывать к ним доступ только лицам и приложениям, заслуживающим доверие."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Показать это сообщение в следующий раз"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Отчеты об ошибках"</string> diff --git a/packages/Shell/res/values-sl/strings.xml b/packages/Shell/res/values-sl/strings.xml index 9419760f06f1..fdf34468c060 100644 --- a/packages/Shell/res/values-sl/strings.xml +++ b/packages/Shell/res/values-sl/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Lupina"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Poročilo o napaki <xliff:g id="ID">#%d</xliff:g> je v izdelavi"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Poročilo o napaki <xliff:g id="ID">#%d</xliff:g> zajeto"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Poroč. o napakah <xliff:g id="ID">#%d</xliff:g> zajeto, posnetek zaslona nastaja"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodajanje podrobnosti v poročilo o napakah"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Počakajte ..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Povlecite v levo, če želite poslati sporočilo o napaki"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dotaknite se, če želite poročilo o napaki dati v skupno rabo"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dotaknite se za pošiljanje poročila o napakah brez posnetka zaslona ali počakajte, da se ta dokonča"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dotaknite se za pošiljanje poročila o napakah brez posnetka zaslona ali počakajte, da se ta dokonča"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Poročila o napakah vsebujejo podatke iz različnih dnevniških datotek sistema, vključno z osebnimi in zasebnimi podatki. Poročila o napakah delite samo z aplikacijami in ljudmi, ki jim zaupate."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Pokaži to sporočilo naslednjič"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Poročila o napakah"</string> diff --git a/packages/Shell/res/values-sq-rAL/strings.xml b/packages/Shell/res/values-sq-rAL/strings.xml index 206ffda6f773..f43ce9fdab0f 100644 --- a/packages/Shell/res/values-sq-rAL/strings.xml +++ b/packages/Shell/res/values-sq-rAL/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Guaska"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Raporti i defekteve në kod <xliff:g id="ID">#%d</xliff:g> po krijohet"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Raporti i defekteve në kod <xliff:g id="ID">#%d</xliff:g> u regjistrua"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Raporti i defekteve në kod <xliff:g id="ID">#%d</xliff:g> u regjistrua, por pamja e çastit është në pritje"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Po shtohen detajet te raporti i defekteve në kod"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Qëndro në pritje..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Rrëshqit majtas për të ndarë raportin e defektit në kod"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Trokit për të ndarë raportin e defekteve në kod"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Trokit për të ndarë raportin e defekteve në kod pa një pamje çasti ose prit që pamja e çastit të përfundojë"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Trokit për të ndarë raportin e defekteve në kod pa një pamje çasti ose prit që pamja e çastit të përfundojë"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Raportet e gabimeve përmbajnë të dhëna nga skedarë të ndryshëm ditarësh sistemi, përfshi informacione personale dhe private. Shpërndaji publikisht raportet e gabimeve vetëm me aplikacionet dhe personat që iu beson."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tregoje këtë mesazh herën tjetër"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Raportet e gabimeve"</string> diff --git a/packages/Shell/res/values-th/strings.xml b/packages/Shell/res/values-th/strings.xml index ff9a647e61dd..db7f823230c7 100644 --- a/packages/Shell/res/values-th/strings.xml +++ b/packages/Shell/res/values-th/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"กำลังสร้างรายงานข้อบกพร่อง <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"บันทึกรายงานข้อบกพร่อง <xliff:g id="ID">#%d</xliff:g> แล้ว"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"จับภาพรายงานข้อบกพร่อง <xliff:g id="ID">#%d</xliff:g> แล้วแต่ภาพหน้าจอยังไม่เสร็จ"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"กำลังเพิ่มรายละเอียดในรายงานข้อบกพร่อง"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"โปรดรอสักครู่…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"กวาดไปทางซ้ายเพื่อแชร์รายงานข้อบกพร่อง"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"แตะเพื่อแชร์รายงานข้อบกพร่องของคุณ"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"แตะเพื่อแชร์รายงานข้อบกพร่องของคุณโดยไม่มีภาพหน้าจอ หรือรอให้ภาพหน้าจอเสร็จสมบูรณ์"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"แตะเพื่อแชร์รายงานข้อบกพร่องของคุณโดยไม่มีภาพหน้าจอ หรือรอให้ภาพหน้าจอเสร็จสมบูรณ์"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"รายงานข้อบกพร่องมีข้อมูลจากไฟล์บันทึกต่างๆ ของระบบ รวมถึงข้อมูลส่วนตัว แชร์รายงานข้อบกพร่องกับแอปและบุคคลที่คุณไว้ใจเท่านั้น"</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"แสดงข้อความนี้ในครั้งต่อไป"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"รายงานข้อบกพร่อง"</string> diff --git a/packages/Shell/res/values-tl/strings.xml b/packages/Shell/res/values-tl/strings.xml index 9e152d3d1f70..f99a1b8fcb67 100644 --- a/packages/Shell/res/values-tl/strings.xml +++ b/packages/Shell/res/values-tl/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Binubuo na ang ulat ng bug na <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Na-capture ang ulat ng bug na <xliff:g id="ID">#%d</xliff:g>"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Nakunan ang ulat ng bug <xliff:g id="ID">#%d</xliff:g>, nakabinbin ang screenshot"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Pagdaragdag ng mga detalye sa ulat ng bug"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Mangyaring maghintay..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Mag-swipe pakaliwa upang ibahagi ang iyong ulat ng bug"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Mag-tap upang ibahagi ang iyong ulat ng bug"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Mag-tap para ibahagi ang iyong ulat ng bug nang walang screenshot o hintaying matapos ang screenshot"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Mag-tap para ibahagi ang iyong ulat ng bug nang walang screenshot o hintaying matapos ang screenshot"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Naglalaman ang mga ulat ng bug ng data mula sa iba\'t ibang file ng log ng system, kabilang ang personal at pribadong impormasyon. Magbahagi lang ng mga ulat ng bug sa apps at mga tao na pinagkakatiwalaan mo."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Ipakita ang mensaheng ito sa susunod"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Mga ulat sa bug"</string> diff --git a/packages/Shell/res/values-tr/strings.xml b/packages/Shell/res/values-tr/strings.xml index 4c765da922ce..be448afa0fc9 100644 --- a/packages/Shell/res/values-tr/strings.xml +++ b/packages/Shell/res/values-tr/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Kabuk"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Hata raporu (<xliff:g id="ID">#%d</xliff:g>) oluşturuluyor"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Hata raporu (<xliff:g id="ID">#%d</xliff:g>) yakalandı"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"<xliff:g id="ID">#%d</xliff:g> hata raporu yakalandı, ekran görüntüsü bekleniyor"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Hata raporuna ayrıntılar ekleniyor"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Lütfen bekleyin…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Hata raporunuzu paylaşmak için hızlıca sola kaydırın"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Hata raporunuzu paylaşmak için hafifçe dokunun"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Hata raporunu ekran görüntüsüz paylaşmak için dokunun veya bitirmek için ekran görüntüsünü bekleyin"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Hata raporunu ekran görüntüsüz paylaşmak için dokunun veya bitirmek için ekran görüntüsünü bekleyin"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Hata raporları, kişisel ve özel bilgiler dahil olmak üzere sistemin çeşitli günlük dosyalarından veriler içerir. Hata raporlarını sadece güvendiğiniz uygulamalar ve kişilerle paylaşın."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bir dahaki sefere bu iletiyi göster"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Hata raporları"</string> diff --git a/packages/Shell/res/values-ur-rPK/strings.xml b/packages/Shell/res/values-ur-rPK/strings.xml index edc7433cf350..ef6801fefcb1 100644 --- a/packages/Shell/res/values-ur-rPK/strings.xml +++ b/packages/Shell/res/values-ur-rPK/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"شیل"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"بگ رپورٹ <xliff:g id="ID">#%d</xliff:g> تخلیق ہو رہی ہے"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"بگ رپورٹ <xliff:g id="ID">#%d</xliff:g> کیپچر ہو گئی"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"بگ رپورٹ <xliff:g id="ID">#%d</xliff:g> کیپچر ہو گیا مگر اسکرین شاٹ زیر التواء"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"بگ رپورٹ میں تفصیلات شامل کی جا رہی ہیں"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"براہ کرم انتظار کریں…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"اپنی بگ رپورٹ کا اشتراک کرنے کیلئے بائیں سوائپ کریں"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"اپنی بگ رپورٹ کا اشتراک کرنے کیلئے تھپتھپائیں"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"بغیر اسکرین شاٹ کے بگ رپورٹ کا اشتراک کرنے کیلئے تھپتھپائیں یا اسکرین شاٹ کے ختم ہونے کا انتظار کریں"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"بغیر اسکرین شاٹ کے بگ رپورٹ کا اشتراک کرنے کیلئے تھپتھپائیں یا اسکرین شاٹ کے ختم ہونے کا انتظار کریں"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"بَگ رپورٹس میں سسٹم کی مختلف لاگ فائلوں سے ڈیٹا شامل ہوتا ہے، بشمول ذاتی اور نجی معلومات۔ بَگ رپورٹس کا اشتراک صرف اپنے بھروسے مند ایپس اور لوگوں کے ساتھ کریں۔"</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"یہ پیغام اگلی بار دکھائیں"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"بگ رپورٹس"</string> diff --git a/packages/Shell/res/values-uz-rUZ/strings.xml b/packages/Shell/res/values-uz-rUZ/strings.xml index 90d771818483..c1a19480c0df 100644 --- a/packages/Shell/res/values-uz-rUZ/strings.xml +++ b/packages/Shell/res/values-uz-rUZ/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Terminal"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Xatoliklar hisoboti (<xliff:g id="ID">#%d</xliff:g>) tayyorlanmoqda"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Xatoliklar hisoboti (<xliff:g id="ID">#%d</xliff:g>) yozib olindi"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Xatoliklar hisoboti (<xliff:g id="ID">#%d</xliff:g>) tayyor, skrinshot kutilmoqda"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Xatoliklar hisobotiga tafsilotlar qo‘shilmoqda"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Iltimos, kuting…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Xatolik hisobotini yuborish uchun barmog‘ingiz bilan chapga suring"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Xatoliklar hisobotini ulashish uchun bosing"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Xatoliklar hisobotini darhol yuborish uchun bosing yoki skrinshot saqlanguncha kuting"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Xatoliklar hisobotini darhol yuborish uchun bosing yoki skrinshot saqlanguncha kuting"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Xatolik hisobotlari tizimdagi har xil jurnal fayllardagi ma’lumotlarni, shuningdek, shaxsiy hamda maxfiy ma’lumotlarni o‘z ichiga oladi. Xatolik hisobotlarini faqat ishonchli dasturlar va odamlar bilan bo‘lishing."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Ushbu xabar keyingi safar ko‘rsatilsin"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Xatoliklar hisoboti"</string> diff --git a/packages/Shell/res/values-vi/strings.xml b/packages/Shell/res/values-vi/strings.xml index cb8c5b98c7cb..22299916c149 100644 --- a/packages/Shell/res/values-vi/strings.xml +++ b/packages/Shell/res/values-vi/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Báo cáo lỗi <xliff:g id="ID">#%d</xliff:g> đang được tạo"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Đã chụp báo cáo lỗi <xliff:g id="ID">#%d</xliff:g>"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Đã chụp báo cáo lỗi <xliff:g id="ID">#%d</xliff:g>, đang chờ ảnh chụp màn hình"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Đang thêm thông tin chi tiết vào báo cáo lỗi"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Vui lòng đợi…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Vuốt sang trái để chia sẻ báo cáo lỗi của bạn"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Nhấn để chia sẻ báo cáo lỗi của bạn"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Bấm để chia sẻ báo cáo lỗi mà không cần ảnh chụp màn hình hoặc đợi hoàn tất ảnh chụp màn hình"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Bấm để chia sẻ báo cáo lỗi mà không cần ảnh chụp màn hình hoặc đợi hoàn tất ảnh chụp màn hình"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Các báo cáo lỗi chứa dữ liệu từ nhiều tệp nhật ký khác nhau của hệ thống, bao gồm cả thông tin cá nhân và riêng tư. Chỉ chia sẻ báo cáo lỗi với các ứng dụng và những người mà bạn tin tưởng."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Hiển thị thông báo này vào lần tới"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Báo cáo lỗi"</string> diff --git a/packages/Shell/res/values-zh-rCN/strings.xml b/packages/Shell/res/values-zh-rCN/strings.xml index 6e13d75ab5cb..b09a7d0b783b 100644 --- a/packages/Shell/res/values-zh-rCN/strings.xml +++ b/packages/Shell/res/values-zh-rCN/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"正在生成错误报告 <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"已捕获错误报告 <xliff:g id="ID">#%d</xliff:g>"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"已捕获错误报告 <xliff:g id="ID">#%d</xliff:g>,但仍在等待屏幕截图完成"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"正在向错误报告添加详细信息"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"请稍候…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"向左滑动即可分享错误报告"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"点按即可分享您的错误报告"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"点按即可分享不含屏幕截图的错误报告;您也可以等待屏幕截图完成"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"点按即可分享不含屏幕截图的错误报告;您也可以等待屏幕截图完成"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"错误报告包含的数据来自于系统的各个日志文件,其中包含个人信息和隐私信息。请务必只与您信任的应用和用户分享错误报告。"</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次再显示这条讯息"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"错误报告"</string> diff --git a/packages/Shell/res/values-zh-rHK/strings.xml b/packages/Shell/res/values-zh-rHK/strings.xml index 7ade56bdd949..384eee70caea 100644 --- a/packages/Shell/res/values-zh-rHK/strings.xml +++ b/packages/Shell/res/values-zh-rHK/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"命令介面"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"正在產生錯誤報告 <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"已擷取錯誤報告 <xliff:g id="ID">#%d</xliff:g>"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"已擷取錯誤報告 <xliff:g id="ID">#%d</xliff:g>,但螢幕畫面仍未擷取完成"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"正在新增錯誤報告詳細資訊"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"請稍候…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"向左滑動即可分享錯誤報告"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"輕按即可分享錯誤報告"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"輕按以分享錯誤報告 (不包含螢幕擷圖),或等待螢幕畫面擷取完成"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"輕按以分享錯誤報告 (不包含螢幕擷圖),或等待螢幕畫面擷取完成"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"錯誤報告中有來自系統各個記錄檔案的資料,包括個人和私人資料。請只與您信任的應用程式和使用者分享錯誤報告。"</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次再顯示這則訊息"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"錯誤報告"</string> diff --git a/packages/Shell/res/values-zh-rTW/strings.xml b/packages/Shell/res/values-zh-rTW/strings.xml index 8695d5f3f57b..2702bad05e87 100644 --- a/packages/Shell/res/values-zh-rTW/strings.xml +++ b/packages/Shell/res/values-zh-rTW/strings.xml @@ -19,16 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"殼層"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"正在產生錯誤報告 <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"已擷取錯誤報告 <xliff:g id="ID">#%d</xliff:g>"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_title (5460883450679439591) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"錯誤報告 <xliff:g id="ID">#%d</xliff:g> 擷取成功,但螢幕畫面尚未擷取完畢"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"正在新增錯誤報告詳細資訊"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"請稍候…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"向左滑動即可分享錯誤報告"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"輕按即可分享錯誤報告"</string> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> - <!-- no translation found for bugreport_finished_pending_screenshot_text (1474435374470177193) --> - <skip /> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"輕觸即可分享無螢幕擷圖的錯誤報告;您也可以等候螢幕畫面擷取完畢"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"輕觸即可分享無螢幕擷圖的錯誤報告;您也可以等候螢幕畫面擷取完畢"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"錯誤報告的資料來自系統各個紀錄檔,包括個人和私密資訊。請務必只與您信任的應用程式和使用者分享錯誤報告。"</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"下次仍顯示這則訊息"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"錯誤報告"</string> diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java index d212d53a6c88..10c541600d87 100644 --- a/packages/Shell/src/com/android/shell/BugreportProgressService.java +++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java @@ -620,7 +620,11 @@ public class BugreportProgressService extends Service { * upon receiving a {@link #INTENT_BUGREPORT_STARTED}. */ private void takeScreenshot(int id, boolean delayed) { - MetricsLogger.action(this, MetricsEvent.ACTION_BUGREPORT_NOTIFICATION_ACTION_SCREENSHOT); + if (delayed) { + // Only logs screenshots requested from the notification action. + MetricsLogger.action(this, + MetricsEvent.ACTION_BUGREPORT_NOTIFICATION_ACTION_SCREENSHOT); + } if (getInfo(id) == null) { // Most likely am killed Shell before user tapped the notification. Since system might // be too busy anwyays, it's better to ignore the notification and switch back to the diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 637551c68a74..334035cb5dff 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -187,6 +187,15 @@ android:process=":screenshot" android:exported="false" /> + <!-- Called from PhoneWindowManager --> + <receiver android:name=".screenshot.ScreenshotServiceErrorReceiver" + android:process=":screenshot" + android:exported="false"> + <intent-filter> + <action android:name="com.android.systemui.screenshot.SHOW_ERROR" /> + </intent-filter> + </receiver> + <service android:name=".LoadAverageService" android:exported="true" /> diff --git a/packages/SystemUI/res/layout/qs_customize_panel.xml b/packages/SystemUI/res/layout/qs_customize_panel.xml index 0491ea08525d..7af247ef1d2f 100644 --- a/packages/SystemUI/res/layout/qs_customize_panel.xml +++ b/packages/SystemUI/res/layout/qs_customize_panel.xml @@ -24,26 +24,4 @@ android:background="@drawable/qs_customizer_background" android:gravity="center_horizontal"> - <Toolbar - android:id="@*android:id/action_bar" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_marginTop="28dp" - android:navigationContentDescription="@*android:string/action_bar_up_description" - style="?android:attr/toolbarStyle" /> - - <android.support.v7.widget.RecyclerView - android:id="@android:id/list" - android:layout_width="@dimen/notification_panel_width" - android:layout_height="0dp" - android:layout_weight="1" - android:scrollIndicators="top" - android:scrollbars="vertical" /> - - <View - android:layout_width="match_parent" - android:layout_height="@dimen/navigation_bar_size" - android:layout_gravity="bottom" - android:background="#ff000000" /> - </com.android.systemui.qs.customize.QSCustomizer> diff --git a/packages/SystemUI/res/layout/qs_customize_panel_content.xml b/packages/SystemUI/res/layout/qs_customize_panel_content.xml new file mode 100644 index 000000000000..75f8fa4ff45a --- /dev/null +++ b/packages/SystemUI/res/layout/qs_customize_panel_content.xml @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<merge xmlns:android="http://schemas.android.com/apk/res/android"> + + <Toolbar + android:id="@*android:id/action_bar" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="28dp" + android:navigationContentDescription="@*android:string/action_bar_up_description" + style="?android:attr/toolbarStyle" /> + + <android.support.v7.widget.RecyclerView + android:id="@android:id/list" + android:layout_width="@dimen/notification_panel_width" + android:layout_height="0dp" + android:layout_weight="1" + android:scrollIndicators="top" + android:scrollbars="vertical" /> + + <View + android:layout_width="match_parent" + android:layout_height="@dimen/navigation_bar_size" + android:layout_gravity="bottom" + android:background="#ff000000" /> +</merge> diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml index 70247eec090e..7d85ef67c059 100644 --- a/packages/SystemUI/res/values-af/strings.xml +++ b/packages/SystemUI/res/values-af/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Skermkiekie geneem."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Raak om jou skermkiekie te sien."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Kon nie skermkiekie neem nie."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Kon nie skermkiekie stoor nie."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Kan weens beperkte bergingspasie nie skermkiekie stoor nie."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Die program of jou organisasie laat nie toe dat skermkiekies geneem word nie."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB-lêeroordrag-opsies"</string> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 226d7f505424..e870ea7315c0 100644 --- a/packages/SystemUI/res/values-am/strings.xml +++ b/packages/SystemUI/res/values-am/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"ቅጽበታዊ ገጽ እይታ ተቀርጿል"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"የእርስዎን ቅጽበታዊ ገጽ እይታ ለማየት ይንኩ"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"ቅጽበታዊ ገጽ እይታ መቅረጽ አልተቻለም::"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"ቅጽበታዊ ገጽ ዕይታን በማስቀመጥ ጊዜ ችግር አጋጥሟል።"</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ባለው የተገደበ የማከማቻ ቦታ ምክንያት ቅጽበታዊ ገጽ ዕይታን ማስቀመጥ አይችልም።"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ቅጽበታዊ ገጽ እይታዎችን ማንሳት በመተግበሪያው ወይም በእርስዎ ድርጅት አይፈቀድም።"</string> <string name="usb_preference_title" msgid="6551050377388882787">"የUSB ፋይል ሰደዳ አማራጮች"</string> diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml index a6b9660bab9e..544ae0739a1e 100644 --- a/packages/SystemUI/res/values-am/strings_tv.xml +++ b/packages/SystemUI/res/values-am/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"PIPን ዝጋ"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"ሙሉ ማያ ገጽ"</string> <string name="pip_play" msgid="674145557658227044">"አጫውት"</string> <string name="pip_pause" msgid="8412075640017218862">"ለአፍታ አቁም"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"PIPን ለመቆጣጠር "<b>"መነሻ"</b>"ን ይያዙ"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIPን ለመቆጣጠር የመነሻ\nአዝራሩን ይጫኑ እና ይያዙ"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"ገባኝ"</string> </resources> diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml index 5dc3b01fe7d6..100bc632de04 100644 --- a/packages/SystemUI/res/values-ar/strings.xml +++ b/packages/SystemUI/res/values-ar/strings.xml @@ -77,6 +77,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"تم التقاط لقطة الشاشة."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"المس لعرض لقطة الشاشة."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"تعذر التقاط لقطة الشاشة."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"حدثت مشكلة أثناء حفظ لقطة الشاشة."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"يتعذر حفظ لقطة الشاشة نظرًا لأن مساحة التخزين المتاحة محدودة."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"غير مسموح بالتقاط لقطات شاشة نظرًا لإذن يتعلق بالتطبيق أو بالمؤسسة."</string> <string name="usb_preference_title" msgid="6551050377388882787">"خيارات نقل الملفات عبر USB"</string> diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml index 21bdc4590bf1..7763cb3588c6 100644 --- a/packages/SystemUI/res/values-az-rAZ/strings.xml +++ b/packages/SystemUI/res/values-az-rAZ/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Skrinşot çəkildi."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Skrinşotunuza baxmaq üçün toxunun"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Skrinşot götürülə bilinmədi."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Skrinşot yadda saxlanarkən problem baş verdi."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Yaddaş ehtiyatının az olması səbəbindən skrinşotu yadda saxlamaq olmur."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Tətbiq və ya təşkilatınız tərəfindən skrinşot çəkməyə icazə verilmir."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB fayl transferi seçimləri"</string> diff --git a/packages/SystemUI/res/values-az-rAZ/strings_tv.xml b/packages/SystemUI/res/values-az-rAZ/strings_tv.xml index e4e35ab21f71..6751bc9c16a6 100644 --- a/packages/SystemUI/res/values-az-rAZ/strings_tv.xml +++ b/packages/SystemUI/res/values-az-rAZ/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"PIP bağlayın"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Tam ekran"</string> <string name="pip_play" msgid="674145557658227044">"Göstərin"</string> <string name="pip_pause" msgid="8412075640017218862">"Fasilə verin"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"PIP idarı etmək üçün "<b>"Əsas səhifəni"</b>" tutub saxlayın"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP idarə etmək üçün Əsas səhifə\n düyməsini basıb saxlayın"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Anladım"</string> </resources> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml index 969b3783e02f..1198950cb714 100644 --- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml +++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml @@ -74,6 +74,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Snimak ekrana je napravljen."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Dodirnite da biste videli snimak ekrana."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Nije moguće napraviti snimak ekrana."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Čuvanje snimka ekrana nije uspelo zbog ograničenog memorijskog prostora."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikacija ili organizacija ne dozvoljavaju pravljenje snimaka ekrana."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prenosa datoteka"</string> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 9ff5f951d596..876af0af7d23 100644 --- a/packages/SystemUI/res/values-bg/strings.xml +++ b/packages/SystemUI/res/values-bg/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Екранната снимка е заснета."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Докоснете, за да видите екранната си снимка."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Екранната снимка не можа да бъде заснета."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"При запазването на екранната снимка възникна проблем."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Екранната снимка не може да се запази поради ограничено място в хранилището."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Правенето на екранни снимки не е разрешено от приложението или организацията ви."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Опции за пренос на файлове чрез USB"</string> diff --git a/packages/SystemUI/res/values-bg/strings_tv.xml b/packages/SystemUI/res/values-bg/strings_tv.xml index c5fc5b1c95bc..38c10ab6b828 100644 --- a/packages/SystemUI/res/values-bg/strings_tv.xml +++ b/packages/SystemUI/res/values-bg/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Затваряне на PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Цял екран"</string> <string name="pip_play" msgid="674145557658227044">"Пускане"</string> <string name="pip_pause" msgid="8412075640017218862">"Пауза"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Контр. на PIP: Задр. "<b>"HOME"</b></string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"За контролиране на PIP\nнатиснете и задръжте HOME"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Разбрах"</string> </resources> diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml index 66537da17104..eaf450fa3d8d 100644 --- a/packages/SystemUI/res/values-bn-rBD/strings.xml +++ b/packages/SystemUI/res/values-bn-rBD/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"স্ক্রীনশট নেওয়া হযেছে৷"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"আপনার স্ক্রীনশট দেখতে স্পর্শ করুন৷"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"স্ক্রীনশট নেওয়া যায়নি৷"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"স্ক্রীনশট সংরক্ষণের সময়ে সমস্যা হয়েছে৷"</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"সঞ্চয়স্থান সীমিত থাকায় স্ক্রীনশটটি সংরক্ষণ করা যাবে না৷"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"অ্যাপ্লিকেশান বা আপনার প্রতিষ্ঠান স্ক্রীনশটগুলি নেওয়া অনুমতি দেয়নি৷"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ফাইল স্থানান্তরের বিকল্পগুলি"</string> diff --git a/packages/SystemUI/res/values-bs-rBA/strings.xml b/packages/SystemUI/res/values-bs-rBA/strings.xml index 91d9dead2c5f..3befd442d719 100644 --- a/packages/SystemUI/res/values-bs-rBA/strings.xml +++ b/packages/SystemUI/res/values-bs-rBA/strings.xml @@ -74,6 +74,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekran snimljen."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Dodirnite za prikaz snimka ekrana."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Došlo je do greške prilikom snimanja ekrana."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Snimak ekrana se ne može sačuvati zbog manjka prostora za pohranu."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikacija ili vaša organizacija ne dopuštaju pravljenje snimaka ekrana."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prijenosa fajlova"</string> diff --git a/packages/SystemUI/res/values-bs-rBA/strings_tv.xml b/packages/SystemUI/res/values-bs-rBA/strings_tv.xml new file mode 100644 index 000000000000..17193189525d --- /dev/null +++ b/packages/SystemUI/res/values-bs-rBA/strings_tv.xml @@ -0,0 +1,32 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +/** + * Copyright (c) 2016, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="pip_close" msgid="3480680679023423574">"Zatvori PIP"</string> + <!-- no translation found for pip_fullscreen (8604643018538487816) --> + <skip /> + <!-- no translation found for pip_play (674145557658227044) --> + <skip /> + <!-- no translation found for pip_pause (8412075640017218862) --> + <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Za kontr. PIP držite "<b>"HOME"</b></string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Za kontrolu PIP \n držite dugme POČETAK"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Jasno mi je"</string> +</resources> diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml index a75879834197..42596fe2f927 100644 --- a/packages/SystemUI/res/values-ca/strings.xml +++ b/packages/SystemUI/res/values-ca/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"S\'ha fet una captura de pantalla."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Toca per veure la captura de pantalla."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"No s\'ha pogut fer una captura de pantalla."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"La captura de pantalla no es pot desar perquè no hi ha prou espai d\'emmagatzematge."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"L\'aplicació o l\'organització no permeten fer captures de pantalla."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opcions transf. fitxers USB"</string> diff --git a/packages/SystemUI/res/values-ca/strings_tv.xml b/packages/SystemUI/res/values-ca/strings_tv.xml index c5779ae6807e..1aed2b4af948 100644 --- a/packages/SystemUI/res/values-ca/strings_tv.xml +++ b/packages/SystemUI/res/values-ca/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Tanca PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string> <string name="pip_play" msgid="674145557658227044">"Reprodueix"</string> <string name="pip_pause" msgid="8412075640017218862">"Posa en pausa"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Prem "<b>"INICI"</b>" per contr. PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Mantén premut botó INICI\n per controlar PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"D\'acord"</string> </resources> diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml index 86353a6a679a..386767363cb1 100644 --- a/packages/SystemUI/res/values-cs/strings.xml +++ b/packages/SystemUI/res/values-cs/strings.xml @@ -75,6 +75,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Snímek obrazovky Snímek obrazovky pořízen."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Snímek obrazovky zobrazíte dotykem."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Snímek obrazovky se nepodařilo zachytit."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Snímek obrazovky nelze pořídit kvůli nedostatku místa v úložišti."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikace nebo organizace zakazuje pořizování snímků obrazovky."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Možnosti přenosu souborů pomocí rozhraní USB"</string> diff --git a/packages/SystemUI/res/values-cs/strings_tv.xml b/packages/SystemUI/res/values-cs/strings_tv.xml index 89640cdab1cf..2480c3736443 100644 --- a/packages/SystemUI/res/values-cs/strings_tv.xml +++ b/packages/SystemUI/res/values-cs/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Ukončit PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Celá obrazovka"</string> <string name="pip_play" msgid="674145557658227044">"Přehrát"</string> <string name="pip_pause" msgid="8412075640017218862">"Pozastavit"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Funkci PIP lze ovládat podržením tlačítka "<b>"PLOCHA"</b></string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Funkci PIP lze ovládat\npodržením tlačítka PLOCHA"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Rozumím"</string> </resources> diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml index 55fefc236d46..0356a18025fe 100644 --- a/packages/SystemUI/res/values-da/strings.xml +++ b/packages/SystemUI/res/values-da/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Skærmbilledet er gemt."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Tryk for at se dit skærmbillede."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Skærmbilledet kunne ikke tages."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Skærmbilledet kan ikke gemmes pga. begrænset lagerplads."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Appen eller din organisation tillader ikke, at du tager skærmbilleder."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Muligheder for USB-filoverførsel"</string> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index cb8e0fd0feaa..7e7b2acf635a 100644 --- a/packages/SystemUI/res/values-de/strings.xml +++ b/packages/SystemUI/res/values-de/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot aufgenommen"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Zum Ansehen berühren"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Screenshot konnte nicht aufgenommen werden."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Speichern des Screenshots aufgrund von zu wenig Speicher nicht möglich."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Die App oder Ihr Unternehmen lässt das Erstellen von Screenshots nicht zu."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB-Dateiübertragungsoptionen"</string> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index b1df6154f434..943c67d248fe 100644 --- a/packages/SystemUI/res/values-el/strings.xml +++ b/packages/SystemUI/res/values-el/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Λήφθηκε το στιγμιότυπο οθόνης ."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Αγγίξτε για να δείτε το στιγμιότυπο οθόνης σας"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Αδύνατη η αποθήκευση του στιγμιότυπου οθόνης."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Παρουσιάστηκε πρόβλημα κατά την αποθήκευση του στιγμιότυπου οθόνης."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Δεν είναι δυνατή η αποθήκευση του στιγμιότυπου οθόνης λόγω περιορισμένου χώρου αποθήκευσης."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Η λήψη στιγμιοτύπων οθόνης δεν επιτρέπεται από την εφαρμογή ή από τον οργανισμό σας."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Επιλογές μεταφοράς αρχείων μέσω USB"</string> diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index 72c71a876cca..6367ed9900d7 100644 --- a/packages/SystemUI/res/values-en-rAU/strings.xml +++ b/packages/SystemUI/res/values-en-rAU/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot captured."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Touch to view your screenshot."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Couldn\'t capture screenshot."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Problem encountered while saving screenshot."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Can\'t save screenshot due to limited storage space."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Taking screenshots is not allowed by the app or your organisation."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string> @@ -220,10 +221,8 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Work mode on."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Work mode turned off."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string> - <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) --> - <skip /> - <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) --> - <skip /> + <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver turned off."</string> + <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver turned on."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G data is paused"</string> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index 72c71a876cca..6367ed9900d7 100644 --- a/packages/SystemUI/res/values-en-rGB/strings.xml +++ b/packages/SystemUI/res/values-en-rGB/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot captured."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Touch to view your screenshot."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Couldn\'t capture screenshot."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Problem encountered while saving screenshot."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Can\'t save screenshot due to limited storage space."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Taking screenshots is not allowed by the app or your organisation."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string> @@ -220,10 +221,8 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Work mode on."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Work mode turned off."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string> - <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) --> - <skip /> - <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) --> - <skip /> + <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver turned off."</string> + <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver turned on."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G data is paused"</string> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index 72c71a876cca..6367ed9900d7 100644 --- a/packages/SystemUI/res/values-en-rIN/strings.xml +++ b/packages/SystemUI/res/values-en-rIN/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot captured."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Touch to view your screenshot."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Couldn\'t capture screenshot."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Problem encountered while saving screenshot."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Can\'t save screenshot due to limited storage space."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Taking screenshots is not allowed by the app or your organisation."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB file transfer options"</string> @@ -220,10 +221,8 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Work mode on."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Work mode turned off."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work mode turned on."</string> - <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) --> - <skip /> - <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) --> - <skip /> + <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Data Saver turned off."</string> + <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Data Saver turned on."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Display brightness"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G data is paused"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G data is paused"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 34e5a7eb2a0c..e60fd2e47c39 100644 --- a/packages/SystemUI/res/values-es-rUS/strings.xml +++ b/packages/SystemUI/res/values-es-rUS/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Se guardó la captura de pantalla."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Toca para ver tu captura de pantalla."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"No se pudo guardar la captura de pantalla."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"No se puede guardar la captura de pantalla debido al almacenamiento limitado."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"La app o tu organización no permiten las capturas de pantalla."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opciones de transferencia de archivos por USB"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings_tv.xml b/packages/SystemUI/res/values-es-rUS/strings_tv.xml index 16d9f364dc8d..1df219d68aa0 100644 --- a/packages/SystemUI/res/values-es-rUS/strings_tv.xml +++ b/packages/SystemUI/res/values-es-rUS/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Cerrar PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Pantalla completa"</string> <string name="pip_play" msgid="674145557658227044">"Reproducir"</string> <string name="pip_pause" msgid="8412075640017218862">"Pausar"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Mantén presionado "<b>"INICIO"</b>" para controlar PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Mantén presionado botón\nINICIO para controlar PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Entendido"</string> </resources> diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml index 2698ffc45774..e3870197f520 100644 --- a/packages/SystemUI/res/values-es/strings.xml +++ b/packages/SystemUI/res/values-es/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura guardada"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Toca para ver la captura de pantalla"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"No se ha podido guardar la captura de pantalla."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"No se puede guardar la captura de pantalla porque no hay espacio de almacenamiento suficiente."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"La aplicación o tu organización no permiten que se realicen capturas de pantalla."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opciones de transferencia de archivos por USB"</string> diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml index 42d449aa03ac..7e687576e3c3 100644 --- a/packages/SystemUI/res/values-et-rEE/strings.xml +++ b/packages/SystemUI/res/values-et-rEE/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekraanipilt on jäädvustatud."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Puudutage kuvatõmmise vaatamiseks."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Kuvatõmmist ei saanud jäädvustada."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Piiratud salvestusruumi tõttu ei saa ekraanipilti salvestada."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Rakendus või teie organisatsioon ei luba ekraanipilte jäädvustada."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB-failiedastuse valikud"</string> diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml index 67f13cc1ea92..6a358d425bcb 100644 --- a/packages/SystemUI/res/values-eu-rES/strings.xml +++ b/packages/SystemUI/res/values-eu-rES/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Pantaila-argazkia atera da."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Pantaila-argazkia ikusteko, ukitu ezazu."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Ezin izan da pantaila-argazkia atera."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Ezin da atera pantaila-argazkia ez delako tokirik geratzen."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikazioak edo erakundeak ez du onartzen pantaila-argazkiak ateratzea."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB fitxategiak transferitzeko aukerak"</string> diff --git a/packages/SystemUI/res/values-eu-rES/strings_tv.xml b/packages/SystemUI/res/values-eu-rES/strings_tv.xml index e6bbd32ef8c5..80feff6b5f01 100644 --- a/packages/SystemUI/res/values-eu-rES/strings_tv.xml +++ b/packages/SystemUI/res/values-eu-rES/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Itxi PIPa"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Pantaila osoa"</string> <string name="pip_play" msgid="674145557658227044">"Erreproduzitu"</string> <string name="pip_pause" msgid="8412075640017218862">"Pausatu"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109"><b>"HASIERA"</b>" PIP kontrolatzeko"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Eduki sakatuta HASIERA\nPIPa kontrolatzeko"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Ados"</string> </resources> diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml index 13c9132e2506..2477a12698de 100644 --- a/packages/SystemUI/res/values-fa/strings.xml +++ b/packages/SystemUI/res/values-fa/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"عکس صفحهنمایش گرفته شد."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"برای مشاهده عکس صفحهنمایشتان، لمس کنید."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"عکس صفحهنمایش گرفته نشد."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"به دلیل محدود بودن فضای ذخیرهسازی نمیتوانید عکس صفحهنمایش را ذخیره کنید."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"این برنامه یا سازمان شما اجازه نمیدهند عکس صفحهنمایش بگیرید."</string> <string name="usb_preference_title" msgid="6551050377388882787">"گزینههای انتقال فایل USB"</string> @@ -510,9 +512,9 @@ <string name="headset" msgid="4534219457597457353">"هدست"</string> <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"هدفون وصل شد"</string> <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"هدست وصل شد"</string> - <string name="data_saver" msgid="5037565123367048522">"صرفهجویی در مصرف داده"</string> - <string name="accessibility_data_saver_on" msgid="8454111686783887148">"صرفهجویی در مصرف داده روشن است"</string> - <string name="accessibility_data_saver_off" msgid="8841582529453005337">"صرفهجویی در مصرف داده خاموش است"</string> + <string name="data_saver" msgid="5037565123367048522">"صرفهجویی داده"</string> + <string name="accessibility_data_saver_on" msgid="8454111686783887148">"صرفهجویی داده روشن است"</string> + <string name="accessibility_data_saver_off" msgid="8841582529453005337">"صرفهجویی داده خاموش است"</string> <string name="switch_bar_on" msgid="1142437840752794229">"روشن"</string> <string name="switch_bar_off" msgid="8803270596930432874">"خاموش"</string> <string name="nav_bar" msgid="1993221402773877607">"نوار پیمایش"</string> diff --git a/packages/SystemUI/res/values-fa/strings_tv.xml b/packages/SystemUI/res/values-fa/strings_tv.xml index 6a62f1251fe8..5130b5085825 100644 --- a/packages/SystemUI/res/values-fa/strings_tv.xml +++ b/packages/SystemUI/res/values-fa/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"بستن PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"تمام صفحه"</string> <string name="pip_play" msgid="674145557658227044">"پخش"</string> <string name="pip_pause" msgid="8412075640017218862">"مکث"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"کنترل PIP با نگهداشتن "<b>"HOME"</b></string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"برای کنترل PIP دکمه صفحه\nاصلی را فشار دهید و نگهدارید"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"متوجه شدم"</string> </resources> diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml index e5ddaad90763..6199536cc3c9 100644 --- a/packages/SystemUI/res/values-fi/strings.xml +++ b/packages/SystemUI/res/values-fi/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Kuvakaappaus tallennettu"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Katso kuvakaappaus koskettamalla."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Kuvakaappausta ei voitu tallentaa"</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Kuvakaappauksen tallentaminen epäonnistui, sillä tallennustilaa ei ole riittävästi."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Sovellus tai organisaatiosi ei salli kuvakaappauksien tallentamista."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB-tiedostonsiirtoasetukset"</string> diff --git a/packages/SystemUI/res/values-fi/strings_tv.xml b/packages/SystemUI/res/values-fi/strings_tv.xml index c19894f74f26..a42c23139ae1 100644 --- a/packages/SystemUI/res/values-fi/strings_tv.xml +++ b/packages/SystemUI/res/values-fi/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Sulje PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Koko näyttö"</string> <string name="pip_play" msgid="674145557658227044">"Toista"</string> <string name="pip_pause" msgid="8412075640017218862">"Keskeytä"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"PIP: paina pitkään "<b>"aloituspain"</b>"."</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Hallinnoi PIP:tä: paina\naloitusnäyttöpainiketta pitkään."</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Selvä"</string> </resources> diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml index 8ad463b674a1..6ed42edfd3aa 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Capture d\'écran réussie"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Appuyez pour afficher votre capture d\'écran."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Impossible de réaliser une capture d\'écran"</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Impossible d\'enregistrer la saisie d\'écran, car l\'espace de stockage est limité."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"L\'application ou votre organisation n\'autorise pas les saisies d\'écran."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Options transfert fichiers USB"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml index 9165632e69d0..29e94c6d2b0d 100644 --- a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml +++ b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Fermer mode IDI"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Plein écran"</string> <string name="pip_play" msgid="674145557658227044">"Lecture"</string> <string name="pip_pause" msgid="8412075640017218862">"Interrompre"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Maint. enf. "<b>"ACC."</b>" pr gér. mode IDI"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Maint. enf. \nACCUEIL pr gér. mode IDI"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string> </resources> diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml index b520a883f76c..c08958d5624d 100644 --- a/packages/SystemUI/res/values-fr/strings.xml +++ b/packages/SystemUI/res/values-fr/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Capture d\'écran réussie"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Appuyez pour afficher votre capture d\'écran."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Impossible de réaliser une capture d\'écran"</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Impossible d\'enregistrer la capture d\'écran, car l\'espace de stockage est limité."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Les captures d\'écran ne sont pas autorisées par l\'application ou par votre organisation."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Options transfert fichiers USB"</string> diff --git a/packages/SystemUI/res/values-fr/strings_tv.xml b/packages/SystemUI/res/values-fr/strings_tv.xml index bc4bd22cc97b..8504a8ea3bab 100644 --- a/packages/SystemUI/res/values-fr/strings_tv.xml +++ b/packages/SystemUI/res/values-fr/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Fermer mode PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Plein écran"</string> <string name="pip_play" msgid="674145557658227044">"Lire"</string> <string name="pip_pause" msgid="8412075640017218862">"Suspendre"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Appui long "<b>"ACCUEIL"</b>" pour contrôler PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Appui long bouton ACCUEIL\npour contrôler PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string> </resources> diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml index 1dc47d5aa4e4..7cb3cb1bdfe0 100644 --- a/packages/SystemUI/res/values-gl-rES/strings.xml +++ b/packages/SystemUI/res/values-gl-rES/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura de pantalla gardada."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Toca para ver a captura de pantalla."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Non se puido facer a captura de pantalla."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Non se pode gardar a captura de pantalla porque o espazo de almacenamento é limitado."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"A aplicación ou a túa organización non permite realizar capturas de pantalla."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opcións de transferencia USB"</string> diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml index 57a95cd30c5d..a8394a2e25ee 100644 --- a/packages/SystemUI/res/values-gu-rIN/strings.xml +++ b/packages/SystemUI/res/values-gu-rIN/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"સ્ક્રીનશોટ કેપ્ચર કર્યો."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"તમારો સ્ક્રીનશોટ જોવા માટે ટચ કરો."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"સ્ક્રીનશોટ કેપ્ચર કરી શકાયો નથી."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"સ્ક્રીનશૉટ સાચવવામાં સમયા આવી."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"મર્યાદિત સંગ્રહ સ્થાનને કારણે સ્ક્રીનશોટ સાચવી શકાતો નથી."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ઍપ્લિકેશન કે તમારી સંસ્થા દ્વારા સ્ક્રીનશોટ્સ લેવાની મંજૂરી નથી."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ફાઇલ ટ્રાન્સફર વિકલ્પો"</string> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 0c3cb482f15e..7618c021ab56 100644 --- a/packages/SystemUI/res/values-hi/strings.xml +++ b/packages/SystemUI/res/values-hi/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"स्क्रीनशॉट कैप्चर किया गया."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"अपना स्क्रीनशॉट देखने के लिए स्पर्श करें."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"स्क्रीनशॉट को कैप्चर नहीं किया जा सका."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"सीमित मेमोरी स्थान के कारण स्क्रीनशॉट सहेजा नहीं जा सकता."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"आपके ऐप्लिकेशन या आपके संगठन द्वारा स्क्रीनशॉट लेने की अनुमति नहीं है."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB फ़ाइल स्थानांतरण विकल्प"</string> diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index 81f10a2ed995..715f667ecd83 100644 --- a/packages/SystemUI/res/values-hr/strings.xml +++ b/packages/SystemUI/res/values-hr/strings.xml @@ -74,6 +74,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Zaslon je snimljen."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Dodirnite za prikaz snimke zaslona."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Nije bilo moguće snimiti zaslon."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Prilikom spremanja snimke zaslona pojavio se problem."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Zaslon nije snimljen zbog ograničenog prostora za pohranu."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Snimanje zaslona ne dopušta aplikacija ili vaša organizacija."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opcije USB prijenosa datoteka"</string> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index ccf582b44d68..280cdb6248f6 100644 --- a/packages/SystemUI/res/values-hu/strings.xml +++ b/packages/SystemUI/res/values-hu/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Képernyőkép rögzítve."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Megérintésével megtekintheti a képernyőképet."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Nem sikerült rögzíteni a képernyőképet."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Hiba történt a képernyőkép mentése során."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Nem menthet képernyőképet, mert kevés a tárhely."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Az alkalmazás vagy szervezete nem engedélyezi képernyőképek készítését."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB-fájlátvitel beállításai"</string> diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml index e60ce28d20f6..bf9f80d38053 100644 --- a/packages/SystemUI/res/values-hy-rAM/strings.xml +++ b/packages/SystemUI/res/values-hy-rAM/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Էկրանի հանույթը լուսանկարվել է:"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Հպեք ձեր էկրանի հանույթը տեսնելու համար:"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Չհաջողվեց լուսանկարել էկրանի հանույթը:"</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Չհաջողվեց պահել էկրանի պատկերը սահմանափակ հիշողության պատճառով:"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Այս հավելվածը կամ ձեր կազմակերպությունը չի թույլատրում Էկրանի պատկերի ստացումը:"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ֆայլերի փոխանցման ընտրանքներ"</string> diff --git a/packages/SystemUI/res/values-hy-rAM/strings_tv.xml b/packages/SystemUI/res/values-hy-rAM/strings_tv.xml index 2eed586e62f7..0ddb715f7a0b 100644 --- a/packages/SystemUI/res/values-hy-rAM/strings_tv.xml +++ b/packages/SystemUI/res/values-hy-rAM/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Փակել PIP-ն"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Լիէկրան"</string> <string name="pip_play" msgid="674145557658227044">"Նվագարկել"</string> <string name="pip_pause" msgid="8412075640017218862">"Դադարեցնել"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"PIP-ն կառավարելու համար սեղմած պահեք "<b>"HOME"</b>" կոճակը"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP-ն կառավարելու համար սեղմեք և պահեք HOME\n կոճակը"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Պարզ է"</string> </resources> diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml index 9eb133116b35..77236634c139 100644 --- a/packages/SystemUI/res/values-in/strings.xml +++ b/packages/SystemUI/res/values-in/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Tangkapan layar diambil."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Sentuh untuk melihat tangkapan layar Anda."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Tidak dapat mengambil tangkapan layar."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Terjadi masalah saat menyimpan tangkapan layar."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Tidak dapat menyimpan tangkapan layar karena ruang penyimpanan terbatas."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Mengambil tangkapan layar tidak diizinkan oleh aplikasi atau organisasi."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opsi transfer file USB"</string> @@ -220,10 +221,8 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Mode kerja aktif."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Mode kerja dinonaktifkan."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Mode kerja diaktifkan."</string> - <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) --> - <skip /> - <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) --> - <skip /> + <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Penghemat Data nonaktif."</string> + <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Penghemat Data diaktifkan."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Kecerahan tampilan"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data 2G-3G dijeda"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Data 4G dijeda"</string> diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml index 19325958db02..6b4f1910ae36 100644 --- a/packages/SystemUI/res/values-is-rIS/strings.xml +++ b/packages/SystemUI/res/values-is-rIS/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Skjámynd var tekin."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Snertu til að skoða skjámyndina."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Ekki tókst að taka skjámynd."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Ekki tókst að vista skjámynd vegna takmarkaðs geymslupláss."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Forritið eða fyrirtækið þitt leyfir ekki að teknar séu skjámyndir."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Valkostir USB-skráaflutnings"</string> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index 34faece8a85e..6fc814a5f46d 100644 --- a/packages/SystemUI/res/values-it/strings.xml +++ b/packages/SystemUI/res/values-it/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot acquisito."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Tocca per visualizzare il tuo screenshot."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Impossibile acquisire lo screenshot."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Impossibile salvare lo screenshot a causa dello spazio di archiviazione limitato."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"L\'acquisizione di screenshot non è consentita dall\'app o dall\'organizzazione."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opzioni trasferimento file USB"</string> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index 9beed4fc7d6b..2eda0e44f11a 100644 --- a/packages/SystemUI/res/values-iw/strings.xml +++ b/packages/SystemUI/res/values-iw/strings.xml @@ -75,6 +75,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"צילום המסך בוצע."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"גע כדי להציג את צילום המסך שלך"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"לא ניתן לבצע צילום מסך."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"לא ניתן לשמור צילום מסך עקב שטח אחסון מוגבל."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"האפליקציה, או הארגון שלך, אינם מתירים לבצע צילומי מסך."</string> <string name="usb_preference_title" msgid="6551050377388882787">"אפשרויות העברת קבצים ב-USB"</string> diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index b4b24ecc1c80..27bb23224011 100644 --- a/packages/SystemUI/res/values-ja/strings.xml +++ b/packages/SystemUI/res/values-ja/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"スクリーンショットを取得しました。"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"タップしてスクリーンショットを表示します。"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"スクリーンショットをキャプチャできませんでした。"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"スクリーンショットの保存中に問題が発生しました。"</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"空き容量が足りないため、スクリーンショットを保存できません。"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"アプリまたは組織によって許可されていないため、スクリーンショットは撮れません。"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USBファイル転送オプション"</string> diff --git a/packages/SystemUI/res/values-ja/strings_tv.xml b/packages/SystemUI/res/values-ja/strings_tv.xml index 8c56866b9b5c..be6693bc2329 100644 --- a/packages/SystemUI/res/values-ja/strings_tv.xml +++ b/packages/SystemUI/res/values-ja/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"PIP を閉じる"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"全画面表示"</string> <string name="pip_play" msgid="674145557658227044">"再生"</string> <string name="pip_pause" msgid="8412075640017218862">"一時停止"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"PIP を管理するには ["<b>"ホーム"</b>"] を押し続けます"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP を管理するには\n[ホーム] ボタンを押し続けます"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"閉じる"</string> </resources> diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml index 4c461de820be..41da19150da1 100644 --- a/packages/SystemUI/res/values-ka-rGE/strings.xml +++ b/packages/SystemUI/res/values-ka-rGE/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"სკრინშოტი გადაღებულია."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"შეეხეთ ეკრანის სურათის სანახავად."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"ვერ მოხერხდა ეკრანის ანაბეჭდის გადაღება."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ეკრანის ანაბეჭდის შენახვა ვერ მოხერხდა შეზღუდული მეხსიერების გამო."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ეკრანის ანაბეჭდების შექმნა არ არის ნებადართული აპის ან თქვენი ორგანიზაციის მიერ."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ფაილის ტრანსფერის პარამეტრები"</string> diff --git a/packages/SystemUI/res/values-ka-rGE/strings_tv.xml b/packages/SystemUI/res/values-ka-rGE/strings_tv.xml index 9c5b0d6e7927..97944c3c0112 100644 --- a/packages/SystemUI/res/values-ka-rGE/strings_tv.xml +++ b/packages/SystemUI/res/values-ka-rGE/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"PIP-ის დახურვა"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"სრულ ეკრანზე"</string> <string name="pip_play" msgid="674145557658227044">"დაკვრა"</string> <string name="pip_pause" msgid="8412075640017218862">"პაუზა"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"PIP-ის სამართავად, გეჭიროთ "<b>"მთავარ ღილაკზე"</b></string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP-ის სამართავად, ხანგრძლივად\nდააჭირეთ მთავარ ღილაკს"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"გასაგებია"</string> </resources> diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml index f1c09d8d3c38..bc56c8e0b5e3 100644 --- a/packages/SystemUI/res/values-kk-rKZ/strings.xml +++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Скриншот сақталды."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Скриншотты көру үшін түрту."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Скриншот жасалмады."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Скриншотты сақтау кезінде мәселе орын алды."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Жадтағы шектеулі бос орынға байланысты скриншотты сақтау мүмкін емес."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Қолданба немесе ұйым скриншоттар түсіруге рұқсат етпейді."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB файлын жіберу опциялары"</string> diff --git a/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml b/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml index 3fc3403b14e5..f67157c669b6 100644 --- a/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml +++ b/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"PIP жабу"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Толық экран"</string> <string name="pip_play" msgid="674145557658227044">"Ойнату"</string> <string name="pip_pause" msgid="8412075640017218862">"Кідірту"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"PIP бас. үшін "<b>"HOME"</b>" түй. ұс. тұр."</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP бас. үшін HOME\n түй. бас., ұс. тұр."</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Түсіндім"</string> </resources> diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml index 845a48e0f01b..cafa32902e5d 100644 --- a/packages/SystemUI/res/values-km-rKH/strings.xml +++ b/packages/SystemUI/res/values-km-rKH/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"បានចាប់យករូបថតអេក្រង់។"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"ប៉ះ ដើម្បីមើលរូបថតអេក្រង់របស់អ្នក។"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"មិនអាចចាប់យករូបថតអេក្រង់។"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"បានជួបប្រទះបញ្ហាខណៈពេលរក្សាទុកការថតអេក្រង់"</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"មិនអាចរក្សាទុករូបថតអេក្រង់បានទេដោយសារទំហំផ្ទុកមានកម្រិត។"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ការថតរូបអេក្រង់មិនត្រូវបានអនុញ្ញាតដោយកម្មវិធីនេះ ឬស្ថាប័នរបស់អ្នក។"</string> <string name="usb_preference_title" msgid="6551050377388882787">"ជម្រើសផ្ទេរឯកសារតាមយូអេសប៊ី"</string> diff --git a/packages/SystemUI/res/values-km-rKH/strings_tv.xml b/packages/SystemUI/res/values-km-rKH/strings_tv.xml index 4b4213264157..cc0a8b0e32a3 100644 --- a/packages/SystemUI/res/values-km-rKH/strings_tv.xml +++ b/packages/SystemUI/res/values-km-rKH/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"បិទ PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"ពេញអេក្រង់"</string> <string name="pip_play" msgid="674145557658227044">"ចាក់"</string> <string name="pip_pause" msgid="8412075640017218862">"ផ្អាក"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"សង្កត់ប៊ូតុង "<b>"ដើម"</b>" ដើម្បីគ្រប់គ្រង PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"ចុច និងសង្កត់ប៊ូតុង ដើម\nដើម្បីគ្រប់គ្រង PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"យល់ហើយ"</string> </resources> diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml index bf604e783b34..62a1235f40d0 100644 --- a/packages/SystemUI/res/values-kn-rIN/strings.xml +++ b/packages/SystemUI/res/values-kn-rIN/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ಸೆರೆಹಿಡಿಯಲಾಗಿದೆ."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ಶಾಟ್ ವೀಕ್ಷಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"ಸ್ಕ್ರೀನ್ಶಾಟ್ ಸೆರೆಹಿಡಿಯಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ಪರಿಮಿತ ಸಂಗ್ರಹಣೆ ಸ್ಥಳದ ಕಾರಣದಿಂದಾಗಿ ಸ್ಕ್ರೀನ್ಶಾಟ್ ಉಳಿಸಲು ಸಾಧ್ಯವಿಲ್ಲ."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ಸ್ಕ್ರೀನ್ಶಾಟ್ಗಳನ್ನು ತೆಗೆದುಕೊಳ್ಳುವುದನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಅಥವಾ ನಿಮ್ಮ ಸಂಸ್ಥೆ ಅನುಮತಿಸುವುದಿಲ್ಲ."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ಫೈಲ್ ವರ್ಗಾವಣೆ ಆಯ್ಕೆಗಳು"</string> diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index 1a1cabe10f07..fca1dba068fa 100644 --- a/packages/SystemUI/res/values-ko/strings.xml +++ b/packages/SystemUI/res/values-ko/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"캡쳐화면 저장됨"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"캡쳐화면을 보려면 터치하세요."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"캡쳐화면을 캡쳐하지 못했습니다."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"저장용량이 부족하여 스크린샷을 저장할 수 없습니다."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"앱이나 조직에서 스크린샷 촬영을 허용하지 않습니다."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB 파일 전송 옵션"</string> diff --git a/packages/SystemUI/res/values-ko/strings_tv.xml b/packages/SystemUI/res/values-ko/strings_tv.xml index e7cac9fc2a8b..ea12d5e6a6cc 100644 --- a/packages/SystemUI/res/values-ko/strings_tv.xml +++ b/packages/SystemUI/res/values-ko/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"PIP 닫기"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"전체화면"</string> <string name="pip_play" msgid="674145557658227044">"재생"</string> <string name="pip_pause" msgid="8412075640017218862">"일시중지"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109"><b>"HOME"</b>"을 눌러 PIP 제어"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"HOME\n버튼을 길게 눌러 PIP 제어"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"확인"</string> </resources> diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml index 571b69157a02..88948202bc37 100644 --- a/packages/SystemUI/res/values-ky-rKG/strings.xml +++ b/packages/SystemUI/res/values-ky-rKG/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Скриншот тартылды."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Тийип, скриншотту көрүңүз."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Скриншот кылынбай жатат."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Сактагычта бош орун аз болгондуктан скриншот сакталбай жатат."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Скриншот тартууга колдонмо же ишканаңыз уруксат бербейт."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB менен файл өткөрүү мүмкүнчүлүктөрү"</string> diff --git a/packages/SystemUI/res/values-ky-rKG/strings_tv.xml b/packages/SystemUI/res/values-ky-rKG/strings_tv.xml index 2724230fc74a..e95bc8912282 100644 --- a/packages/SystemUI/res/values-ky-rKG/strings_tv.xml +++ b/packages/SystemUI/res/values-ky-rKG/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"PIP\'ти жабуу"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Толук экран"</string> <string name="pip_play" msgid="674145557658227044">"Ойнотуу"</string> <string name="pip_pause" msgid="8412075640017218862">"Тындыруу"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"PIP\'ти көзөмөлдөө үчүн "<b>"БАШКЫ БЕТ"</b>" баскычын кармап туруңуз"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP\'ти көзөмөлдөө үчүн БАШКЫ БЕТ\nбаскычын басып, кармап туруңуз"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Түшүндүм"</string> </resources> diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml index 823e02b82818..80c1e01d7137 100644 --- a/packages/SystemUI/res/values-lo-rLA/strings.xml +++ b/packages/SystemUI/res/values-lo-rLA/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"ຖ່າຍຮູບໜ້າຈໍແລ້ວ"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"ແຕະເພື່ອເບິ່ງພາບໜ້າຈໍຂອງທ່ານ."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"ບໍ່ສາມາດຖ່າຍຮູບໜ້າຈໍໄດ້"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"ເກີດບັນຫາໃນການບັນທຶກພາບໜ້າຈໍຂອງທ່ານ."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ບໍ່ສາມາດຖ່າຍຮູບໜ້າຈໍໄດ້ເນື່ອງຈາກພື້ນທີ່ຈັດເກັບຂໍ້ມູນມີຈຳກັດ."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ແອັບ ຫຼື ອົງກອນຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ມີການຖ່າຍຮູບໜ້າຈໍ."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ໂຕເລືອກການຍ້າຍໄຟລ໌"</string> diff --git a/packages/SystemUI/res/values-lo-rLA/strings_tv.xml b/packages/SystemUI/res/values-lo-rLA/strings_tv.xml index 47374e8affe2..f6bc833363aa 100644 --- a/packages/SystemUI/res/values-lo-rLA/strings_tv.xml +++ b/packages/SystemUI/res/values-lo-rLA/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"ປິດ PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"ເຕັມໜ້າຈໍ"</string> <string name="pip_play" msgid="674145557658227044">"ຫຼິ້ນ"</string> <string name="pip_pause" msgid="8412075640017218862">"ຢຸດຊົ່ວຄາວ"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"ກົດ "<b>"HOME"</b>" ຄ້າງໄວ້ເພື່ອຄວບຄຸມ PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"ກົດປຸ່ມ HOME\nຄ້າງໄວ້ເພື່ອຄວບຄຸມ PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"ເຂົ້າໃຈແລ້ວ"</string> </resources> diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml index db354eb26b40..4299efa0c784 100644 --- a/packages/SystemUI/res/values-lt/strings.xml +++ b/packages/SystemUI/res/values-lt/strings.xml @@ -75,6 +75,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekrano kopija užfiksuota."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Palieskite, kad peržiūrėtumėte ekrano kopiją."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Nepavyko užfiksuoti ekrano kopijos."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Negalima išsaugoti ekrano kopijos dėl ribotos saugyklos vietos."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Jūsų organizacijoje arba naudojant šią programą neleidžiama daryti ekrano kopijų"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB failo perdavimo parinktys"</string> diff --git a/packages/SystemUI/res/values-lt/strings_tv.xml b/packages/SystemUI/res/values-lt/strings_tv.xml index ac3a44e9a3d8..140b55ddd62a 100644 --- a/packages/SystemUI/res/values-lt/strings_tv.xml +++ b/packages/SystemUI/res/values-lt/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Uždaryti PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Visas ekranas"</string> <string name="pip_play" msgid="674145557658227044">"Leisti"</string> <string name="pip_pause" msgid="8412075640017218862">"Pristabdyti"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Kad vald. PIP, pal. pasp. m. "<b>"PAGRINDINIS"</b></string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Kad vald. PIP, pal.\npasp. m. PAGRINDINIS"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Supratau"</string> </resources> diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml index 29e1b95c7845..ad00ad0e5359 100644 --- a/packages/SystemUI/res/values-lv/strings.xml +++ b/packages/SystemUI/res/values-lv/strings.xml @@ -74,6 +74,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekrānuzņēmums ir uzņemts."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Pieskarieties, lai skatītu ekrānuzņēmumu."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Nevarēja uzņemt ekrānuzņēmumu."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Nevar saglabāt ekrānuzņēmumu, jo krātuvē nepietiek vietas."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Lietotne vai jūsu organizācija neatļauj veikt ekrānuzņēmumus."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB failu pārsūtīšanas opcijas"</string> diff --git a/packages/SystemUI/res/values-lv/strings_tv.xml b/packages/SystemUI/res/values-lv/strings_tv.xml index 7fa804db1c90..d7ca3704f00c 100644 --- a/packages/SystemUI/res/values-lv/strings_tv.xml +++ b/packages/SystemUI/res/values-lv/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Aizvērt PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Pilnekrāna režīms"</string> <string name="pip_play" msgid="674145557658227044">"Atskaņot"</string> <string name="pip_pause" msgid="8412075640017218862">"Apturēt"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Turiet taustiņu "<b>"SĀKUMS"</b>", lai kontrolētu PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Nospiediet un turiet pogu SĀKUMS,\n lai kontrolētu PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Labi"</string> </resources> diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml index cf97df84fabc..4116b6ff6df6 100644 --- a/packages/SystemUI/res/values-mk-rMK/strings.xml +++ b/packages/SystemUI/res/values-mk-rMK/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Сликата на екранот е снимена."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Допрете за да ја видите сликата на екранот."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Сликата на екранот не можеше да се сними."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Сликата од екранот не може да се зачува поради ограничена меморија."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Апликацијата или вашата организација не дозволува создавање слики од екранот."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Пренос на датотека со УСБ"</string> diff --git a/packages/SystemUI/res/values-mk-rMK/strings_tv.xml b/packages/SystemUI/res/values-mk-rMK/strings_tv.xml index 30c6db9297d3..5f88cb5c4dce 100644 --- a/packages/SystemUI/res/values-mk-rMK/strings_tv.xml +++ b/packages/SystemUI/res/values-mk-rMK/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Затвори PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Цел екран"</string> <string name="pip_play" msgid="674145557658227044">"Пушти"</string> <string name="pip_pause" msgid="8412075640017218862">"Пауза"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Задржете "<b>"ДОМА"</b>" за кон. PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Притиснете и задржете го копчето\nДОМА за контролирање PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Разбрав"</string> </resources> diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml index df69933ba178..f861a0022cd4 100644 --- a/packages/SystemUI/res/values-ml-rIN/strings.xml +++ b/packages/SystemUI/res/values-ml-rIN/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"സ്ക്രീൻഷോട്ട് എടുത്തു."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"നിങ്ങളുടെ സ്ക്രീൻഷോട്ട് കാണാനായി സ്പർശിക്കുക."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"സ്ക്രീൻഷോട്ട് എടുക്കാൻ കഴിഞ്ഞില്ല."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"സ്റ്റോറേജ് ഇടം പരിമിതമായതിനാൽ സ്ക്രീൻഷോട്ട് സംരക്ഷിക്കാൻ കഴിയില്ല."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"സ്ക്രീൻഷോട്ടുകൾ എടുക്കുന്നത് ആപ്പോ നിങ്ങളുടെ സ്ഥാപനമോ അനുവദിക്കുന്നില്ല."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ഫയൽ കൈമാറൽ ഓപ്ഷനുകൾ"</string> diff --git a/packages/SystemUI/res/values-ml-rIN/strings_tv.xml b/packages/SystemUI/res/values-ml-rIN/strings_tv.xml index 564a32ab1870..0094bb6704e0 100644 --- a/packages/SystemUI/res/values-ml-rIN/strings_tv.xml +++ b/packages/SystemUI/res/values-ml-rIN/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"PIP അടയ്ക്കുക"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"പൂര്ണ്ണ സ്ക്രീന്"</string> <string name="pip_play" msgid="674145557658227044">"പ്ലേ ചെയ്യുക"</string> <string name="pip_pause" msgid="8412075640017218862">"തൽക്കാലം നിർത്തൂ"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"PIP നിയന്ത്രിക്കാൻ "<b>"ഹോം"</b>" പിടിക്കുക"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP നിയന്ത്രിക്കാൻ ഹോം\nബട്ടൺ അമർത്തിപ്പിടിക്കുക"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"മനസ്സിലായി"</string> </resources> diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml index 793e16551f06..73df53559da6 100644 --- a/packages/SystemUI/res/values-mn-rMN/strings.xml +++ b/packages/SystemUI/res/values-mn-rMN/strings.xml @@ -71,6 +71,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Дэлгэцийн агшинг авсан."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Дэлгэцийн агшныг харах бол хүрнэ үү."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Дэлгэцийн агшинг авч чадсангүй."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Дэлгэцийн агшинг хадгалахад алдаа гарлаа."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Хадгалах сангийн багтаамж бага байгаа тул дэлгэцийн авсан зургийг хадгалах боломжгүй байна."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Дэлгэцийн зураг авахыг апп эсвэл танай байгууллагаас зөвшөөрөөгүй байна."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB файл шилжүүлэх сонголт"</string> diff --git a/packages/SystemUI/res/values-mn-rMN/strings_tv.xml b/packages/SystemUI/res/values-mn-rMN/strings_tv.xml index ae4029fd4eb2..78b7cc859e6d 100644 --- a/packages/SystemUI/res/values-mn-rMN/strings_tv.xml +++ b/packages/SystemUI/res/values-mn-rMN/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"PIP-г хаах"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Бүтэн дэлгэц"</string> <string name="pip_play" msgid="674145557658227044">"Тоглуулах"</string> <string name="pip_pause" msgid="8412075640017218862">"Түр зогсоох"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"PIP-г удирдахын тулд "<b>"HOME"</b>" товчлуурыг дарна уу"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP-г удирдахын тулд HOME\nтовчлуурыг дараад хүлээнэ үү"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Ойлголоо"</string> </resources> diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml index e39db5d0789c..a3cb7361092a 100644 --- a/packages/SystemUI/res/values-mr-rIN/strings.xml +++ b/packages/SystemUI/res/values-mr-rIN/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"स्क्रीनशॉट कॅप्चर केला."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"आपला स्क्रीनशॉट पाहण्यासाठी स्पर्श करा."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"स्क्रीनशॉट कॅप्चर करू शकलो नाही."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"मर्यादित संचय जागेमुळे स्क्रीनशॉट जतन करू शकत नाही."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"अॅप किंवा आपल्या संस्थेद्वारे स्क्रीनशॉट घेण्यास अनुमती नाही."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB फाईल स्थानांतरण पर्याय"</string> diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml index 3ec3db17da1c..75fdf62485aa 100644 --- a/packages/SystemUI/res/values-ms-rMY/strings.xml +++ b/packages/SystemUI/res/values-ms-rMY/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Tangkapan skrin ditangkap."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Sentuh untuk melihat tangkapan skrin anda."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Tidak dapat menangkap tangkapan skrin."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Tidak dapat menyimpan tangkapan skrin kerana ruang storan terhad."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Apl atau organisasi anda tidak membenarkan pengambilan tangkapan skrin."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Pilihan pemindahan fail USB"</string> diff --git a/packages/SystemUI/res/values-ms-rMY/strings_tv.xml b/packages/SystemUI/res/values-ms-rMY/strings_tv.xml index feae0424b603..5fc98b9a1f25 100644 --- a/packages/SystemUI/res/values-ms-rMY/strings_tv.xml +++ b/packages/SystemUI/res/values-ms-rMY/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Tutup PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Skrin penuh"</string> <string name="pip_play" msgid="674145557658227044">"Main"</string> <string name="pip_pause" msgid="8412075640017218862">"Jeda"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Thn "<b>"SKRN UTMA"</b>" utk kwl PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Tkn & thn butang SKRIN UTAMA\nutk mengawal PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string> </resources> diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml index ca3414488583..d7597a598ea0 100644 --- a/packages/SystemUI/res/values-my-rMM/strings.xml +++ b/packages/SystemUI/res/values-my-rMM/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"ဖန်သားပြင်ဓါတ်ပုံရိုက်ခြင်းအား ဖမ်းယူပြီး"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"သင့်ဖန်သားပြင်ဓါတ်ပုံရိုက်ခြင်းအား ကြည့်ရှုရန် ထိပါ"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"ဖန်သားပြင်ဓါတ်ပုံရိုက်ခြင်းအား မဖမ်းစီးနိုင်ပါ"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"ဖန်သားပြင်ဓာတ်ပုံဖမ်းယူမှုကို သိမ်းဆည်းရာတွင် ပြဿနာကြုံခဲ့သည်။"</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"သိုလှောင်ခန်းနေရာ အကန့်အသတ်ရှိသောကြောင့် ဖန်သားပြင်ဓာတ်ပုံကို သိမ်းဆည်း၍မရပါ။"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ဖန်သားပြင်ဓာတ်ပုံရိုက်ကူးခြင်းကို အက်ပ်မှ သို့မဟုတ် သင့်အဖွဲ့အစည်းမှ ခွင့်မပြုပါ။"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ဖိုင်ပြောင်း ရွေးမှုများ"</string> diff --git a/packages/SystemUI/res/values-my-rMM/strings_tv.xml b/packages/SystemUI/res/values-my-rMM/strings_tv.xml index ebadebe4516b..8491e371604a 100644 --- a/packages/SystemUI/res/values-my-rMM/strings_tv.xml +++ b/packages/SystemUI/res/values-my-rMM/strings_tv.xml @@ -23,7 +23,7 @@ <string name="pip_fullscreen" msgid="8604643018538487816">"မျက်နှာပြင် အပြည့်"</string> <string name="pip_play" msgid="674145557658227044">"ဖွင့်ပါ"</string> <string name="pip_pause" msgid="8412075640017218862">"ဆိုင်းငံ့ပါ"</string> - <string name="pip_hold_home" msgid="340086535668778109">"PIP ကိုထိန်းချုပ်ရန် "<b>"ပင်မခလုတ်"</b>" ကိုဖိထားပါ"</string> - <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP ကိုထိန်းချုပ်ရန် ပင်မခလုတ်\nကိုနှိပ်ပြီးဖိထားပါ"</string> + <string name="pip_hold_home" msgid="340086535668778109">"PIP ကိုထိန်းချုပ်ရန် "<b>"ပင်မ"</b>" ခလုတ်ကို ဖိထားပါ"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP ကိုထိန်းချုပ်ရန် ပင်မ\nခလုတ်ကို နှိပ်ပြီးဖိထားပါ"</string> <string name="pip_onboarding_button" msgid="3957426748484904611">"ရပါပြီ"</string> </resources> diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml index 269746e2a56a..5b0c6eb92497 100644 --- a/packages/SystemUI/res/values-nb/strings.xml +++ b/packages/SystemUI/res/values-nb/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Skjermdumpen er lagret."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Trykk for å se skjermdumpen."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Kan ikke lagre skjermdumpen."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Kan ikke lagre skjermdumpen på grunn av begrenset lagringsplass."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Appen eller organisasjonen din tillater ikke at du tar skjermdumper."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Altern. for USB-filoverføring"</string> diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml index 882a19426cf9..42067abd9cf4 100644 --- a/packages/SystemUI/res/values-ne-rNP/strings.xml +++ b/packages/SystemUI/res/values-ne-rNP/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"स्क्रिनसट क्याप्चर गरियो।"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"तपाईँको स्क्रिनसट हेर्न छुनुहोस्।"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"स्क्रिनसट क्याप्चर गर्न सकिएन।"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"स्क्रिनसटलाई सुरक्षित गर्दा समस्या भयो।"</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"सीमित भण्डारण स्थान उपलब्ध रहेको हुनाले स्क्रिनसटलाई सुरक्षित गर्न सकिँदैन।"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"अनुप्रयोग वा तपाईँको संगठनले स्क्रिनसट लिन अनुमति दॅिंदैन।"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB फाइल सार्ने विकल्पहरू"</string> @@ -220,10 +221,8 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"कार्य मोड अन।"</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"कार्य मोड बन्द भयो।"</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"कार्य मोड सक्रिय भयो।"</string> - <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) --> - <skip /> - <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) --> - <skip /> + <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"डेटा सेभरलाई निष्क्रिय पारियो।"</string> + <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"डेटा सेभरलाई सक्रिय गरियो।"</string> <string name="accessibility_brightness" msgid="8003681285547803095">"प्रदर्शन चमक"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G डेटा रोकिएको छ"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G डेटा रोकिएको छ"</string> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 99acbaa2e3f9..6f15bafee917 100644 --- a/packages/SystemUI/res/values-nl/strings.xml +++ b/packages/SystemUI/res/values-nl/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Screenshot gemaakt."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Raak aan om je screenshot te bekijken."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Screenshot is niet gemaakt."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Er is een probleem opgetreden bij het opslaan van het screenshot."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Kan screenshot niet opslaan vanwege beperkte opslagruimte."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Het maken van screenshots wordt niet toegestaan door de app of je organisatie."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opties voor USB-bestandsoverdracht"</string> diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml index 2de6583096c1..d07c4d2a864f 100644 --- a/packages/SystemUI/res/values-pa-rIN/strings.xml +++ b/packages/SystemUI/res/values-pa-rIN/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"ਸਕ੍ਰੀਨਸ਼ੌਟ ਕੈਪਚਰ ਕੀਤਾ।"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"ਆਪਣਾ ਸਕ੍ਰੀਨਸ਼ੌਟ ਦੇਖਣ ਲਈ ਛੋਹਵੋ।"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"ਸਕ੍ਰੀਨਸ਼ੌਟ ਕੈਪਚਰ ਨਹੀਂ ਕਰ ਸਕਿਆ।"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"ਸਕ੍ਰੀਨਸ਼ਾਟ ਰੱਖਿਅਤ ਕਰਨ ਦੌਰਾਨ ਸਮੱਸਿਆ ਆਈ।"</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ਸੀਮਿਤ ਸਟੋਰੇਜ ਥਾਂ ਦੇ ਕਾਰਨ ਸਕ੍ਰੀਨਸ਼ਾਟ ਰੱਖਿਅਤ ਨਹੀਂ ਕੀਤਾ ਸਕਦਾ।"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ਐਪ ਜਾਂ ਤੁਹਾਡੀ ਸੰਸਥਾ ਦੁਆਰਾ ਸਕ੍ਰੀਨਸ਼ਾਟ ਲੈਣ ਦੀ ਮਨਜ਼ੂਰੀ ਨਹੀਂ ਹੈ।"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ਫਾਈਲ ਟ੍ਰਾਂਸਫਰ ਚੋਣਾਂ"</string> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 0fdb4dfd5195..8a1fff6e0f2c 100644 --- a/packages/SystemUI/res/values-pl/strings.xml +++ b/packages/SystemUI/res/values-pl/strings.xml @@ -75,6 +75,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Wykonano zrzut ekranu."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Dotknij, aby wyświetlić zrzut ekranu."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Nie udało się wykonać zrzutu ekranu."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Nie można zapisać zrzutu ekranu, bo brakuje miejsca w pamięci."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Nie możesz wykonać zrzutu ekranu, bo nie zezwala na to aplikacja lub Twoja organizacja."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB – opcje przesyłania plików"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 86b94ab55819..1cf0ed98b635 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura de tela obtida."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Toque para visualizar a captura de tela."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Não foi possível obter a captura de tela."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Não é possível salvar a captura de tela, porque não há espaço suficiente."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Capturas de tela não são permitidas pelo app ou por sua organização."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opções transf. arq. por USB"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml index 742ea28e6751..21d36e09e425 100644 --- a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml +++ b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Fechar PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Tela cheia"</string> <string name="pip_play" msgid="674145557658227044">"Reproduzir"</string> <string name="pip_pause" msgid="8412075640017218862">"Pausar"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Mantenha "<b>"INÍCIO"</b>" pressionado para controlar o PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Mantenha o botão INÍCIO\npressionado para controlar o PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Entendi"</string> </resources> diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml index 35ef0dd7b65b..520abc45a4a7 100644 --- a/packages/SystemUI/res/values-pt-rPT/strings.xml +++ b/packages/SystemUI/res/values-pt-rPT/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura de ecrã efetuada"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Toque para ver a captura de ecrã"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Não foi possível obter captura de ecrã."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Problema encontrado ao guardar a captura de ecrã."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Não é possível guardar a captura de ecrã devido a espaço de armazenamento limitado."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"A aplicação ou a sua entidade não tem autorização para tirar capturas de ecrã."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opções de transm. de fich. USB"</string> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 86b94ab55819..1cf0ed98b635 100644 --- a/packages/SystemUI/res/values-pt/strings.xml +++ b/packages/SystemUI/res/values-pt/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Captura de tela obtida."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Toque para visualizar a captura de tela."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Não foi possível obter a captura de tela."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Não é possível salvar a captura de tela, porque não há espaço suficiente."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Capturas de tela não são permitidas pelo app ou por sua organização."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opções transf. arq. por USB"</string> diff --git a/packages/SystemUI/res/values-pt/strings_tv.xml b/packages/SystemUI/res/values-pt/strings_tv.xml index 742ea28e6751..21d36e09e425 100644 --- a/packages/SystemUI/res/values-pt/strings_tv.xml +++ b/packages/SystemUI/res/values-pt/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Fechar PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Tela cheia"</string> <string name="pip_play" msgid="674145557658227044">"Reproduzir"</string> <string name="pip_pause" msgid="8412075640017218862">"Pausar"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Mantenha "<b>"INÍCIO"</b>" pressionado para controlar o PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Mantenha o botão INÍCIO\npressionado para controlar o PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Entendi"</string> </resources> diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml index b854ffba4579..113f2bc7907b 100644 --- a/packages/SystemUI/res/values-ro/strings.xml +++ b/packages/SystemUI/res/values-ro/strings.xml @@ -74,6 +74,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Captură de ecran realizată."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Atingeți pentru a vedea captura de ecran."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Captura de ecran nu a putut fi realizată."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Captura de ecran nu poate fi salvată din cauza spațiului de stocare limitat."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Crearea capturilor de ecran nu este permisă de aplicație sau de organizația dvs."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opțiuni pentru transferul de fișiere prin USB"</string> diff --git a/packages/SystemUI/res/values-ro/strings_tv.xml b/packages/SystemUI/res/values-ro/strings_tv.xml index cbe5e386e78e..e30b2f9fdf4e 100644 --- a/packages/SystemUI/res/values-ro/strings_tv.xml +++ b/packages/SystemUI/res/values-ro/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Închideți PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Ecran complet"</string> <string name="pip_play" msgid="674145557658227044">"Redați"</string> <string name="pip_pause" msgid="8412075640017218862">"Întrerupeți"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Apăsați lung "<b>"ACASĂ"</b>" pentru a controla PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Apăsați lung ACASĂ\npentru a controla PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Am înțeles"</string> </resources> diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml index 5a7e51c74cac..c131284ffa9b 100644 --- a/packages/SystemUI/res/values-ru/strings.xml +++ b/packages/SystemUI/res/values-ru/strings.xml @@ -75,6 +75,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Скриншот сохранен"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Нажмите, чтобы просмотреть"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Не удалось сохранить скриншот."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Не удалось сохранить скриншот: недостаточно места."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Не удалось сделать скриншот: нет разрешения от приложения или организации."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Параметры передачи через USB"</string> diff --git a/packages/SystemUI/res/values-ru/strings_tv.xml b/packages/SystemUI/res/values-ru/strings_tv.xml index dd9cb5a8b20d..f25b460916d4 100644 --- a/packages/SystemUI/res/values-ru/strings_tv.xml +++ b/packages/SystemUI/res/values-ru/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"\"Кадр в кадре\" – выйти"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Во весь экран"</string> <string name="pip_play" msgid="674145557658227044">"Воспроизвести"</string> <string name="pip_pause" msgid="8412075640017218862">"Приостановить"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Управляйте кадром в кадре, удерживая кнопку "<b>"ГЛАВНАЯ"</b></string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Управляйте кадром в кадре,\nудерживая кнопку \"ГЛАВНАЯ\""</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"ОК"</string> </resources> diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml index 1e178cfe3d08..5a09d3e4785f 100644 --- a/packages/SystemUI/res/values-si-rLK/strings.xml +++ b/packages/SystemUI/res/values-si-rLK/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"තිර රුව ග්රහණය කරන ලදි."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"ඔබගේ තිර රුව බැලීමට ස්පර්ශ කරන්න."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"තිර රුව ග්රහණය කිරීමට නොහැකි විය."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"තිර රුව සුරකින අතරතුර ගැටලුවක් ඇති විය."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"සීමිත ගබඩා ඉඩ නිසා තිර රුව සුරැකිය නොහැකිය."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"තිර රූ ගැනීමට යෙදුම හෝ ඔබගේ සංවිධානය ඉඩ නොදේ."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ගොනු හුවමාරු විකල්ප"</string> diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index c07598055318..26d6d2fbd9eb 100644 --- a/packages/SystemUI/res/values-sk/strings.xml +++ b/packages/SystemUI/res/values-sk/strings.xml @@ -75,6 +75,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Snímka obrazovky bola zaznamenaná."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Snímku obrazovky zobrazíte dotykom."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Snímku obrazovky sa nepodarilo zachytiť."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Snímku obrazovky nie je možné vytvoriť z dôvodu nedostatku miesta v úložisku."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Vytváranie snímok obrazovky je zakázané aplikáciou alebo vašou organizáciou."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Možnosti prenosu súborov USB"</string> @@ -222,10 +224,8 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Pracovný režim – zap."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Pracovný režim je vypnutý."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Pracovný režim je zapnutý."</string> - <!-- no translation found for accessibility_quick_settings_data_saver_changed_off (650231949881093289) --> - <skip /> - <!-- no translation found for accessibility_quick_settings_data_saver_changed_on (4218725402373934151) --> - <skip /> + <string name="accessibility_quick_settings_data_saver_changed_off" msgid="650231949881093289">"Šetrič dát bol vypnutý."</string> + <string name="accessibility_quick_settings_data_saver_changed_on" msgid="4218725402373934151">"Šetrič dát bol zapnutý."</string> <string name="accessibility_brightness" msgid="8003681285547803095">"Jas displeja"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Dátové prenosy 2G a 3G sú pozastavené"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Dátové prenosy 4G sú pozastavené"</string> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 8aa79bec6725..b268f183ff6a 100644 --- a/packages/SystemUI/res/values-sl/strings.xml +++ b/packages/SystemUI/res/values-sl/strings.xml @@ -75,6 +75,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Posnetek zaslona je shranjen."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Dotaknite se, če si želite ogledati posnetek zaslona."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Posnetka zaslona ni bilo mogoče shraniti."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Pri shranjevanju posnetka zaslona je prišlo do težave."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Shranjevanje posnetka zaslona ni mogoče zaradi omejenega prostora za shranjevanje."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Aplikacija ali organizacija ne dovoljuje posnetkov zaslona."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Možnosti prenosa datotek prek USB-ja"</string> diff --git a/packages/SystemUI/res/values-sl/strings_tv.xml b/packages/SystemUI/res/values-sl/strings_tv.xml index 9fab6e1dfede..e1d160413914 100644 --- a/packages/SystemUI/res/values-sl/strings_tv.xml +++ b/packages/SystemUI/res/values-sl/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Zapri način PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Celozaslonsko"</string> <string name="pip_play" msgid="674145557658227044">"Predvajanje"</string> <string name="pip_pause" msgid="8412075640017218862">"Zaustavitev"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Pridr. "<b>"HOME"</b>" za up. n. PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Pridržite gumb HOME\nza upravljanje načina PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Razumem"</string> </resources> diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml index 8314044b072e..b3e6ea8d2ee2 100644 --- a/packages/SystemUI/res/values-sq-rAL/strings.xml +++ b/packages/SystemUI/res/values-sq-rAL/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Pamja e ekranit u kap."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Prek për të parë pamjen e ekranit tënd."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Nuk mundi të kapte pamjen e ekranit."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Pamja e ekranit nuk mund të ruhet për shkak të hapësirës ruajtëse të kufizuar."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Nxjerrja e pamjeve të ekranit nuk lejohet nga aplikacioni ose organizata jote."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opsionet e transferimit të dosjeve të USB-së"</string> diff --git a/packages/SystemUI/res/values-sq-rAL/strings_tv.xml b/packages/SystemUI/res/values-sq-rAL/strings_tv.xml index 10cf2f9f7dd2..28bfbb5b3fe5 100644 --- a/packages/SystemUI/res/values-sq-rAL/strings_tv.xml +++ b/packages/SystemUI/res/values-sq-rAL/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Mbyll PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Ekrani i plotë"</string> <string name="pip_play" msgid="674145557658227044">"Luaj"</string> <string name="pip_pause" msgid="8412075640017218862">"Pauzë"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Mbaj shtypur "<b>"HOME"</b>" për të kontrolluar PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Shtyp dhe mbaj shtypur butonin HOME\npër të kontrolluar PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"E kuptova"</string> </resources> diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml index 318a92afe743..9c26ebd85350 100644 --- a/packages/SystemUI/res/values-sr/strings.xml +++ b/packages/SystemUI/res/values-sr/strings.xml @@ -74,6 +74,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Снимак екрана је направљен."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Додирните да бисте видели снимак екрана."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Није могуће направити снимак екрана."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Чување снимка екрана није успело због ограниченог меморијског простора."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Апликација или организација не дозвољавају прављење снимака екрана."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Опције USB преноса датотека"</string> diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index a50e7442aeab..0fb5731d4edd 100644 --- a/packages/SystemUI/res/values-sv/strings.xml +++ b/packages/SystemUI/res/values-sv/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Skärmdumpen har tagits."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Tryck här om du vill visa skärmdumpen."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Det gick inte att ta någon skärmdump."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Det går inte att spara skärmdumpen eftersom lagringsutrymmet inte räcker."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Appen eller organisationen tillåter inte att du tar skärmdumpar."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Överföringsalternativ"</string> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index 2a10259b6789..a7162817c490 100644 --- a/packages/SystemUI/res/values-sw/strings.xml +++ b/packages/SystemUI/res/values-sw/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Picha ya skrini imenaswa."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Gusa ili kuona picha yako ya skrini."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Haikuweza kunasa picha ya skrini"</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Haina nafasi ya kutosha kuhifadhi picha ya skrini."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Shirika au programu yako haikuruhusu upige picha za skrini."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Machaguo ya uhamisho wa faili la USB"</string> diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml index eb7dbe4018d9..59fe9dd604c1 100644 --- a/packages/SystemUI/res/values-ta-rIN/strings.xml +++ b/packages/SystemUI/res/values-ta-rIN/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"ஸ்கிரீன் ஷாட் எடுக்கப்பட்டது."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"உங்கள் ஸ்க்ரீன் ஷாட்டைப் பார்க்க தொடவும்."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"ஸ்க்ரீன் ஷாட்டை எடுக்க முடியவில்லை."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"போதுமான சேமிப்பிடம் இல்லாததால் ஸ்கிரீன்ஷாட்டைச் சேமிக்க முடியவில்லை."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"பயன்பாடு அல்லது உங்கள் நிறுவனம் ஸ்கிரீன்ஷாட்டுகளை எடுக்க அனுமதிக்கவில்லை."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB கோப்பு இடமாற்ற விருப்பங்கள்"</string> diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml index 29e25392a604..c7f9b424426b 100644 --- a/packages/SystemUI/res/values-te-rIN/strings.xml +++ b/packages/SystemUI/res/values-te-rIN/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"స్క్రీన్షాట్ క్యాప్చర్ చేయబడింది."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"మీ స్క్రీన్షాట్ను వీక్షించడానికి తాకండి."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"స్క్రీన్షాట్ను క్యాప్చర్ చేయడం సాధ్యపడలేదు."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"పరిమిత నిల్వ స్థలం కారణంగా స్క్రీన్షాట్ను సేవ్ చేయడం సాధ్యపడదు."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"స్క్రీన్షాట్లు తీయడానికి అనువర్తనం లేదా మీ సంస్థ అనుమతించలేదు."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB ఫైల్ బదిలీ ఎంపికలు"</string> diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 2fb82b75218e..98029ed9c785 100644 --- a/packages/SystemUI/res/values-th/strings.xml +++ b/packages/SystemUI/res/values-th/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"จับภาพหน้าจอแล้ว"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"แตะเพื่อดูภาพหน้าจอของคุณ"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"ไม่สามารถจับภาพหน้าจอ"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"พบปัญหาขณะกำลังบันทึกภาพหน้าจอ"</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"ไม่สามารถบันทึกภาพหน้าจอเนื่องจากพื้นที่เก็บข้อมูลมีจำกัด"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"แอปหรือองค์กรของคุณไม่อนุญาตให้จับภาพหน้าจอ"</string> <string name="usb_preference_title" msgid="6551050377388882787">"ตัวเลือกการถ่ายโอนไฟล์ USB"</string> diff --git a/packages/SystemUI/res/values-th/strings_tv.xml b/packages/SystemUI/res/values-th/strings_tv.xml index 78fd1b8837fc..f1c24ec646a6 100644 --- a/packages/SystemUI/res/values-th/strings_tv.xml +++ b/packages/SystemUI/res/values-th/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"ปิด PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"เต็มหน้าจอ"</string> <string name="pip_play" msgid="674145557658227044">"เล่น"</string> <string name="pip_pause" msgid="8412075640017218862">"หยุดชั่วคราว"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"กด "<b>"HOME"</b>" ค้างไว้เพื่อควบคุม PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"กดปุ่ม HOME ค้างไว้\nเพื่อควบคุม PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"รับทราบ"</string> </resources> diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml index 943d21fc4654..d93fd96362f6 100644 --- a/packages/SystemUI/res/values-tl/strings.xml +++ b/packages/SystemUI/res/values-tl/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Nakuha ang screenshot."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Pindutin upang tingnan ang iyong screenshot."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Hindi makuha ang screenshot."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Nagkaroon ng problema habang sine-save ang screenshot."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Hindi ma-save ang screenshot dahil sa limitadong espasyo ng storage."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Hindi pinapayagan ng app o ng iyong organisasyon ang pagkuha ng mga screenshot."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Opsyon paglipat ng USB file"</string> diff --git a/packages/SystemUI/res/values-tl/strings_tv.xml b/packages/SystemUI/res/values-tl/strings_tv.xml index db898c689b24..85a4f5b662d0 100644 --- a/packages/SystemUI/res/values-tl/strings_tv.xml +++ b/packages/SystemUI/res/values-tl/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Isara ang PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string> <string name="pip_play" msgid="674145557658227044">"I-play"</string> <string name="pip_pause" msgid="8412075640017218862">"I-pause"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"I-hold ang "<b>"HOME"</b>" para makontrol ang PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"I-hold ang button na HOME\nupang makontrol ang PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string> </resources> diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml index a294977f5181..12be4c34974d 100644 --- a/packages/SystemUI/res/values-tr/strings.xml +++ b/packages/SystemUI/res/values-tr/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Ekran görüntüsü alındı."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Ekran görüntünüzü izlemek için dokunun."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Ekran görüntüsü alınamadı."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Depolama alanı sınırlı olduğundan ekran görüntüsü kaydedilemiyor."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Uygulama veya kuruluşunuz, ekran görüntüsü alınmasına izin vermiyor."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB dosya aktarım seçenekleri"</string> diff --git a/packages/SystemUI/res/values-tr/strings_tv.xml b/packages/SystemUI/res/values-tr/strings_tv.xml index 255df49a66d3..ea136b14fe1a 100644 --- a/packages/SystemUI/res/values-tr/strings_tv.xml +++ b/packages/SystemUI/res/values-tr/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"PIP\'yi kapat"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Tam ekran"</string> <string name="pip_play" msgid="674145557658227044">"Oynat"</string> <string name="pip_pause" msgid="8412075640017218862">"Duraklat"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"PIP\'yi kontrol etmek için "<b>"ANA EKRAN"</b>"\'ı basılı tutun"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP\'yi kontrol etmek için\nANA EKRAN düğmesini basılı tutun"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Anladım"</string> </resources> diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml index 41b89f905e1f..e7721f127d61 100644 --- a/packages/SystemUI/res/values-uk/strings.xml +++ b/packages/SystemUI/res/values-uk/strings.xml @@ -75,6 +75,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Знімок екрана зроблено."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Торкніться, щоб переглянути знімок екрана."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Не вдалося зробити знімок екрана."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Не вдалося зберегти знімок екрана через обмежений обсяг пам’яті."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Додаток або ваша організація не дозволяють робити знімки екрана."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Парам.передав.файлів через USB"</string> diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml index ba2d014852e3..dd7682868141 100644 --- a/packages/SystemUI/res/values-ur-rPK/strings.xml +++ b/packages/SystemUI/res/values-ur-rPK/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"اسکرین شاٹ کیپچر کیا گیا۔"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"اپنے اسکرین شاٹ دیکھنے کیلئے چھوئیں۔"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"اسکرین شاٹ کیپچر نہیں کر سکے۔"</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"محدود اسٹوریج جگہ کی وجہ سے اسکرین شاٹس نہیں لئے جا سکتے۔"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"ایپ یا آپ کی تنظیم کی جانب سے اسکرین شاٹس لینے کی اجازت نہیں ہے۔"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB فائل منتقل کرنیکے اختیارات"</string> diff --git a/packages/SystemUI/res/values-ur-rPK/strings_tv.xml b/packages/SystemUI/res/values-ur-rPK/strings_tv.xml index 28987c37c693..4929f81fbce6 100644 --- a/packages/SystemUI/res/values-ur-rPK/strings_tv.xml +++ b/packages/SystemUI/res/values-ur-rPK/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"PIP بند کریں"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"فُل اسکرین"</string> <string name="pip_play" msgid="674145557658227044">"چلائیں"</string> <string name="pip_pause" msgid="8412075640017218862">"موقوف کریں"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"PIP کنٹرول کرنے کیلئے "<b>"ہوم"</b>" پکڑے رکھیں"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP کنٹرول کرنے کیلئے\nہوم بٹن دبائیں اور پکڑے رکھیں"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"سمجھ آ گئی"</string> </resources> diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml index 0ad7df6b35e5..21400b305b1d 100644 --- a/packages/SystemUI/res/values-uz-rUZ/strings.xml +++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Skrinshot saqlandi."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Ko‘rish uchun bu yerga bosing."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Skrinshot saqlanmadi."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Xotirada joy kamligi uchun skrinshotni saqlab bo‘lmadi."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Ilova yoki tashkilotingiz skrinshot olishni taqiqlagan."</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB fayl ko‘chirish moslamalari"</string> diff --git a/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml b/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml index 00d259605370..d6ffb67f6b09 100644 --- a/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml +++ b/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"PIP’ni yopish"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"To‘liq ekran"</string> <string name="pip_play" msgid="674145557658227044">"Ijro"</string> <string name="pip_pause" msgid="8412075640017218862">"Pauza"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109"><b>"BOSHIGA"</b>" tugmasini bosib turib, PIP’ni boshqaring"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"BOSHIGA tugmasini bosib turib,\nPIP’ni boshqaring"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string> </resources> diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml index 9a80cb2e1e7e..8f947afcd5ff 100644 --- a/packages/SystemUI/res/values-vi/strings.xml +++ b/packages/SystemUI/res/values-vi/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Đã chụp ảnh màn hình."</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Chạm để xem ảnh chụp màn hình của bạn."</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Không thể chụp ảnh màn hình."</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"Đã gặp phải sự cố khi đang lưu ảnh chụp màn hình."</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Không thể lưu ảnh chụp màn hình do giới hạn dung lượng bộ nhớ."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Ứng dụng hoặc tổ chức của bạn không cho phép chụp ảnh màn hình."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Tùy chọn truyền tệp USB"</string> diff --git a/packages/SystemUI/res/values-vi/strings_tv.xml b/packages/SystemUI/res/values-vi/strings_tv.xml index e4cbc485f0e2..48ba4440082f 100644 --- a/packages/SystemUI/res/values-vi/strings_tv.xml +++ b/packages/SystemUI/res/values-vi/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"Đóng PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"Toàn màn hình"</string> <string name="pip_play" msgid="674145557658227044">"Phát"</string> <string name="pip_pause" msgid="8412075640017218862">"Tạm dừng"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"Giữ "<b>"HOME"</b>" để đ.khiển PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Nhấn và giữ nút HOME\nđể điều khiển PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml index 7f7108c821c7..74d787f58c7c 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"已抓取屏幕截图。"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"触摸可查看您的屏幕截图。"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"无法抓取屏幕截图。"</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"由于存储空间有限,无法保存屏幕截图。"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"此应用或贵单位不允许进行屏幕截图。"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB文件传输选项"</string> diff --git a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml index 2abd3387572d..860df351ded2 100644 --- a/packages/SystemUI/res/values-zh-rCN/strings_tv.xml +++ b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"关闭 PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"全屏"</string> <string name="pip_play" msgid="674145557658227044">"播放"</string> <string name="pip_pause" msgid="8412075640017218862">"暂停"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"按住"<b>"主屏幕"</b>"即可控制 PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"按住主屏幕\n按钮即可控制 PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"知道了"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml index 13a668218ab0..c7b2fffeea30 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings.xml @@ -73,6 +73,7 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"已擷取螢幕畫面。"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"輕觸即可查看螢幕擷取畫面。"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"無法擷取螢幕畫面。"</string> + <string name="screenshot_failed_to_save_unknown_text" msgid="7887826345701753830">"儲存螢幕擷圖時發生問題。"</string> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"由於儲存空間有限,因此無法儲存螢幕擷取畫面。"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"此應用程式或您的機構禁止擷取螢幕畫面。"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB 檔案傳輸選項"</string> @@ -510,9 +511,9 @@ <string name="headset" msgid="4534219457597457353">"耳機"</string> <string name="accessibility_status_bar_headphones" msgid="9156307120060559989">"已連接至耳機"</string> <string name="accessibility_status_bar_headset" msgid="8666419213072449202">"已連接至耳機"</string> - <string name="data_saver" msgid="5037565123367048522">"數據節省程式"</string> - <string name="accessibility_data_saver_on" msgid="8454111686783887148">"數據節省程式已開啟"</string> - <string name="accessibility_data_saver_off" msgid="8841582529453005337">"數據節省程式已關閉"</string> + <string name="data_saver" msgid="5037565123367048522">"數據節省模式"</string> + <string name="accessibility_data_saver_on" msgid="8454111686783887148">"數據節省模式已開啟"</string> + <string name="accessibility_data_saver_off" msgid="8841582529453005337">"數據節省模式已關閉"</string> <string name="switch_bar_on" msgid="1142437840752794229">"開啟"</string> <string name="switch_bar_off" msgid="8803270596930432874">"關閉"</string> <string name="nav_bar" msgid="1993221402773877607">"導覽列"</string> diff --git a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml index 8707d327dfb7..8e5a2df9743c 100644 --- a/packages/SystemUI/res/values-zh-rHK/strings_tv.xml +++ b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"關閉 PIP"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"全螢幕"</string> <string name="pip_play" msgid="674145557658227044">"播放"</string> <string name="pip_pause" msgid="8412075640017218862">"暫停"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"按住"<b>"主按鈕"</b>"即可控制 PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"按住主按鈕\n即可控制 PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"知道了"</string> </resources> diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml index e7172acd56ff..636f2fb87b17 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"已拍攝螢幕擷取畫面。"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"輕觸即可查看螢幕擷取畫面。"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"無法拍攝螢幕擷取畫面。"</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"由於儲存空間有限,因此無法儲存螢幕擷取畫面。"</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"這個應用程式或貴機構禁止擷取螢幕畫面。"</string> <string name="usb_preference_title" msgid="6551050377388882787">"USB 檔案傳輸選項"</string> diff --git a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml index 8707d327dfb7..60edac232e1f 100644 --- a/packages/SystemUI/res/values-zh-rTW/strings_tv.xml +++ b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml @@ -19,15 +19,11 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for pip_close (3480680679023423574) --> - <skip /> + <string name="pip_close" msgid="3480680679023423574">"關閉子母畫面"</string> <string name="pip_fullscreen" msgid="8604643018538487816">"全螢幕"</string> <string name="pip_play" msgid="674145557658227044">"播放"</string> <string name="pip_pause" msgid="8412075640017218862">"暫停"</string> - <!-- no translation found for pip_hold_home (340086535668778109) --> - <skip /> - <!-- no translation found for pip_onboarding_description (2627737116380318292) --> - <skip /> - <!-- no translation found for pip_onboarding_button (3957426748484904611) --> - <skip /> + <string name="pip_hold_home" msgid="340086535668778109">"按住「主畫面」"<b></b>"按鈕即可控制子母畫面"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"按住「主畫面」按鈕\n即可控制子母畫面"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"我知道了"</string> </resources> diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml index 5868b2a474c3..8d2a51bfa7bf 100644 --- a/packages/SystemUI/res/values-zu/strings.xml +++ b/packages/SystemUI/res/values-zu/strings.xml @@ -73,6 +73,8 @@ <string name="screenshot_saved_title" msgid="6461865960961414961">"Umfanekiso weskrini uqoshiwe"</string> <string name="screenshot_saved_text" msgid="1152839647677558815">"Thinta ukubona imifanekiso yakho yeskrini"</string> <string name="screenshot_failed_title" msgid="705781116746922771">"Yehlulekile ukulondoloza umfanekiso weskrini."</string> + <!-- no translation found for screenshot_failed_to_save_unknown_text (7887826345701753830) --> + <skip /> <string name="screenshot_failed_to_save_text" msgid="2592658083866306296">"Ayikwazi ukulondoloza isithombe-skrini ngenxa yesikhala sesitoreji esikhawulelwe."</string> <string name="screenshot_failed_to_capture_text" msgid="7602391003979898374">"Ukuthatha izithombe-skrini akuvunyelwe uhlelo lokusebenza noma inhlangano yakho."</string> <string name="usb_preference_title" msgid="6551050377388882787">"Okukhethwa kokudluliswa kwefayela ye-USB"</string> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 30acc72abae5..d65ab04b110f 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -165,4 +165,7 @@ <!-- Keyboard shortcuts colors --> <color name="ksh_system_group_color">#ff00bcd4</color> <color name="ksh_application_group_color">#fff44336</color> + + <!-- Background color of edit overflow --> + <color name="qs_edit_overflow_bg">#455A64</color> </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 7838fea7722c..8af413c4816c 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -185,7 +185,9 @@ <string name="screenshot_saved_text">Touch to view your screenshot.</string> <!-- Notification title displayed when we fail to take a screenshot. [CHAR LIMIT=50] --> <string name="screenshot_failed_title">Couldn\'t capture screenshot.</string> - <!-- Notification text displayed when we fail to take a screenshot. [CHAR LIMIT=100] --> + <!-- Notification text displayed when we fail to save a screenshot for unknown reasons. [CHAR LIMIT=100] --> + <string name="screenshot_failed_to_save_unknown_text">Problem encountered while saving screenshot.</string> + <!-- Notification text displayed when we fail to save a screenshot. [CHAR LIMIT=100] --> <string name="screenshot_failed_to_save_text">Can\'t save screenshot due to limited storage space.</string> <!-- Notification text displayed when we fail to take a screenshot. [CHAR LIMIT=100] --> <string name="screenshot_failed_to_capture_text">Taking screenshots is not allowed by the app or your organization.</string> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 89890d6d320d..2660926aa38b 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -339,4 +339,8 @@ <item name="android:colorAccent">@color/switch_accent_color</item> </style> + <style name="edit_theme" parent="@android:style/Theme.Material"> + <item name="android:colorBackground">@color/qs_edit_overflow_bg</item> + </style> + </resources> diff --git a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java index 051921aaf164..358674c809a3 100644 --- a/packages/SystemUI/src/com/android/systemui/ExpandHelper.java +++ b/packages/SystemUI/src/com/android/systemui/ExpandHelper.java @@ -78,6 +78,7 @@ public class ExpandHelper implements Gefingerpoken { private float mOldHeight; private float mNaturalHeight; private float mInitialTouchFocusY; + private float mInitialTouchX; private float mInitialTouchY; private float mInitialTouchSpan; private float mLastFocusY; @@ -291,7 +292,8 @@ public class ExpandHelper implements Gefingerpoken { } if (mWatchingForPull) { final float yDiff = ev.getRawY() - mInitialTouchY; - if (yDiff > mTouchSlop) { + final float xDiff = ev.getRawX() - mInitialTouchX; + if (yDiff > mTouchSlop && yDiff > Math.abs(xDiff)) { if (DEBUG) Log.v(TAG, "got venetian gesture (dy=" + yDiff + "px)"); mWatchingForPull = false; if (mResizedView != null && !isFullyExpanded(mResizedView)) { @@ -316,6 +318,7 @@ public class ExpandHelper implements Gefingerpoken { mWatchingForPull = false; } mInitialTouchY = ev.getY(); + mInitialTouchX = ev.getX(); break; case MotionEvent.ACTION_CANCEL: @@ -409,12 +412,14 @@ public class ExpandHelper implements Gefingerpoken { mWatchingForPull = mScrollAdapter != null && isInside(mScrollAdapter.getHostView(), x, y); mResizedView = findView(x, y); + mInitialTouchX = ev.getX(); mInitialTouchY = ev.getY(); break; case MotionEvent.ACTION_MOVE: { if (mWatchingForPull) { final float yDiff = ev.getRawY() - mInitialTouchY; - if (yDiff > mTouchSlop) { + final float xDiff = ev.getRawX() - mInitialTouchX; + if (yDiff > mTouchSlop && yDiff > Math.abs(xDiff)) { if (DEBUG) Log.v(TAG, "got venetian gesture (dy=" + yDiff + "px)"); mWatchingForPull = false; if (mResizedView != null && !isFullyExpanded(mResizedView)) { diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java index 1fe218a885fb..81ba23f27f23 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -517,35 +517,16 @@ public class SwipeHelper implements Gefingerpoken { break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: - if (mCurrView != null) { - float maxVelocity = MAX_DISMISS_VELOCITY * mDensityScale; - mVelocityTracker.computeCurrentVelocity(1000 /* px/sec */, maxVelocity); - float escapeVelocity = SWIPE_ESCAPE_VELOCITY * mDensityScale; - float velocity = getVelocity(mVelocityTracker); - float perpendicularVelocity = getPerpendicularVelocity(mVelocityTracker); - - float translation = getTranslation(mCurrView); - // Decide whether to dismiss the current view - boolean childSwipedFarEnough = DISMISS_IF_SWIPED_FAR_ENOUGH && - Math.abs(translation) > 0.4 * getSize(mCurrView); - boolean childSwipedFastEnough = (Math.abs(velocity) > escapeVelocity) && - (Math.abs(velocity) > Math.abs(perpendicularVelocity)) && - (velocity > 0) == (translation > 0); - boolean falsingDetected = mCallback.isAntiFalsingNeeded(); - - if (mFalsingManager.isClassiferEnabled()) { - falsingDetected = falsingDetected && mFalsingManager.isFalseTouch(); - } else { - falsingDetected = falsingDetected && !mTouchAboveFalsingThreshold; - } - - boolean dismissChild = mCallback.canChildBeDismissed(mCurrView) - && !falsingDetected && (childSwipedFastEnough || childSwipedFarEnough) - && ev.getActionMasked() == MotionEvent.ACTION_UP; + if (mCurrView == null) { + break; + } + mVelocityTracker.computeCurrentVelocity(1000 /* px/sec */, getMaxVelocity()); + float velocity = getVelocity(mVelocityTracker); - if (dismissChild) { + if (!handleUpEvent(ev, mCurrView, velocity, getTranslation(mCurrView))) { + if (isDismissGesture(ev)) { // flingadingy - dismissChild(mCurrView, childSwipedFastEnough ? velocity : 0f); + dismissChild(mCurrView, swipedFastEnough() ? velocity : 0f); } else { // snappity mCallback.onDragCancelled(mCurrView); @@ -562,6 +543,46 @@ public class SwipeHelper implements Gefingerpoken { return (int) (mFalsingThreshold * factor); } + private float getMaxVelocity() { + return MAX_DISMISS_VELOCITY * mDensityScale; + } + + protected float getEscapeVelocity() { + return SWIPE_ESCAPE_VELOCITY * mDensityScale; + } + + protected boolean swipedFarEnough() { + float translation = getTranslation(mCurrView); + return DISMISS_IF_SWIPED_FAR_ENOUGH && Math.abs(translation) > 0.4 * getSize(mCurrView); + } + + protected boolean isDismissGesture(MotionEvent ev) { + boolean falsingDetected = mCallback.isAntiFalsingNeeded(); + if (mFalsingManager.isClassiferEnabled()) { + falsingDetected = falsingDetected && mFalsingManager.isFalseTouch(); + } else { + falsingDetected = falsingDetected && !mTouchAboveFalsingThreshold; + } + return !falsingDetected && (swipedFastEnough() || swipedFarEnough()) + && ev.getActionMasked() == MotionEvent.ACTION_UP + && mCallback.canChildBeDismissed(mCurrView); + } + + protected boolean swipedFastEnough() { + float velocity = getVelocity(mVelocityTracker); + float perpendicularVelocity = getPerpendicularVelocity(mVelocityTracker); + float translation = getTranslation(mCurrView); + boolean ret = (Math.abs(velocity) > getEscapeVelocity()) && + (Math.abs(velocity) > Math.abs(perpendicularVelocity)) && + (velocity > 0) == (translation > 0); + return ret; + } + + protected boolean handleUpEvent(MotionEvent ev, View animView, float velocity, + float translation) { + return false; + } + public interface Callback { View getChildAtPosition(MotionEvent ev); diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java index 068efa6aaa37..72a59d7c16b1 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java +++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java @@ -25,6 +25,7 @@ import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.util.TypedValue; import android.view.ContextThemeWrapper; +import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; @@ -66,26 +67,11 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene private QSContainer mQsContainer; public QSCustomizer(Context context, AttributeSet attrs) { - super(new ContextThemeWrapper(context, android.R.style.Theme_Material), attrs); + super(new ContextThemeWrapper(context, R.style.edit_theme), attrs); mClipper = new QSDetailClipper(this); - } - - public void setHost(QSTileHost host) { - mHost = host; - mPhoneStatusBar = host.getPhoneStatusBar(); - } - - public void setContainer(NotificationsQuickSettingsContainer notificationsQsContainer) { - mNotifQsContainer = notificationsQsContainer; - } - public void setQsContainer(QSContainer qsContainer) { - mQsContainer = qsContainer; - } + LayoutInflater.from(getContext()).inflate(R.layout.qs_customize_panel_content, this); - @Override - protected void onFinishInflate() { - super.onFinishInflate(); mToolbar = (Toolbar) findViewById(com.android.internal.R.id.action_bar); TypedValue value = new TypedValue(); mContext.getTheme().resolveAttribute(android.R.attr.homeAsUpIndicator, value, true); @@ -115,6 +101,19 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene mRecyclerView.setItemAnimator(animator); } + public void setHost(QSTileHost host) { + mHost = host; + mPhoneStatusBar = host.getPhoneStatusBar(); + } + + public void setContainer(NotificationsQuickSettingsContainer notificationsQsContainer) { + mNotifQsContainer = notificationsQsContainer; + } + + public void setQsContainer(QSContainer qsContainer) { + mQsContainer = qsContainer; + } + public void show(int x, int y) { if (!isShown) { isShown = true; diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index 73ce26fecf29..2b6ed445a810 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -45,6 +45,7 @@ import com.android.systemui.R; import com.android.systemui.RecentsComponent; import com.android.systemui.SystemUI; import com.android.systemui.recents.events.EventBus; +import com.android.systemui.recents.events.activity.ConfigurationChangedEvent; import com.android.systemui.recents.events.activity.DockedTopTaskEvent; import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent; import com.android.systemui.recents.events.component.RecentsVisibilityChangedEvent; @@ -619,6 +620,12 @@ public class Recents extends SystemUI } } + public final void onBusEvent(ConfigurationChangedEvent event) { + // Update the configuration for the Recents component when the activity configuration + // changes as well + mImpl.onConfigurationChanged(); + } + /** * Attempts to register with the system user. */ diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java index 4e11bcaefc6a..d864df8331e1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java @@ -759,6 +759,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener TaskStackLayoutAlgorithm stackLayout = stackView.getStackAlgorithm(); TaskStackViewScroller stackScroller = stackView.getScroller(); + stackView.updateLayoutAlgorithm(true /* boundScroll */); stackView.updateToInitialState(); for (int i = tasks.size() - 1; i >= 0; i--) { @@ -825,6 +826,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener } // Get the transform for the running task + stackView.updateLayoutAlgorithm(true /* boundScroll */); stackView.updateToInitialState(); mTmpTransform = stackView.getStackAlgorithm().getStackTransformScreenCoordinates(launchTask, stackView.getScroller().getStackScroll(), mTmpTransform, null); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java index e2830a14d05c..6c410c3981c6 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -813,7 +813,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal * * @see #updateLayoutAlgorithm(boolean, ArraySet<Task.TaskKey>) */ - void updateLayoutAlgorithm(boolean boundScrollToNewMinMax) { + public void updateLayoutAlgorithm(boolean boundScrollToNewMinMax) { updateLayoutAlgorithm(boundScrollToNewMinMax, mIgnoreTasks); } @@ -822,7 +822,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal * * @param ignoreTasksSet the set of tasks to ignore in the relayout */ - void updateLayoutAlgorithm(boolean boundScrollToNewMinMax, + public void updateLayoutAlgorithm(boolean boundScrollToNewMinMax, ArraySet<Task.TaskKey> ignoreTasksSet) { // Compute the min and max scroll values mLayoutAlgorithm.update(mStack, ignoreTasksSet); diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index e64354ca1408..eb089471c992 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -93,13 +93,13 @@ class SaveImageInBackgroundData { /** * An AsyncTask that saves an image to the media store in the background. */ -class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Void, - SaveImageInBackgroundData> { +class SaveImageInBackgroundTask extends AsyncTask<Void, Void, Void> { private static final String SCREENSHOTS_DIR_NAME = "Screenshots"; private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png"; private static final String SCREENSHOT_SHARE_SUBJECT_TEMPLATE = "Screenshot (%s)"; + private final SaveImageInBackgroundData mParams; private final NotificationManager mNotificationManager; private final Notification.Builder mNotificationBuilder, mPublicNotificationBuilder; private final File mScreenshotDir; @@ -122,6 +122,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi Resources r = context.getResources(); // Prepare all the output metadata + mParams = data; mImageTime = System.currentTimeMillis(); String imageDate = new SimpleDateFormat("yyyyMMdd-HHmmss").format(new Date(mImageTime)); mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate); @@ -210,17 +211,17 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi } @Override - protected SaveImageInBackgroundData doInBackground(SaveImageInBackgroundData... params) { + protected Void doInBackground(Void... params) { if (isCancelled()) { - return params[0]; + return null; } // By default, AsyncTask sets the worker thread to have background thread priority, so bump // it back up so that we save a little quicker. Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); - Context context = params[0].context; - Bitmap image = params[0].image; + Context context = mParams.context; + Bitmap image = mParams.image; Resources r = context.getResources(); try { @@ -284,14 +285,14 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi r.getString(com.android.internal.R.string.delete), deleteAction); mNotificationBuilder.addAction(deleteActionBuilder.build()); - params[0].imageUri = uri; - params[0].image = null; - params[0].errorMsgResId = 0; + mParams.imageUri = uri; + mParams.image = null; + mParams.errorMsgResId = 0; } catch (Exception e) { // IOException/UnsupportedOperationException may be thrown if external storage is not // mounted - params[0].clearImage(); - params[0].errorMsgResId = R.string.screenshot_failed_to_save_text; + mParams.clearImage(); + mParams.errorMsgResId = R.string.screenshot_failed_to_save_text; } // Recycle the bitmap data @@ -299,23 +300,23 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi image.recycle(); } - return params[0]; + return null; } @Override - protected void onPostExecute(SaveImageInBackgroundData params) { - if (params.errorMsgResId != 0) { + protected void onPostExecute(Void params) { + if (mParams.errorMsgResId != 0) { // Show a message that we've failed to save the image to disk - GlobalScreenshot.notifyScreenshotError(params.context, mNotificationManager, - params.errorMsgResId); + GlobalScreenshot.notifyScreenshotError(mParams.context, mNotificationManager, + mParams.errorMsgResId); } else { // Show the final notification to indicate screenshot saved - Context context = params.context; + Context context = mParams.context; Resources r = context.getResources(); // Create the intent to show the screenshot in gallery Intent launchIntent = new Intent(Intent.ACTION_VIEW); - launchIntent.setDataAndType(params.imageUri, "image/png"); + launchIntent.setDataAndType(mParams.imageUri, "image/png"); launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); final long now = System.currentTimeMillis(); @@ -324,7 +325,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi mPublicNotificationBuilder .setContentTitle(r.getString(R.string.screenshot_saved_title)) .setContentText(r.getString(R.string.screenshot_saved_text)) - .setContentIntent(PendingIntent.getActivity(params.context, 0, launchIntent, 0)) + .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0)) .setWhen(now) .setAutoCancel(true) .setColor(context.getColor( @@ -332,7 +333,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi mNotificationBuilder .setContentTitle(r.getString(R.string.screenshot_saved_title)) .setContentText(r.getString(R.string.screenshot_saved_text)) - .setContentIntent(PendingIntent.getActivity(params.context, 0, launchIntent, 0)) + .setContentIntent(PendingIntent.getActivity(mParams.context, 0, launchIntent, 0)) .setWhen(now) .setAutoCancel(true) .setColor(context.getColor( @@ -342,15 +343,18 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi mNotificationManager.notify(R.id.notification_screenshot, mNotificationBuilder.build()); } - params.finisher.run(); - params.clearContext(); + mParams.finisher.run(); + mParams.clearContext(); } @Override - protected void onCancelled(SaveImageInBackgroundData params) { - params.finisher.run(); - params.clearImage(); - params.clearContext(); + protected void onCancelled(Void params) { + // If we are cancelled while the task is running in the background, we may get null params. + // The finisher is expected to always be called back, so just use the baked-in params from + // the ctor in any case. + mParams.finisher.run(); + mParams.clearImage(); + mParams.clearContext(); // Cancel the posted notification mNotificationManager.cancel(R.id.notification_screenshot); @@ -419,7 +423,7 @@ class GlobalScreenshot { private float mBgPadding; private float mBgPaddingScale; - private AsyncTask<SaveImageInBackgroundData, Void, SaveImageInBackgroundData> mSaveInBgTask; + private AsyncTask<Void, Void, Void> mSaveInBgTask; private MediaActionSound mCameraSound; @@ -510,7 +514,7 @@ class GlobalScreenshot { mSaveInBgTask.cancel(false); } mSaveInBgTask = new SaveImageInBackgroundTask(mContext, data, mNotificationManager) - .execute(data); + .execute(); } /** diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java new file mode 100644 index 000000000000..fc2a1e47253c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotServiceErrorReceiver.java @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.systemui.screenshot; + +import android.app.NotificationManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import com.android.systemui.R; + +/** + * Performs a number of miscellaneous, non-system-critical actions + * after the system has finished booting. + */ +public class ScreenshotServiceErrorReceiver extends BroadcastReceiver { + + @Override + public void onReceive(final Context context, Intent intent) { + // Show a message that we've failed to save the image to disk + NotificationManager nm = (NotificationManager) + context.getSystemService(Context.NOTIFICATION_SERVICE); + GlobalScreenshot.notifyScreenshotError(context, nm, + R.string.screenshot_failed_to_save_unknown_text); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index 51553be35c51..93cb952b1eb7 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java @@ -241,18 +241,22 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { } private void updateLimits() { - boolean customView = getPrivateLayout().getContractedChild().getId() + updateLimitsForView(mPrivateLayout); + updateLimitsForView(mPublicLayout); + } + + private void updateLimitsForView(NotificationContentView layout) { + boolean customView = layout.getContractedChild().getId() != com.android.internal.R.id.status_bar_latest_event_content; boolean beforeN = mEntry.targetSdk < Build.VERSION_CODES.N; int minHeight = customView && beforeN && !mIsSummaryWithChildren ? mNotificationMinHeightLegacy : mNotificationMinHeight; - boolean headsUpCustom = getPrivateLayout().getHeadsUpChild() != null && - getPrivateLayout().getHeadsUpChild().getId() - != com.android.internal.R.id.status_bar_latest_event_content; + boolean headsUpCustom = layout.getHeadsUpChild() != null && + layout.getHeadsUpChild().getId() + != com.android.internal.R.id.status_bar_latest_event_content; int headsUpheight = headsUpCustom && beforeN ? mMaxHeadsUpHeightLegacy : mMaxHeadsUpHeight; - mPrivateLayout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight); - mPublicLayout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight); + layout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight); } public StatusBarNotification getStatusBarNotification() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java index 375459f0f30c..fcc48bf8d510 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java @@ -29,11 +29,18 @@ import com.android.systemui.R; public class NotificationSettingsIconRow extends FrameLayout implements View.OnClickListener { + private static final int GEAR_ALPHA_ANIM_DURATION = 200; + public interface SettingsIconRowListener { /** * Called when the gear behind a notification is touched. */ public void onGearTouched(ExpandableNotificationRow row, int x, int y); + + /** + * Called when a notification is slid back over the gear. + */ + public void onSettingsIconRowReset(NotificationSettingsIconRow row); } private ExpandableNotificationRow mParent; @@ -45,6 +52,8 @@ public class NotificationSettingsIconRow extends FrameLayout implements View.OnC private boolean mSettingsFadedIn = false; private boolean mAnimating = false; private boolean mOnLeft = true; + private boolean mDismissing = false; + private boolean mSnapping = false; private int[] mGearLocation = new int[2]; private int[] mParentLocation = new int[2]; @@ -78,8 +87,14 @@ public class NotificationSettingsIconRow extends FrameLayout implements View.OnC public void resetState() { setGearAlpha(0f); + mSettingsFadedIn = false; mAnimating = false; + mSnapping = false; + mDismissing = false; setIconLocation(true /* on left */); + if (mListener != null) { + mListener.onSettingsIconRowReset(this); + } } public void setGearListener(SettingsIconRowListener listener) { @@ -94,20 +109,24 @@ public class NotificationSettingsIconRow extends FrameLayout implements View.OnC return mParent; } - private void setGearAlpha(float alpha) { + public void setGearAlpha(float alpha) { if (alpha == 0) { mSettingsFadedIn = false; // Can fade in again once it's gone. setVisibility(View.INVISIBLE); } else { - if (alpha == 1) { - mSettingsFadedIn = true; - } setVisibility(View.VISIBLE); } mGearIcon.setAlpha(alpha); } /** + * Returns whether the icon is on the left side of the view or not. + */ + public boolean isIconOnLeft() { + return mOnLeft; + } + + /** * Returns the horizontal space in pixels required to display the gear behind a notification. */ public float getSpaceForGear() { @@ -119,7 +138,7 @@ public class NotificationSettingsIconRow extends FrameLayout implements View.OnC * if entire view is visible. */ public boolean isVisible() { - return mSettingsFadedIn; + return mGearIcon.getAlpha() > 0; } public void cancelFadeAnimator() { @@ -129,16 +148,18 @@ public class NotificationSettingsIconRow extends FrameLayout implements View.OnC } public void updateSettingsIcons(final float transX, final float size) { - if (mAnimating || (mGearIcon.getAlpha() == 0)) { - // Don't adjust when animating or settings aren't visible + if (mAnimating || !mSettingsFadedIn) { + // Don't adjust when animating, or if the gear hasn't been shown yet. return; } - setIconLocation(transX > 0 /* fromLeft */); + final float fadeThreshold = size * 0.3f; final float absTrans = Math.abs(transX); float desiredAlpha = 0; - if (absTrans <= fadeThreshold) { + if (absTrans == 0) { + desiredAlpha = 0; + } else if (absTrans <= fadeThreshold) { desiredAlpha = 1; } else { desiredAlpha = 1 - ((absTrans - fadeThreshold) / (size - fadeThreshold)); @@ -148,6 +169,12 @@ public class NotificationSettingsIconRow extends FrameLayout implements View.OnC public void fadeInSettings(final boolean fromLeft, final float transX, final float notiThreshold) { + if (mDismissing || mAnimating) { + return; + } + if (isIconLocationChange(transX)) { + setGearAlpha(0f); + } setIconLocation(transX > 0 /* fromLeft */); mFadeAnimator = ValueAnimator.ofFloat(mGearIcon.getAlpha(), 1); mFadeAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @@ -164,40 +191,53 @@ public class NotificationSettingsIconRow extends FrameLayout implements View.OnC }); mFadeAnimator.addListener(new AnimatorListenerAdapter() { @Override - public void onAnimationCancel(Animator animation) { - super.onAnimationCancel(animation); - mAnimating = false; - mSettingsFadedIn = false; + public void onAnimationStart(Animator animation) { + mAnimating = true; } @Override - public void onAnimationStart(Animator animation) { - super.onAnimationStart(animation); - mAnimating = true; + public void onAnimationCancel(Animator animation) { + // TODO should animate back to 0f from current alpha + mGearIcon.setAlpha(0f); } @Override public void onAnimationEnd(Animator animation) { - super.onAnimationEnd(animation); mAnimating = false; - mSettingsFadedIn = true; + mSettingsFadedIn = mGearIcon.getAlpha() == 1; } }); mFadeAnimator.setInterpolator(Interpolators.ALPHA_IN); - mFadeAnimator.setDuration(200); + mFadeAnimator.setDuration(GEAR_ALPHA_ANIM_DURATION); mFadeAnimator.start(); } - private void setIconLocation(boolean onLeft) { - if (onLeft == mOnLeft) { + public void setIconLocation(boolean onLeft) { + if (onLeft == mOnLeft || mSnapping) { // Same side? Do nothing. return; } - setTranslationX(onLeft ? 0 : (mParent.getWidth() - mHorizSpaceForGear)); mOnLeft = onLeft; } + public boolean isIconLocationChange(float translation) { + boolean onLeft = translation > mGearIcon.getPaddingStart(); + boolean onRight = translation < -mGearIcon.getPaddingStart(); + if ((mOnLeft && onRight) || (!mOnLeft && onLeft)) { + return true; + } + return false; + } + + public void setDismissing() { + mDismissing = true; + } + + public void setSnapping(boolean snapping) { + mSnapping = snapping; + } + @Override public void onClick(View v) { if (v.getId() == R.id.gear_icon) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java index 66f945ea83fa..f75f357421f8 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ViewTransformationHelper.java @@ -188,6 +188,9 @@ public class ViewTransformationHelper implements TransformableView { @Override public void setVisible(boolean visible) { + if (mViewTransformationAnimation != null) { + mViewTransformationAnimation.cancel(); + } for (Integer viewType : mTransformedViews.keySet()) { TransformState ownState = getCurrentState(viewType); if (ownState != null) { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java index cedc3c7eef2f..ab44b6a277ee 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java @@ -315,8 +315,8 @@ public class UserSwitcherController { public void logoutCurrentUser() { int currentUser = ActivityManager.getCurrentUser(); if (currentUser != UserHandle.USER_SYSTEM) { - switchToUserId(UserHandle.USER_SYSTEM); - stopUserId(currentUser); + pauseRefreshUsers(); + ActivityManager.logoutCurrentUser(); } } @@ -384,14 +384,6 @@ public class UserSwitcherController { } } - private void stopUserId(int id) { - try { - ActivityManagerNative.getDefault().stopUser(id, /* force= */ false, null); - } catch (RemoteException e) { - Log.e(TAG, "Couldn't stop user.", e); - } - } - private void showExitGuestDialog(int id) { if (mExitGuestDialog != null && mExitGuestDialog.isShowing()) { mExitGuestDialog.cancel(); 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 2da47874b49b..d9b78a2f09fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -372,6 +372,11 @@ public class NotificationStackScrollLayout extends ViewGroup } @Override + public void onSettingsIconRowReset(NotificationSettingsIconRow row) { + mSwipeHelper.setSnappedToGear(false); + } + + @Override protected void onDraw(Canvas canvas) { canvas.drawRect(0, mCurrentBounds.top, getWidth(), mCurrentBounds.bottom, mBackgroundPaint); if (DEBUG) { @@ -717,11 +722,15 @@ public class NotificationStackScrollLayout extends ViewGroup mDragAnimPendingChildren.remove(animView); } - if (targetLeft == 0 && mCurrIconRow != null) { - mCurrIconRow.resetState(); - mCurrIconRow = null; - if (mGearExposedView != null && mGearExposedView == mTranslatingParentView) { - mGearExposedView = null; + if (mCurrIconRow != null) { + if (targetLeft == 0) { + mCurrIconRow.resetState(); + mCurrIconRow = null; + if (mGearExposedView != null && mGearExposedView == mTranslatingParentView) { + mGearExposedView = null; + } + } else { + mSwipeHelper.setSnappedToGear(true); } } } @@ -2730,13 +2739,13 @@ public class NotificationStackScrollLayout extends ViewGroup if (view instanceof ExpandableNotificationRow) { ExpandableNotificationRow row = (ExpandableNotificationRow) view; if (row.isUserLocked() && row != getFirstChildNotGone()) { + if (row.isSummaryWithChildren()) { + return; + } // We are actually expanding this view - float endPosition; + float endPosition = row.getTranslationY() + row.getActualHeight(); if (row.isChildInGroup()) { - ExpandableNotificationRow parent = row.getNotificationParent(); - endPosition = parent.getTranslationY() + parent.getActualHeight(); - } else { - endPosition = row.getTranslationY() + row.getActualHeight(); + endPosition += row.getNotificationParent().getTranslationY(); } int stackEnd = mMaxLayoutHeight - mBottomStackPeekSize - mBottomStackSlowDownHeight + (int) mStackTranslation; @@ -3379,15 +3388,11 @@ public class NotificationStackScrollLayout extends ViewGroup } private class NotificationSwipeHelper extends SwipeHelper { - private static final int MOVE_STATE_LEFT = -1; - private static final int MOVE_STATE_UNDEFINED = 0; - private static final int MOVE_STATE_RIGHT = 1; - private static final long GEAR_SHOW_DELAY = 60; - private CheckForDrag mCheckForDrag; private Handler mHandler; - private int mMoveState = MOVE_STATE_UNDEFINED; + private boolean mGearSnappedTo; + private boolean mGearSnappedOnLeft; public NotificationSwipeHelper(int swipeDirection, Callback callback, Context context) { super(swipeDirection, callback, context); @@ -3400,6 +3405,10 @@ public class NotificationStackScrollLayout extends ViewGroup mTranslatingParentView = currView; // Reset check for drag gesture + cancelCheckForDrag(); + if (mCurrIconRow != null) { + mCurrIconRow.setSnapping(false); + } mCheckForDrag = null; mCurrIconRow = null; @@ -3411,17 +3420,32 @@ public class NotificationStackScrollLayout extends ViewGroup mCurrIconRow = ((ExpandableNotificationRow) currView).getSettingsRow(); mCurrIconRow.setGearListener(NotificationStackScrollLayout.this); } - mMoveState = MOVE_STATE_UNDEFINED; } @Override public void onMoveUpdate(View view, float translation, float delta) { - final int newMoveState = (delta < 0) ? MOVE_STATE_RIGHT : MOVE_STATE_LEFT; - if (mMoveState != MOVE_STATE_UNDEFINED && mMoveState != newMoveState) { - // Changed directions, make sure we check for drag again. - mCheckForDrag = null; + if (mCurrIconRow != null) { + mCurrIconRow.setSnapping(false); // If we're moving, we're not snapping. + + // If the gear is visible and the movement is towards it it's not a location change. + boolean onLeft = mGearSnappedTo ? mGearSnappedOnLeft : mCurrIconRow.isIconOnLeft(); + boolean locationChange = isTowardsGear(translation, onLeft) + ? false : mCurrIconRow.isIconLocationChange(translation); + if (locationChange) { + // Don't consider it "snapped" if location has changed. + setSnappedToGear(false); + + // Changed directions, make sure we check to fade in icon again. + if (!mHandler.hasCallbacks(mCheckForDrag)) { + // No check scheduled, set null to schedule a new one. + mCheckForDrag = null; + } else { + // Check scheduled, reset alpha and update location; check will fade it in + mCurrIconRow.setGearAlpha(0f); + mCurrIconRow.setIconLocation(translation > 0 /* onLeft */); + } + } } - mMoveState = newMoveState; final boolean gutsExposed = (view instanceof ExpandableNotificationRow) && ((ExpandableNotificationRow) view).areGutsExposed(); @@ -3434,35 +3458,101 @@ public class NotificationStackScrollLayout extends ViewGroup @Override public void dismissChild(final View view, float velocity) { - cancelCheckForDrag(); super.dismissChild(view, velocity); + cancelCheckForDrag(); + setSnappedToGear(false); } @Override public void snapChild(final View animView, final float targetLeft, float velocity) { + super.snapChild(animView, targetLeft, velocity); + onDragCancelled(animView); + if (targetLeft == 0) { + cancelCheckForDrag(); + setSnappedToGear(false); + } + } + + + @Override + public boolean handleUpEvent(MotionEvent ev, View animView, float velocity, + float translation) { + if (mCurrIconRow == null) { + cancelCheckForDrag(); + return false; // Let SwipeHelper handle it. + } + + boolean gestureTowardsGear = isTowardsGear(velocity, mCurrIconRow.isIconOnLeft()); + boolean gestureFastEnough = Math.abs(velocity) > getEscapeVelocity(); + + if (mGearSnappedTo && mCurrIconRow.isVisible()) { + if (mGearSnappedOnLeft == mCurrIconRow.isIconOnLeft()) { + boolean coveringGear = + Math.abs(getTranslation(animView)) <= getSpaceForGear(animView) * 0.6f; + if (gestureTowardsGear || coveringGear) { + // Gesture is towards or covering the gear + snapChild(animView, 0 /* leftTarget */, velocity); + } else if (isDismissGesture(ev)) { + // Gesture is a dismiss that's not towards the gear + dismissChild(animView, swipedFastEnough() ? velocity : 0f); + } else { + // Didn't move enough to dismiss or cover, snap to the gear + snapToGear(animView, velocity); + } + } else if ((!gestureFastEnough && swipedEnoughToShowGear(animView)) + || (gestureTowardsGear && !swipedFarEnough())) { + // The gear has been snapped to previously, however, the gear is now on the + // other side. If gesture is towards gear and not too far snap to the gear. + snapToGear(animView, velocity); + } else { + dismissOrSnapBack(animView, velocity, ev); + } + } else if ((!gestureFastEnough && swipedEnoughToShowGear(animView)) + || gestureTowardsGear) { + // Gear has not been snapped to previously and this is gear revealing gesture + snapToGear(animView, velocity); + } else { + dismissOrSnapBack(animView, velocity, ev); + } + return true; + } + + private void dismissOrSnapBack(View animView, float velocity, MotionEvent ev) { + if (isDismissGesture(ev)) { + dismissChild(animView, swipedFastEnough() ? velocity : 0f); + } else { + snapChild(animView, 0 /* leftTarget */, velocity); + } + } + + private void snapToGear(View animView, float velocity) { + final float snapBackThreshold = getSpaceForGear(animView); + final float target = mCurrIconRow.isIconOnLeft() ? snapBackThreshold + : -snapBackThreshold; + mGearExposedView = mTranslatingParentView; + if (mGearDisplayedListener != null + && (animView instanceof ExpandableNotificationRow)) { + mGearDisplayedListener.onGearDisplayed((ExpandableNotificationRow) animView); + } + if (mCurrIconRow != null) { + mCurrIconRow.setSnapping(true); + setSnappedToGear(true); + } + onDragCancelled(animView); + super.snapChild(animView, target, velocity); + } + + private boolean swipedEnoughToShowGear(View animView) { final float snapBackThreshold = getSpaceForGear(animView); final float translation = getTranslation(animView); final boolean fromLeft = translation > 0; final float absTrans = Math.abs(translation); final float notiThreshold = getSize(mTranslatingParentView) * 0.4f; - boolean pastGear = (fromLeft && translation >= snapBackThreshold * 0.4f - && translation <= notiThreshold) || - (!fromLeft && absTrans >= snapBackThreshold * 0.4f - && absTrans <= notiThreshold); - - if (pastGear && !isPinnedHeadsUp(animView) - && (animView instanceof ExpandableNotificationRow)) { - // bouncity - final float target = fromLeft ? snapBackThreshold : -snapBackThreshold; - mGearExposedView = mTranslatingParentView; - if (mGearDisplayedListener != null) { - mGearDisplayedListener.onGearDisplayed((ExpandableNotificationRow) animView); - } - super.snapChild(animView, target, velocity); - } else { - super.snapChild(animView, 0, velocity); - } + // If the notification can't be dismissed then how far it can move is + // restricted -- reduce the distance it needs to move in this case. + final float multiplier = canChildBeDismissed(animView) ? 0.4f : 0.2f; + return absTrans >= snapBackThreshold * 0.4f && absTrans <= notiThreshold; } @Override @@ -3499,6 +3589,25 @@ public class NotificationStackScrollLayout extends ViewGroup } /** + * Returns whether the gesture is towards the gear location or not. + */ + private boolean isTowardsGear(float velocity, boolean onLeft) { + if (mCurrIconRow == null) { + return false; + } + return mCurrIconRow.isVisible() + && ((onLeft && velocity <= 0) || (!onLeft && velocity >= 0)); + } + + /** + * Indicates the the gear has been snapped to. + */ + private void setSnappedToGear(boolean snapped) { + mGearSnappedOnLeft = (mCurrIconRow != null) ? mCurrIconRow.isIconOnLeft() : false; + mGearSnappedTo = snapped && mCurrIconRow != null; + } + + /** * Returns the horizontal space in pixels required to display the gear behind a * notification. */ @@ -3510,7 +3619,7 @@ public class NotificationStackScrollLayout extends ViewGroup } private void checkForDrag() { - if (mCheckForDrag == null) { + if (mCheckForDrag == null || !mHandler.hasCallbacks(mCheckForDrag)) { mCheckForDrag = new CheckForDrag(); mHandler.postDelayed(mCheckForDrag, GEAR_SHOW_DELAY); } @@ -3521,7 +3630,6 @@ public class NotificationStackScrollLayout extends ViewGroup mCurrIconRow.cancelFadeAnimator(); } mHandler.removeCallbacks(mCheckForDrag); - mCheckForDrag = null; } private final class CheckForDrag implements Runnable { @@ -3531,14 +3639,13 @@ public class NotificationStackScrollLayout extends ViewGroup final float absTransX = Math.abs(translation); final float bounceBackToGearWidth = getSpaceForGear(mTranslatingParentView); final float notiThreshold = getSize(mTranslatingParentView) * 0.4f; - if (mCurrIconRow != null && absTransX >= bounceBackToGearWidth * 0.4 + if ((mCurrIconRow != null && (!mCurrIconRow.isVisible() + || mCurrIconRow.isIconLocationChange(translation))) + && absTransX >= bounceBackToGearWidth * 0.4 && absTransX < notiThreshold) { - // Show icon + // Fade in the gear mCurrIconRow.fadeInSettings(translation > 0 /* fromLeft */, translation, notiThreshold); - } else { - // Allow more to be posted if this wasn't a drag. - mCheckForDrag = null; } } } @@ -3551,7 +3658,7 @@ public class NotificationStackScrollLayout extends ViewGroup final View prevGearExposedView = mGearExposedView; mGearExposedView = null; - + mGearSnappedTo = false; Animator anim = getViewTranslationAnimator(prevGearExposedView, 0 /* leftTarget */, null /* updateListener */); if (anim != null) { diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java index 3ac81f65797f..562d95065cd8 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java @@ -63,14 +63,6 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen void onDoubleTapAndHold(MotionEvent event, int policyFlags); /** - * Called when the user touches the screen on the second tap of a double - * tap. - * - * @return true if the event is consumed, else false - */ - boolean onDoubleTapStarted(); - - /** * Called when the user lifts their finger on the second tap of a double * tap. * @@ -246,13 +238,20 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen mBaseY = y; mBaseTime = time; + // Since the pointer has moved, this is not a double + // tap. + mFirstTapDetected = false; + mDoubleTapDetected = false; + // If this hasn't been confirmed as a gesture yet, send // the event. if (!mGestureStarted) { mGestureStarted = true; return mListener.onGestureStarted(); } - } else { + } else if (!mFirstTapDetected) { + // The finger may not move if they are double tapping. + // In that case, we shouldn't cancel the gesture. final long timeDelta = time - mBaseTime; final long threshold = mGestureStarted ? CANCEL_ON_PAUSE_THRESHOLD_STARTED_MS : @@ -371,7 +370,7 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen // The processing of the double tap is deferred until the finger is // lifted, so that we can detect a long press on the second tap. mDoubleTapDetected = true; - return mListener.onDoubleTapStarted(); + return false; } private void maybeSendLongPress(MotionEvent event, int policyFlags) { diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java index cd8b792449cc..3cc991cab65d 100644 --- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java +++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java @@ -390,11 +390,6 @@ class TouchExplorer implements EventStreamTransformation, AccessibilityGestureDe } @Override - public boolean onDoubleTapStarted() { - return true; - } - - @Override public boolean onDoubleTap(MotionEvent event, int policyFlags) { // Ignore the event if we aren't touch exploring. if (mCurrentState != STATE_TOUCH_EXPLORING) { diff --git a/services/core/java/com/android/server/AppOpsService.java b/services/core/java/com/android/server/AppOpsService.java index 32f2d593f670..bfe9e8e74122 100644 --- a/services/core/java/com/android/server/AppOpsService.java +++ b/services/core/java/com/android/server/AppOpsService.java @@ -25,6 +25,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; @@ -57,6 +58,7 @@ import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; import android.util.Log; +import android.util.Pair; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; @@ -107,8 +109,21 @@ public class AppOpsService extends IAppOpsService.Stub { private final SparseArray<UidState> mUidStates = new SparseArray<>(); - /** These are app op restrictions imposed per user from various parties */ - private final ArrayMap<IBinder, SparseArray<boolean[]>> mOpUserRestrictions = new ArrayMap<>(); + /* + * These are app op restrictions imposed per user from various parties. + * + * This is organized as follows: + * + * ArrayMap w/ mapping: + * IBinder (for client imposing restriction) --> SparseArray w/ mapping: + * User handle --> Pair containing: + * - Array w/ index = AppOp code, value = restricted status boolean + * - SparseArray w/ mapping: + * AppOp code --> Set of packages that are not restricted for this code + * + */ + private final ArrayMap<IBinder, SparseArray<Pair<boolean[], SparseArray<ArraySet<String>>>>> + mOpUserRestrictions = new ArrayMap<>(); private static final class UidState { public final int uid; @@ -1267,11 +1282,35 @@ public class AppOpsService extends IAppOpsService.Stub { private boolean isOpRestricted(int uid, int code, String packageName) { int userHandle = UserHandle.getUserId(uid); final int restrictionSetCount = mOpUserRestrictions.size(); + for (int i = 0; i < restrictionSetCount; i++) { - SparseArray<boolean[]> perUserRestrictions = mOpUserRestrictions.valueAt(i); - boolean[] opRestrictions = perUserRestrictions.get(userHandle); - if (opRestrictions != null && opRestrictions[code]) { + // For each client, check that the given op is not restricted, or that the given + // package is exempt from the restriction. + + SparseArray<Pair<boolean[],SparseArray<ArraySet<String>>>> perUserRestrictions = + mOpUserRestrictions.valueAt(i); + + Pair<boolean[],SparseArray<ArraySet<String>>> restrictions = + perUserRestrictions.get(userHandle); + if (restrictions == null) { + continue; // No restrictions set by this client + } + + boolean[] opRestrictions = restrictions.first; + SparseArray<ArraySet<String>> opExceptions = restrictions.second; + + if (opRestrictions == null) { + continue; // No restrictions set by this client + } + + if (opRestrictions[code]) { + if (opExceptions != null && opExceptions.get(code) != null && + opExceptions.get(code).contains(packageName)) { + continue; // AppOps code is restricted, but this package is exempt + } + if (AppOpsManager.opAllowSystemBypassRestriction(code)) { + // If we are the system, bypass user restrictions for certain codes synchronized (this) { Ops ops = getOpsLocked(uid, packageName, true); if ((ops != null) && ops.isPrivileged) { @@ -1279,6 +1318,7 @@ public class AppOpsService extends IAppOpsService.Stub { } } } + return true; } } @@ -2069,7 +2109,8 @@ public class AppOpsService extends IAppOpsService.Stub { } @Override - public void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle) { + public void setUserRestriction(int code, boolean restricted, IBinder token, int userHandle, + String[] exceptionPackages) { if (Binder.getCallingPid() != Process.myPid()) { mContext.enforcePermission(Manifest.permission.MANAGE_APP_OPS_RESTRICTIONS, Binder.getCallingPid(), Binder.getCallingUid(), null); @@ -2085,12 +2126,37 @@ public class AppOpsService extends IAppOpsService.Stub { } verifyIncomingOp(code); Preconditions.checkNotNull(token); - setUserRestrictionNoCheck(code, restricted, token, userHandle); + setUserRestrictionNoCheck(code, restricted, token, userHandle, exceptionPackages); } private void setUserRestrictionNoCheck(int code, boolean restricted, IBinder token, int userHandle) { + setUserRestrictionNoCheck(code, restricted, token, userHandle, /*exceptionPackages*/null); + } + + private void setUserRestrictionNoCheck(int code, boolean restricted, IBinder token, + int userHandle, String[] exceptionPackages) { + final boolean[] opRestrictions = getOrCreateUserRestrictionsForToken(token, userHandle); + + if (restricted) { + final SparseArray<ArraySet<String>> opExceptions = + getUserPackageExemptionsForToken(token, userHandle); + + // If exceptionPackages is not null, update the exception packages for this AppOps code + ArraySet<String> exceptions = opExceptions.get(code); + if (exceptionPackages != null) { + if (exceptions == null) { + exceptions = new ArraySet<>(exceptionPackages.length); + opExceptions.put(code, exceptions); + } else { + exceptions.clear(); + } + + exceptions.addAll(Arrays.asList(exceptionPackages)); + } + } + if (opRestrictions[code] == restricted) { return; } @@ -2132,7 +2198,8 @@ public class AppOpsService extends IAppOpsService.Stub { checkSystemUid("removeUser"); final int tokenCount = mOpUserRestrictions.size(); for (int i = tokenCount - 1; i >= 0; i--) { - SparseArray<boolean[]> opRestrictions = mOpUserRestrictions.valueAt(i); + SparseArray<Pair<boolean[], SparseArray<ArraySet<String>>>> opRestrictions = + mOpUserRestrictions.valueAt(i); if (opRestrictions != null) { opRestrictions.remove(userHandle); if (opRestrictions.size() <= 0) { @@ -2144,15 +2211,23 @@ public class AppOpsService extends IAppOpsService.Stub { private void pruneUserRestrictionsForToken(IBinder token, int userHandle) { - SparseArray<boolean[]> perTokenRestrictions = mOpUserRestrictions.get(token); + SparseArray<Pair<boolean[], SparseArray<ArraySet<String>>>> perTokenRestrictions = + mOpUserRestrictions.get(token); if (perTokenRestrictions != null) { - final boolean[] opRestrictions = perTokenRestrictions.get(userHandle); - if (opRestrictions != null) { - for (boolean restriction : opRestrictions) { - if (restriction) { - return; + final Pair<boolean[], SparseArray<ArraySet<String>>> restrictions = + perTokenRestrictions.get(userHandle); + + if (restrictions != null) { + final boolean[] opRestrictions = restrictions.first; + if (opRestrictions != null) { + for (boolean restriction : opRestrictions) { + if (restriction) { + return; + } } } + + // No restrictions set for this client perTokenRestrictions.remove(userHandle); if (perTokenRestrictions.size() <= 0) { mOpUserRestrictions.remove(token); @@ -2161,18 +2236,61 @@ public class AppOpsService extends IAppOpsService.Stub { } } + /** + * Get or create the user restrictions array for a given client if it doesn't already exist. + * + * @param token the binder client creating the restriction. + * @param userHandle the user handle to create a restriction for. + * + * @return the array of restriction states for each AppOps code. + */ private boolean[] getOrCreateUserRestrictionsForToken(IBinder token, int userHandle) { - SparseArray<boolean[]> perTokenRestrictions = mOpUserRestrictions.get(token); + SparseArray<Pair<boolean[], SparseArray<ArraySet<String>>>> perTokenRestrictions = + mOpUserRestrictions.get(token); + if (perTokenRestrictions == null) { - perTokenRestrictions = new SparseArray<>(); + perTokenRestrictions = + new SparseArray<Pair<boolean[], SparseArray<ArraySet<String>>>>(); mOpUserRestrictions.put(token, perTokenRestrictions); } - boolean[] opRestrictions = perTokenRestrictions.get(userHandle); - if (opRestrictions == null) { - opRestrictions = new boolean[AppOpsManager._NUM_OP]; - perTokenRestrictions.put(userHandle, opRestrictions); + + Pair<boolean[], SparseArray<ArraySet<String>>> restrictions = + perTokenRestrictions.get(userHandle); + + if (restrictions == null) { + restrictions = new Pair<boolean[], SparseArray<ArraySet<String>>>( + new boolean[AppOpsManager._NUM_OP], new SparseArray<ArraySet<String>>()); + perTokenRestrictions.put(userHandle, restrictions); + } + + return restrictions.first; + } + + /** + * Get the per-package exemptions for each AppOps code for a given client and userHandle. + * + * @param token the binder client to get the exemptions for. + * @param userHandle the user handle to get the exemptions for. + * + * @return a mapping from the AppOps code to a set of packages exempt for that code. + */ + private SparseArray<ArraySet<String>> getUserPackageExemptionsForToken(IBinder token, + int userHandle) { + SparseArray<Pair<boolean[], SparseArray<ArraySet<String>>>> perTokenRestrictions = + mOpUserRestrictions.get(token); + + if (perTokenRestrictions == null) { + return null; // Don't create user restrictions accidentally } - return opRestrictions; + + Pair<boolean[], SparseArray<ArraySet<String>>> restrictions = + perTokenRestrictions.get(userHandle); + + if (restrictions == null) { + return null; // Don't create user restrictions accidentally + } + + return restrictions.second; } private void checkSystemUid(String function) { diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 86040c2842ed..3c1357742f48 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -3253,8 +3253,12 @@ public class ConnectivityService extends IConnectivityManager.Stub } int user = UserHandle.getUserId(Binder.getCallingUid()); synchronized(mVpns) { - setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, mVpns.get(user), - profile)); + Vpn vpn = mVpns.get(user); + if (vpn == null) { + Slog.w(TAG, "VPN for user " + user + " not ready yet. Skipping lockdown"); + return false; + } + setLockdownTracker(new LockdownVpnTracker(mContext, mNetd, this, vpn, profile)); } } else { setLockdownTracker(null); diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java index a63faf1b3011..d4dd50590c8a 100644 --- a/services/core/java/com/android/server/accounts/AccountManagerService.java +++ b/services/core/java/com/android/server/accounts/AccountManagerService.java @@ -47,6 +47,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.ServiceConnection; +import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; @@ -2460,31 +2461,12 @@ public class AccountManagerService public void onResult(Bundle result) { mNumResults++; Intent intent = null; - if (result != null && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) { - /* - * The Authenticator API allows third party authenticators to - * supply arbitrary intents to other apps that they can run, - * this can be very bad when those apps are in the system like - * the System Settings. - */ - int authenticatorUid = Binder.getCallingUid(); - long bid = Binder.clearCallingIdentity(); - try { - PackageManager pm = mContext.getPackageManager(); - ResolveInfo resolveInfo = pm.resolveActivityAsUser(intent, 0, mAccounts.userId); - int targetUid = resolveInfo.activityInfo.applicationInfo.uid; - if (PackageManager.SIGNATURE_MATCH != pm.checkSignatures(authenticatorUid, - targetUid)) { - throw new SecurityException("Activity to be started with KEY_INTENT must " - + "share Authenticator's signatures"); - } - } finally { - Binder.restoreCallingIdentity(bid); - } + checkKeyIntent( + Binder.getCallingUid(), + intent); } - IAccountManagerResponse response; if (mExpectActivityLaunch && result != null && result.containsKey(AccountManager.KEY_INTENT)) { @@ -3569,6 +3551,36 @@ public class AccountManagerService return response; } + /** + * Checks Intents, supplied via KEY_INTENT, to make sure that they don't violate our + * security policy. + * + * In particular we want to make sure that the Authenticator doesn't try to trick users + * into launching aribtrary intents on the device via by tricking to click authenticator + * supplied entries in the system Settings app. + */ + protected void checkKeyIntent( + int authUid, + Intent intent) throws SecurityException { + long bid = Binder.clearCallingIdentity(); + try { + PackageManager pm = mContext.getPackageManager(); + ResolveInfo resolveInfo = pm.resolveActivityAsUser(intent, 0, mAccounts.userId); + ActivityInfo targetActivityInfo = resolveInfo.activityInfo; + int targetUid = targetActivityInfo.applicationInfo.uid; + if (PackageManager.SIGNATURE_MATCH != pm.checkSignatures(authUid, targetUid)) { + String pkgName = targetActivityInfo.packageName; + String activityName = targetActivityInfo.name; + String tmpl = "KEY_INTENT resolved to an Activity (%s) in a package (%s) that " + + "does not share a signature with the supplying authenticator (%s)."; + throw new SecurityException( + String.format(tmpl, activityName, pkgName, mAccountType)); + } + } finally { + Binder.restoreCallingIdentity(bid); + } + } + private void close() { synchronized (mSessions) { if (mSessions.remove(toString()) == null) { @@ -3711,27 +3723,9 @@ public class AccountManagerService } if (result != null && (intent = result.getParcelable(AccountManager.KEY_INTENT)) != null) { - /* - * The Authenticator API allows third party authenticators to - * supply arbitrary intents to other apps that they can run, - * this can be very bad when those apps are in the system like - * the System Settings. - */ - int authenticatorUid = Binder.getCallingUid(); - long bid = Binder.clearCallingIdentity(); - try { - PackageManager pm = mContext.getPackageManager(); - ResolveInfo resolveInfo = pm.resolveActivityAsUser(intent, 0, mAccounts.userId); - int targetUid = resolveInfo.activityInfo.applicationInfo.uid; - if (PackageManager.SIGNATURE_MATCH != - pm.checkSignatures(authenticatorUid, targetUid)) { - throw new SecurityException( - "Activity to be started with KEY_INTENT must " + - "share Authenticator's signatures"); - } - } finally { - Binder.restoreCallingIdentity(bid); - } + checkKeyIntent( + Binder.getCallingUid(), + intent); } if (result != null && !TextUtils.isEmpty(result.getString(AccountManager.KEY_AUTHTOKEN))) { diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 07f668bf691f..f99d03521d6d 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -5347,6 +5347,7 @@ public final class ActivityManagerService extends ActivityManagerNative Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED, Uri.fromParts("package", packageName, null)); intent.putExtra(Intent.EXTRA_UID, pkgUid); + intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid)); broadcastIntentInPackage("android", Process.SYSTEM_UID, intent, null, null, 0, null, null, null, null, false, false, userId); } catch (RemoteException e) { diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 6bb2a60eb586..d364d8569db0 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2389,6 +2389,11 @@ public final class ActivityStackSupervisor implements DisplayListener { if (task.mActivities.size() == 1) { // There is only one activity in the task. So, we can just move the task over to // the stack without re-parenting the activity in a different task. + if (task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE) { + // Move the home stack forward if the task we just moved to the pinned stack + // was launched from home so home should be visible behind it. + moveHomeStackToFront(reason); + } moveTaskToStackLocked( task.taskId, PINNED_STACK_ID, ON_TOP, FORCE_FOCUS, reason, !ANIMATE); } else { diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index 004be34af7e2..4eae45c616e5 100644 --- a/services/core/java/com/android/server/am/TaskRecord.java +++ b/services/core/java/com/android/server/am/TaskRecord.java @@ -759,6 +759,14 @@ final class TaskRecord { if (r.isPersistable()) { mService.notifyTaskPersisterLocked(this, false); } + + if (stack != null && stack.mStackId == PINNED_STACK_ID) { + // We normally notify listeners of task stack changes on pause, however pinned stack + // activities are normally in the paused state so no notification will be sent there + // before the activity is removed. We send it here so instead. + mService.notifyTaskStackChangedLocked(); + } + if (mActivities.isEmpty()) { return !mReuseTask; } diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index 73da427c47c4..bce77337d581 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -688,12 +688,11 @@ public class NetworkMonitor extends StateMachine { // Time how long it takes to get a response to our request long requestTimestamp = SystemClock.elapsedRealtime(); - urlConnection.getInputStream(); + httpResponseCode = urlConnection.getResponseCode(); // Time how long it takes to get a response to our request long responseTimestamp = SystemClock.elapsedRealtime(); - httpResponseCode = urlConnection.getResponseCode(); validationLog("isCaptivePortal: ret=" + httpResponseCode + " headers=" + urlConnection.getHeaderFields()); // NOTE: We may want to consider an "HTTP/1.0 204" response to be a captive diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java index 212e077f4930..03191a0977cc 100644 --- a/services/core/java/com/android/server/content/ContentService.java +++ b/services/core/java/com/android/server/content/ContentService.java @@ -18,12 +18,16 @@ package com.android.server.content; import android.Manifest; import android.accounts.Account; +import android.annotation.Nullable; import android.app.ActivityManager; +import android.app.AppOpsManager; +import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.IContentService; import android.content.Intent; +import android.content.IntentFilter; import android.content.ISyncStatusObserver; import android.content.PeriodicSync; import android.content.SyncAdapterType; @@ -32,6 +36,7 @@ import android.content.SyncRequest; import android.content.SyncStatusInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManagerInternal; +import android.content.pm.ProviderInfo; import android.database.IContentObserver; import android.database.sqlite.SQLiteException; import android.net.Uri; @@ -44,30 +49,64 @@ import android.os.ServiceManager; import android.os.SystemProperties; import android.os.UserHandle; import android.text.TextUtils; +import android.util.ArrayMap; import android.util.Log; +import android.util.Pair; import android.util.Slog; +import android.util.SparseArray; import android.util.SparseIntArray; + +import com.android.internal.annotations.GuardedBy; +import com.android.internal.util.IndentingPrintWriter; +import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import java.io.FileDescriptor; import java.io.PrintWriter; import java.security.InvalidParameterException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Objects; /** * {@hide} */ public final class ContentService extends IContentService.Stub { private static final String TAG = "ContentService"; + private Context mContext; private boolean mFactoryTest; + private final ObserverNode mRootNode = new ObserverNode(""); + private SyncManager mSyncManager = null; private final Object mSyncManagerLock = new Object(); + /** + * Map from userId to providerPackageName to [clientPackageName, uri] to + * value. This structure is carefully optimized to keep invalidation logic + * as cheap as possible. + */ + @GuardedBy("mCache") + private final SparseArray<ArrayMap<String, ArrayMap<Pair<String, Uri>, Bundle>>> + mCache = new SparseArray<>(); + + private BroadcastReceiver mCacheReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final Uri data = intent.getData(); + if (data != null) { + final int userId = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, + UserHandle.USER_NULL); + final String packageName = data.getSchemeSpecificPart(); + invalidateCacheLocked(userId, packageName, null); + } + } + }; + private SyncManager getSyncManager() { if (SystemProperties.getBoolean("config.disable_network", false)) { return null; @@ -85,13 +124,15 @@ public final class ContentService extends IContentService.Stub { } @Override - protected synchronized void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + protected synchronized void dump(FileDescriptor fd, PrintWriter pw_, String[] args) { mContext.enforceCallingOrSelfPermission(Manifest.permission.DUMP, "caller doesn't have the DUMP permission"); + final IndentingPrintWriter pw = new IndentingPrintWriter(pw_, " "); + // This makes it so that future permission checks will be in the context of this // process rather than the caller's process. We will restore this before returning. - long identityToken = clearCallingIdentity(); + final long identityToken = clearCallingIdentity(); try { if (mSyncManager == null) { pw.println("No SyncManager created! (Disk full?)"); @@ -132,6 +173,19 @@ public final class ContentService extends IContentService.Stub { pw.print(" Total number of nodes: "); pw.println(counts[0]); pw.print(" Total number of observers: "); pw.println(counts[1]); } + + synchronized (mCache) { + pw.println(); + pw.println("Cached content:"); + pw.increaseIndent(); + for (int i = 0; i < mCache.size(); i++) { + pw.println("User " + mCache.keyAt(i) + ":"); + pw.increaseIndent(); + pw.println(mCache.valueAt(i)); + pw.decreaseIndent(); + } + pw.decreaseIndent(); + } } finally { restoreCallingIdentity(identityToken); } @@ -167,6 +221,15 @@ public final class ContentService extends IContentService.Stub { return getSyncAdapterPackagesForAuthorityAsUser(authority, userId); } }); + + final IntentFilter packageFilter = new IntentFilter(); + packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); + packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); + packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); + packageFilter.addAction(Intent.ACTION_PACKAGE_DATA_CLEARED); + packageFilter.addDataScheme("package"); + mContext.registerReceiverAsUser(mCacheReceiver, UserHandle.ALL, + packageFilter, null, null); } public void systemReady() { @@ -312,6 +375,11 @@ public final class ContentService extends IContentService.Stub { uri.getAuthority()); } } + + synchronized (mCache) { + final String providerPackageName = getProviderPackageName(uri); + invalidateCacheLocked(userHandle, providerPackageName, uri); + } } finally { restoreCallingIdentity(identityToken); } @@ -915,6 +983,86 @@ public final class ContentService extends IContentService.Stub { } } + private @Nullable String getProviderPackageName(Uri uri) { + final ProviderInfo pi = mContext.getPackageManager() + .resolveContentProvider(uri.getAuthority(), 0); + return (pi != null) ? pi.packageName : null; + } + + private ArrayMap<Pair<String, Uri>, Bundle> findOrCreateCacheLocked(int userId, + String providerPackageName) { + ArrayMap<String, ArrayMap<Pair<String, Uri>, Bundle>> userCache = mCache.get(userId); + if (userCache == null) { + userCache = new ArrayMap<>(); + mCache.put(userId, userCache); + } + ArrayMap<Pair<String, Uri>, Bundle> packageCache = userCache.get(providerPackageName); + if (packageCache == null) { + packageCache = new ArrayMap<>(); + userCache.put(providerPackageName, packageCache); + } + return packageCache; + } + + private void invalidateCacheLocked(int userId, String providerPackageName, Uri uri) { + ArrayMap<String, ArrayMap<Pair<String, Uri>, Bundle>> userCache = mCache.get(userId); + if (userCache == null) return; + + ArrayMap<Pair<String, Uri>, Bundle> packageCache = userCache.get(providerPackageName); + if (packageCache == null) return; + + if (uri != null) { + for (int i = 0; i < packageCache.size();) { + final Uri key = packageCache.keyAt(i).second; + if (Objects.equals(key, uri)) { + packageCache.removeAt(i); + } else { + i++; + } + } + } else { + packageCache.clear(); + } + } + + @Override + public void putCache(String packageName, Uri key, Bundle value, int userId) { + enforceCrossUserPermission(userId, TAG); + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CACHE_CONTENT, TAG); + mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(), + packageName); + + final String providerPackageName = getProviderPackageName(key); + final Pair<String, Uri> fullKey = Pair.create(packageName, key); + + synchronized (mCache) { + final ArrayMap<Pair<String, Uri>, Bundle> cache = findOrCreateCacheLocked(userId, + providerPackageName); + if (value != null) { + cache.put(fullKey, value); + } else { + cache.remove(fullKey); + } + } + } + + @Override + public Bundle getCache(String packageName, Uri key, int userId) { + enforceCrossUserPermission(userId, TAG); + mContext.enforceCallingOrSelfPermission(android.Manifest.permission.CACHE_CONTENT, TAG); + mContext.getSystemService(AppOpsManager.class).checkPackage(Binder.getCallingUid(), + packageName); + + final String providerPackageName = getProviderPackageName(key); + final Pair<String, Uri> fullKey = Pair.create(packageName, key); + + synchronized (mCache) { + final ArrayMap<Pair<String, Uri>, Bundle> cache = findOrCreateCacheLocked(userId, + providerPackageName); + return cache.get(fullKey); + } + } + public static ContentService main(Context context, boolean factoryTest) { ContentService service = new ContentService(context, factoryTest); ServiceManager.addService(ContentResolver.CONTENT_SERVICE_NAME, service); diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java index 088d96e4a6e0..4527f1f2cc19 100644 --- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java @@ -381,8 +381,8 @@ final class LocalDisplayAdapter extends DisplayAdapter { | DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS; } + final Resources res = getContext().getResources(); if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) { - final Resources res = getContext().getResources(); mInfo.name = res.getString( com.android.internal.R.string.display_manager_built_in_display_name); mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY @@ -416,6 +416,11 @@ final class LocalDisplayAdapter extends DisplayAdapter { if (SystemProperties.getBoolean("persist.demo.hdmirotates", false)) { mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT; } + + if (!res.getBoolean( + com.android.internal.R.bool.config_localDisplaysMirrorContent)) { + mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY; + } } } return mInfo; diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index e90fb3208d85..b7cd3185a228 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -51,6 +51,7 @@ import android.provider.Settings; import android.util.Log; import android.util.Slog; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.content.PackageMonitor; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; @@ -76,6 +77,7 @@ public class LauncherAppsService extends SystemService { publishBinderService(Context.LAUNCHER_APPS_SERVICE, mLauncherAppsImpl); } + @VisibleForTesting static class LauncherAppsImpl extends ILauncherApps.Stub { private static final boolean DEBUG = false; private static final String TAG = "LauncherAppsService"; @@ -167,7 +169,8 @@ public class LauncherAppsService extends SystemService { /** * Checks if the caller is in the same group as the userToCheck. */ - private void ensureInUserProfiles(UserHandle userToCheck, String message) { + @VisibleForTesting // We override it in unit tests + void ensureInUserProfiles(UserHandle userToCheck, String message) { final int callingUserId = UserHandle.getCallingUserId(); final int targetUserId = userToCheck.getIdentifier(); @@ -187,12 +190,14 @@ public class LauncherAppsService extends SystemService { } } - private void verifyCallingPackage(String callingPackage) { + @VisibleForTesting // We override it in unit tests + void verifyCallingPackage(String callingPackage) { int packageUid = -1; try { - packageUid = mPm.getPackageUid(callingPackage, + packageUid = mPm.getPackageUidAsUser(callingPackage, PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE - | PackageManager.MATCH_UNINSTALLED_PACKAGES); + | PackageManager.MATCH_UNINSTALLED_PACKAGES, + UserHandle.getUserId(getCallingUid())); } catch (NameNotFoundException e) { Log.e(TAG, "Package not found: " + callingPackage); } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index debe072b7b98..f8221b351976 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -10822,25 +10822,41 @@ public class PackageManagerService extends IPackageManager.Stub { } } - // TODO: investigate and add more restrictions for suspending crucial packages. + /** + * TODO: cache and disallow blocking the active dialer. + * + * @see also DefaultPermissionGrantPolicy#grantDefaultSystemHandlerPermissions + */ private boolean canSuspendPackageForUserLocked(String packageName, int userId) { if (isPackageDeviceAdmin(packageName, userId)) { - Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName - + "\": has active device admin"); + Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName + + "\": has an active device admin"); return false; } String activeLauncherPackageName = getActiveLauncherPackageName(userId); if (packageName.equals(activeLauncherPackageName)) { - Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName - + "\" because it is set as the active launcher"); + Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName + + "\": contains the active launcher"); + return false; + } + + if (packageName.equals(mRequiredInstallerPackage)) { + Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName + + "\": required for package installation"); + return false; + } + + if (packageName.equals(mRequiredVerifierPackage)) { + Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName + + "\": required for package verification"); return false; } final PackageParser.Package pkg = mPackages.get(packageName); if (pkg != null && isPrivilegedApp(pkg)) { - Slog.w(TAG, "Not suspending/un-suspending package \"" + packageName - + "\" because it is a privileged app"); + Slog.w(TAG, "Cannot suspend/un-suspend package \"" + packageName + + "\": is a privileged app"); return false; } diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index bf5a8f6b7783..4c77f286a404 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -4291,6 +4291,7 @@ final class Settings { } pw.print(prefix); pw.print(" versionCode="); pw.print(ps.versionCode); if (ps.pkg != null) { + pw.print(" minSdk="); pw.print(ps.pkg.applicationInfo.minSdkVersion); pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion); } pw.println(); diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java index 1cd0592db267..0b0f7abbce4e 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -88,6 +88,7 @@ import java.net.URISyntaxException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.function.Predicate; /** @@ -149,6 +150,7 @@ public class ShortcutService extends IShortcutService.Stub { static final String DIRECTORY_BITMAPS = "bitmaps"; static final String TAG_ROOT = "root"; + static final String TAG_USER = "user"; static final String TAG_PACKAGE = "package"; static final String TAG_LAST_RESET_TIME = "last_reset_time"; static final String TAG_INTENT_EXTRAS = "intent-extras"; @@ -221,11 +223,10 @@ public class ShortcutService extends IShortcutService.Stub { private long mRawLastResetTime; /** - * User ID -> package name -> list of ShortcutInfos. + * User ID -> UserShortcuts */ @GuardedBy("mLock") - private final SparseArray<ArrayMap<String, PackageShortcuts>> mShortcuts = - new SparseArray<>(); + private final SparseArray<UserShortcuts> mUsers = new SparseArray<>(); /** * Max number of dynamic shortcuts that each application can have at a time. @@ -313,7 +314,7 @@ public class ShortcutService extends IShortcutService.Stub { /** lifecycle event */ void onCleanupUserInner(int userId) { // Unload - mShortcuts.delete(userId); + mUsers.delete(userId); } /** Return the base state file name */ @@ -583,20 +584,9 @@ public class ShortcutService extends IShortcutService.Stub { XmlSerializer out = new FastXmlSerializer(); out.setOutput(outs, StandardCharsets.UTF_8.name()); out.startDocument(null, true); - out.startTag(null, TAG_ROOT); - - final ArrayMap<String, PackageShortcuts> packages = getUserShortcutsLocked(userId); - // Body. - for (int i = 0; i < packages.size(); i++) { - final String packageName = packages.keyAt(i); - final PackageShortcuts packageShortcuts = packages.valueAt(i); - - packageShortcuts.saveToXml(out); - } + getUserShortcutsLocked(userId).saveToXml(out); - // Epilogue. - out.endTag(null, TAG_ROOT); out.endDocument(); // Close. @@ -612,7 +602,7 @@ public class ShortcutService extends IShortcutService.Stub { } @Nullable - private ArrayMap<String, PackageShortcuts> loadUserLocked(@UserIdInt int userId) { + private UserShortcuts loadUserLocked(@UserIdInt int userId) { final File path = new File(injectUserDataPath(userId), FILENAME_USER_PACKAGES); if (DEBUG) { Slog.i(TAG, "Loading from " + path); @@ -628,13 +618,11 @@ public class ShortcutService extends IShortcutService.Stub { } return null; } - final ArrayMap<String, PackageShortcuts> ret = new ArrayMap<>(); + UserShortcuts ret = null; try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(in, StandardCharsets.UTF_8.name()); - PackageShortcuts shortcuts = null; - int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { @@ -647,22 +635,9 @@ public class ShortcutService extends IShortcutService.Stub { Slog.d(TAG, String.format("depth=%d type=%d name=%s", depth, type, tag)); } - switch (depth) { - case 1: { - if (TAG_ROOT.equals(tag)) { - continue; - } - break; - } - case 2: { - switch (tag) { - case TAG_PACKAGE: - shortcuts = PackageShortcuts.loadFromXml(parser, userId); - ret.put(shortcuts.mPackageName, shortcuts); - continue; - } - break; - } + if ((depth == 1) && TAG_USER.equals(tag)) { + ret = UserShortcuts.loadFromXml(parser, userId); + continue; } throwForInvalidTag(depth, tag); } @@ -731,14 +706,14 @@ public class ShortcutService extends IShortcutService.Stub { /** Return the per-user state. */ @GuardedBy("mLock") @NonNull - private ArrayMap<String, PackageShortcuts> getUserShortcutsLocked(@UserIdInt int userId) { - ArrayMap<String, PackageShortcuts> userPackages = mShortcuts.get(userId); + private UserShortcuts getUserShortcutsLocked(@UserIdInt int userId) { + UserShortcuts userPackages = mUsers.get(userId); if (userPackages == null) { userPackages = loadUserLocked(userId); if (userPackages == null) { - userPackages = new ArrayMap<>(); + userPackages = new UserShortcuts(userId); } - mShortcuts.put(userId, userPackages); + mUsers.put(userId, userPackages); } return userPackages; } @@ -748,11 +723,11 @@ public class ShortcutService extends IShortcutService.Stub { @NonNull private PackageShortcuts getPackageShortcutsLocked( @NonNull String packageName, @UserIdInt int userId) { - final ArrayMap<String, PackageShortcuts> userPackages = getUserShortcutsLocked(userId); - PackageShortcuts shortcuts = userPackages.get(packageName); + final UserShortcuts userPackages = getUserShortcutsLocked(userId); + PackageShortcuts shortcuts = userPackages.getPackages().get(packageName); if (shortcuts == null) { shortcuts = new PackageShortcuts(userId, packageName); - userPackages.put(packageName, shortcuts); + userPackages.getPackages().put(packageName, shortcuts); } return shortcuts; } @@ -1335,7 +1310,7 @@ public class ShortcutService extends IShortcutService.Stub { userId, ret, cloneFlag); } else { final ArrayMap<String, PackageShortcuts> packages = - getUserShortcutsLocked(userId); + getUserShortcutsLocked(userId).getPackages(); for (int i = packages.size() - 1; i >= 0; i--) { getShortcutsInnerLocked( packages.keyAt(i), @@ -1512,38 +1487,14 @@ public class ShortcutService extends IShortcutService.Stub { pw.print(mIconPersistQuality); pw.println(); - pw.println(); - for (int i = 0; i < mShortcuts.size(); i++) { - dumpUserLocked(pw, mShortcuts.keyAt(i)); + for (int i = 0; i < mUsers.size(); i++) { + pw.println(); + mUsers.valueAt(i).dump(this, pw, " "); } } } - private void dumpUserLocked(PrintWriter pw, int userId) { - pw.print(" User: "); - pw.print(userId); - pw.println(); - - final ArrayMap<String, PackageShortcuts> packages = mShortcuts.get(userId); - if (packages == null) { - return; - } - for (int j = 0; j < packages.size(); j++) { - dumpPackageLocked(pw, userId, packages.keyAt(j)); - } - pw.println(); - } - - private void dumpPackageLocked(PrintWriter pw, int userId, String packageName) { - final PackageShortcuts packageShortcuts = mShortcuts.get(userId).get(packageName); - if (packageShortcuts == null) { - return; - } - - packageShortcuts.dump(this, pw, " "); - } - static String formatTime(long time) { Time tobj = new Time(); tobj.set(time); @@ -1694,8 +1645,8 @@ public class ShortcutService extends IShortcutService.Stub { } @VisibleForTesting - SparseArray<ArrayMap<String, PackageShortcuts>> getShortcutsForTest() { - return mShortcuts; + SparseArray<UserShortcuts> getShortcutsForTest() { + return mUsers; } @VisibleForTesting @@ -1736,6 +1687,73 @@ public class ShortcutService extends IShortcutService.Stub { } } +class UserShortcuts { + private static final String TAG = ShortcutService.TAG; + + @UserIdInt + final int mUserId; + + private final ArrayMap<String, PackageShortcuts> mPackages = new ArrayMap<>(); + + public UserShortcuts(int userId) { + mUserId = userId; + } + + public ArrayMap<String, PackageShortcuts> getPackages() { + return mPackages; + } + + public void saveToXml(XmlSerializer out) throws IOException, XmlPullParserException { + out.startTag(null, ShortcutService.TAG_USER); + + for (int i = 0; i < mPackages.size(); i++) { + final String packageName = mPackages.keyAt(i); + final PackageShortcuts packageShortcuts = mPackages.valueAt(i); + + packageShortcuts.saveToXml(out); + } + + out.endTag(null, ShortcutService.TAG_USER); + } + + public static UserShortcuts loadFromXml(XmlPullParser parser, int userId) + throws IOException, XmlPullParserException { + final UserShortcuts ret = new UserShortcuts(userId); + + final int outerDepth = parser.getDepth(); + int type; + while ((type = parser.next()) != XmlPullParser.END_DOCUMENT + && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { + if (type != XmlPullParser.START_TAG) { + continue; + } + final int depth = parser.getDepth(); + final String tag = parser.getName(); + switch (tag) { + case ShortcutService.TAG_PACKAGE: + final PackageShortcuts shortcuts = PackageShortcuts.loadFromXml(parser, userId); + + // Don't use addShortcut(), we don't need to save the icon. + ret.getPackages().put(shortcuts.mPackageName, shortcuts); + continue; + } + throw ShortcutService.throwForInvalidTag(depth, tag); + } + return ret; + } + + public void dump(@NonNull ShortcutService s, @NonNull PrintWriter pw, @NonNull String prefix) { + pw.print(" "); + pw.print("User: "); + pw.print(mUserId); + pw.println(); + + for (int i = 0; i < mPackages.size(); i++) { + mPackages.valueAt(i).dump(s, pw, prefix + " "); + } + } +} + /** * All the information relevant to shortcuts from a single package (per-user). */ diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 0cd69c42ee72..0115a08cefe5 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -191,6 +191,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int LONG_PRESS_POWER_SHUT_OFF = 2; static final int LONG_PRESS_POWER_SHUT_OFF_NO_CONFIRM = 3; + static final int LONG_PRESS_BACK_NOTHING = 0; + static final int LONG_PRESS_BACK_GO_TO_VOICE_ASSIST = 1; + static final int MULTI_PRESS_POWER_NOTHING = 0; static final int MULTI_PRESS_POWER_THEATER_MODE = 1; static final int MULTI_PRESS_POWER_BRIGHTNESS_BOOST = 2; @@ -251,6 +254,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { // app shows again. If that doesn't happen for 30s we drop the gesture. private static final long PANIC_GESTURE_EXPIRATION = 30000; + private static final String SYSUI_PACKAGE = "com.android.systemui"; + private static final String SYSUI_SCREENSHOT_SERVICE = + "com.android.systemui.screenshot.TakeScreenshotService"; + private static final String SYSUI_SCREENSHOT_ERROR_RECEIVER = + "com.android.systemui.screenshot.ScreenshotServiceErrorReceiver"; + /** * Keyguard stuff */ @@ -385,6 +394,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // handler thread. We'll need to resolve this someday by teaching the input dispatcher // to hold wakelocks during dispatch and eliminating the critical path. volatile boolean mPowerKeyHandled; + volatile boolean mBackKeyHandled; volatile boolean mBeganFromNonInteractive; volatile int mPowerKeyPressCounter; volatile boolean mEndCallKeyHandled; @@ -437,6 +447,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mLongPressOnPowerBehavior; int mDoublePressOnPowerBehavior; int mTriplePressOnPowerBehavior; + int mLongPressOnBackBehavior; int mShortPressOnSleepBehavior; int mShortPressWindowBehavior; boolean mAwake; @@ -693,6 +704,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { private static final int MSG_UPDATE_DREAMING_SLEEP_TOKEN = 15; private static final int MSG_REQUEST_TRANSIENT_BARS = 16; private static final int MSG_REQUEST_TV_PICTURE_IN_PICTURE = 17; + private static final int MSG_BACK_LONG_PRESS = 18; private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0; private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1; @@ -757,6 +769,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { case MSG_REQUEST_TV_PICTURE_IN_PICTURE: requestTvPictureInPictureInternal(); break; + case MSG_BACK_LONG_PRESS: + backLongPress(); + break; } } } @@ -1103,6 +1118,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + private void cancelPendingBackKeyAction() { + if (!mBackKeyHandled) { + mBackKeyHandled = true; + mHandler.removeMessages(MSG_BACK_LONG_PRESS); + } + } + private void powerPress(long eventTime, boolean interactive, int count) { if (mScreenOnEarly && !mScreenOnFully) { Slog.i(TAG, "Suppressed redundant power key press while " @@ -1210,6 +1232,19 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + private void backLongPress() { + mBackKeyHandled = true; + + switch (mLongPressOnBackBehavior) { + case LONG_PRESS_BACK_NOTHING: + break; + case LONG_PRESS_BACK_GO_TO_VOICE_ASSIST: + Intent intent = new Intent(Intent.ACTION_VOICE_ASSIST); + startActivityAsUser(intent, UserHandle.CURRENT_OR_SELF); + break; + } + } + private void sleepPress(long eventTime) { if (mShortPressOnSleepBehavior == SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME) { launchHomeFromHotKey(false /* awakenDreams */, true /*respectKeyguard*/); @@ -1238,6 +1273,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { return getResolvedLongPressOnPowerBehavior() != LONG_PRESS_POWER_NOTHING; } + private boolean hasLongPressOnBackBehavior() { + return mLongPressOnBackBehavior != LONG_PRESS_BACK_NOTHING; + } + private void interceptScreenshotChord() { if (mScreenshotChordEnabled && mScreenshotChordVolumeDownKeyTriggered && mScreenshotChordPowerKeyTriggered @@ -1567,6 +1606,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { mSupportLongPressPowerWhenNonInteractive = mContext.getResources().getBoolean( com.android.internal.R.bool.config_supportLongPressPowerWhenNonInteractive); + mLongPressOnBackBehavior = mContext.getResources().getInteger( + com.android.internal.R.integer.config_longPressOnBackBehavior); + mShortPressOnPowerBehavior = mContext.getResources().getInteger( com.android.internal.R.integer.config_shortPressOnPowerBehavior); mLongPressOnPowerBehavior = mContext.getResources().getInteger( @@ -4593,7 +4635,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { } // TYPE_SYSTEM_ERROR is above the NavigationBar so it can't be allowed to extend over it. - if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && attrs.type != TYPE_SYSTEM_ERROR) { + // Also, we don't allow windows in multi-window mode to extend out of the screen. + if ((fl & FLAG_LAYOUT_NO_LIMITS) != 0 && attrs.type != TYPE_SYSTEM_ERROR + && !win.inMultiWindowMode()) { df.left = df.top = -10000; df.right = df.bottom = 10000; if (attrs.type != TYPE_WALLPAPER) { @@ -5186,6 +5230,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mScreenshotConnection != null) { mContext.unbindService(mScreenshotConnection); mScreenshotConnection = null; + notifyScreenshotError(); } } } @@ -5197,10 +5242,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mScreenshotConnection != null) { return; } - ComponentName cn = new ComponentName("com.android.systemui", - "com.android.systemui.screenshot.TakeScreenshotService"); - Intent intent = new Intent(); - intent.setComponent(cn); + final ComponentName serviceComponent = new ComponentName(SYSUI_PACKAGE, + SYSUI_SCREENSHOT_SERVICE); + final Intent serviceIntent = new Intent(); + serviceIntent.setComponent(serviceComponent); ServiceConnection conn = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { @@ -5235,17 +5280,35 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } } + @Override - public void onServiceDisconnected(ComponentName name) {} + public void onServiceDisconnected(ComponentName name) { + notifyScreenshotError(); + } }; - if (mContext.bindServiceAsUser( - intent, conn, Context.BIND_AUTO_CREATE, UserHandle.CURRENT)) { + if (mContext.bindServiceAsUser(serviceIntent, conn, + Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE, + UserHandle.CURRENT)) { mScreenshotConnection = conn; mHandler.postDelayed(mScreenshotTimeout, 10000); } } } + /** + * Notifies the screenshot service to show an error. + */ + private void notifyScreenshotError() { + // If the service process is killed, then ask it to clean up after itself + final ComponentName errorComponent = new ComponentName(SYSUI_PACKAGE, + SYSUI_SCREENSHOT_ERROR_RECEIVER); + Intent errorIntent = new Intent(); + errorIntent.setComponent(errorComponent); + errorIntent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | + Intent.FLAG_RECEIVER_FOREGROUND); + mContext.sendBroadcastAsUser(errorIntent, UserHandle.ALL); + } + /** {@inheritDoc} */ @Override public int interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) { @@ -5316,6 +5379,29 @@ public class PhoneWindowManager implements WindowManagerPolicy { // Handle special keys. switch (keyCode) { + case KeyEvent.KEYCODE_BACK: { + if (down) { + mBackKeyHandled = false; + if (hasLongPressOnBackBehavior()) { + Message msg = mHandler.obtainMessage(MSG_BACK_LONG_PRESS); + msg.setAsynchronous(true); + mHandler.sendMessageDelayed(msg, + ViewConfiguration.get(mContext).getDeviceGlobalActionKeyTimeout()); + } + } else { + boolean handled = mBackKeyHandled; + + // Reset back key state + cancelPendingBackKeyAction(); + + // Don't pass back press to app if we've already handled it + if (handled) { + result &= ~ACTION_PASS_TO_USER; + } + } + break; + } + case KeyEvent.KEYCODE_VOLUME_DOWN: case KeyEvent.KEYCODE_VOLUME_UP: case KeyEvent.KEYCODE_VOLUME_MUTE: { @@ -7365,6 +7451,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { pw.print(" mLidControlsScreenLock="); pw.println(mLidControlsScreenLock); pw.print(" mLidControlsSleep="); pw.println(mLidControlsSleep); pw.print(prefix); + pw.print(" mLongPressOnBackBehavior="); pw.println(mLongPressOnBackBehavior); + pw.print(prefix); pw.print("mShortPressOnPowerBehavior="); pw.print(mShortPressOnPowerBehavior); pw.print(" mLongPressOnPowerBehavior="); pw.println(mLongPressOnPowerBehavior); pw.print(prefix); diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java index f5914fafccf7..d0ee6e030c09 100644 --- a/services/core/java/com/android/server/vr/VrManagerService.java +++ b/services/core/java/com/android/server/vr/VrManagerService.java @@ -201,13 +201,16 @@ public class VrManagerService extends SystemService implements EnabledComponentC } } - private void updateOverlayStateLocked() { + private void updateOverlayStateLocked(ComponentName exemptedComponent) { final long identity = Binder.clearCallingIdentity(); try { AppOpsManager appOpsManager = getContext().getSystemService(AppOpsManager.class); if (appOpsManager != null) { + String[] exemptions = (exemptedComponent == null) ? new String[0] : + new String[] { exemptedComponent.getPackageName() }; + appOpsManager.setUserRestriction(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, - mVrModeEnabled, mOverlayToken); + mVrModeEnabled, mOverlayToken, exemptions); } } finally { Binder.restoreCallingIdentity(identity); @@ -230,12 +233,12 @@ public class VrManagerService extends SystemService implements EnabledComponentC private boolean updateCurrentVrServiceLocked(boolean enabled, @NonNull ComponentName component, int userId) { - // Always send mode change events. - changeVrModeLocked(enabled); - boolean validUserComponent = (mComponentObserver.isValid(component, userId) == EnabledComponentsObserver.NO_ERROR); + // Always send mode change events. + changeVrModeLocked(enabled, (enabled && validUserComponent) ? component : null); + if (!enabled || !validUserComponent) { // Unbind whatever is running if (mCurrentVrService != null) { @@ -275,8 +278,9 @@ public class VrManagerService extends SystemService implements EnabledComponentC * Note: Must be called while holding {@code mLock}. * * @param enabled new state of the VR mode. + * @param exemptedComponent a component to exempt from AppOps restrictions for overlays. */ - private void changeVrModeLocked(boolean enabled) { + private void changeVrModeLocked(boolean enabled, ComponentName exemptedComponent) { if (mVrModeEnabled != enabled) { mVrModeEnabled = enabled; @@ -284,7 +288,7 @@ public class VrManagerService extends SystemService implements EnabledComponentC Slog.i(TAG, "VR mode " + ((mVrModeEnabled) ? "enabled" : "disabled")); setVrModeNative(mVrModeEnabled); - updateOverlayStateLocked(); + updateOverlayStateLocked(exemptedComponent); onVrModeChangedLocked(); } } diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java index ccbdad276ef3..ffdd89ae364c 100644 --- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java +++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java @@ -441,12 +441,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { } // Called during initialization of a given user's wallpaper bookkeeping - boolean ensureCropExists() { - // if the crop file is not present, copy over the source image to use verbatim - if (!cropFile.exists()) { - return FileUtils.copyFile(wallpaperFile, cropFile); - } - return true; + boolean cropExists() { + return cropFile.exists(); } } @@ -734,7 +730,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { public void systemRunning() { if (DEBUG) Slog.v(TAG, "systemReady"); WallpaperData wallpaper = mWallpaperMap.get(UserHandle.USER_SYSTEM); - if (!wallpaper.ensureCropExists()) { + // No crop file? Make sure we've finished the processing sequence if necessary + if (!wallpaper.cropExists()) { + generateCrop(wallpaper); + } + // Still nothing? Fall back to default. + if (!wallpaper.cropExists()) { clearWallpaperLocked(false, FLAG_SET_SYSTEM, UserHandle.USER_SYSTEM, null); } switchWallpaper(wallpaper, null); @@ -1645,7 +1646,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { if (wallpaper == null) { wallpaper = new WallpaperData(userId, WALLPAPER, WALLPAPER_CROP); mWallpaperMap.put(userId, wallpaper); - wallpaper.ensureCropExists(); + if (!wallpaper.cropExists()) { + generateCrop(wallpaper); + } } boolean success = false; try { @@ -1809,7 +1812,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub { if (DEBUG) Slog.v(TAG, "settingsRestored: success=" + success + " id=" + wallpaper.wallpaperId); if (success) { - bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, false, false, + generateCrop(wallpaper); // based on the new image + metadata + bindWallpaperComponentLocked(wallpaper.nextWallpaperComponent, true, false, wallpaper, null); } } diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 910788ea8b91..aff668bb4818 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -642,7 +642,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { mHaveFrame = true; final Task task = getTask(); - final boolean fullscreenTask = task == null || task.isFullscreen(); + final boolean fullscreenTask = !inMultiWindowMode(); final boolean windowsAreFloating = task != null && task.isFloating(); if (fullscreenTask || (isChildWindow() @@ -2215,6 +2215,12 @@ final class WindowState implements WindowManagerPolicy.WindowState { return task != null && task.inFreeformWorkspace(); } + @Override + public boolean inMultiWindowMode() { + final Task task = getTask(); + return task != null && !task.isFullscreen(); + } + boolean isDragResizeChanged() { return mDragResizing != computeDragResizing(); } @@ -2506,9 +2512,8 @@ final class WindowState implements WindowManagerPolicy.WindowState { final int pw = mContainingFrame.width(); final int ph = mContainingFrame.height(); final Task task = getTask(); - final boolean nonFullscreenTask = task != null && !task.isFullscreen(); - final boolean fitToDisplay = task != null && - !task.isFloating(); + final boolean nonFullscreenTask = inMultiWindowMode(); + final boolean fitToDisplay = task != null && !task.isFloating(); float x, y; int w,h; diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp index 6c640ba55042..c4316f63220d 100644 --- a/services/core/jni/com_android_server_tv_TvInputHal.cpp +++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp @@ -400,7 +400,7 @@ int JTvInputHal::addOrUpdateStream(int deviceId, int streamId, const sp<Surface> connection.mThread->shutdown(); } connection.mThread = new BufferProducerThread(mDevice, deviceId, &stream); - connection.mThread->run(); + connection.mThread->run("BufferProducerThread"); } } connection.mSurface = surface; diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index ea1a569b8e5c..b48c185aa2a3 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -33,6 +33,7 @@ import android.accessibilityservice.AccessibilityServiceInfo; import android.accounts.AccountManager; import android.annotation.IntDef; import android.annotation.NonNull; +import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.Activity; import android.app.ActivityManager; @@ -83,6 +84,7 @@ import android.net.wifi.WifiManager; import android.os.AsyncTask; import android.os.Binder; import android.os.Build; +import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Environment; import android.os.FileUtils; @@ -1378,6 +1380,22 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { return new LockPatternUtils(mContext); } + boolean storageManagerIsFileBasedEncryptionEnabled() { + return StorageManager.isFileEncryptedNativeOnly(); + } + + boolean storageManagerIsNonDefaultBlockEncrypted() { + return StorageManager.isNonDefaultBlockEncrypted(); + } + + boolean storageManagerIsEncrypted() { + return StorageManager.isEncrypted(); + } + + boolean storageManagerIsEncryptable() { + return StorageManager.isEncryptable(); + } + Looper getMyLooper() { return Looper.myLooper(); } @@ -2866,13 +2884,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public boolean isSeparateProfileChallengeAllowed(int userHandle) { ComponentName profileOwner = getProfileOwner(userHandle); - try { - // Profile challenge is supported on N or newer release. - return profileOwner != null && - getTargetSdk(profileOwner.getPackageName(), userHandle) > Build.VERSION_CODES.M; - } catch (RemoteException e) { - return false; - } + // Profile challenge is supported on N or newer release. + return profileOwner != null && + getTargetSdk(profileOwner.getPackageName(), userHandle) > Build.VERSION_CODES.M; } @Override @@ -4236,15 +4250,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int userHandle = UserHandle.getCallingUserId(); synchronized (this) { getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); - try { - if (getTargetSdk(who.getPackageName(), userHandle) >= Build.VERSION_CODES.N) { - if (installerPackage != null && - !isPackageInstalledForUser(installerPackage, userHandle)) { - throw new IllegalArgumentException("Package " + installerPackage - + " is not installed on the current user"); - } + if (getTargetSdk(who.getPackageName(), userHandle) >= Build.VERSION_CODES.N) { + if (installerPackage != null && + !isPackageInstalledForUser(installerPackage, userHandle)) { + throw new IllegalArgumentException("Package " + installerPackage + + " is not installed on the current user"); } - } catch (RemoteException e) { } DevicePolicyData policy = getUserData(userHandle); policy.mDelegatedCertInstallerPackage = installerPackage; @@ -4835,12 +4846,23 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * Get the current encryption status of the device. */ @Override - public int getStorageEncryptionStatus(int userHandle) { + public int getStorageEncryptionStatus(@Nullable String callerPackage, int userHandle) { if (!mHasFeature) { // Ok to return current status. } enforceFullCrossUsersPermission(userHandle); - return getEncryptionStatus(); + + // It's not critical here, but let's make sure the package name is correct, in case + // we start using it for different purposes. + ensureCallerPackage(callerPackage); + + final int rawStatus = getEncryptionStatus(); + if ((rawStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER) + && (callerPackage != null) + && (getTargetSdk(callerPackage, userHandle) <= VERSION_CODES.M)) { + return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE; + } + return rawStatus; } /** @@ -4858,15 +4880,18 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * Hook to low-levels: Reporting the current status of encryption. * @return A value such as {@link DevicePolicyManager#ENCRYPTION_STATUS_UNSUPPORTED}, * {@link DevicePolicyManager#ENCRYPTION_STATUS_INACTIVE}, - * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY}, or + * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY}, + * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE_PER_USER}, or * {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE}. */ private int getEncryptionStatus() { - if (StorageManager.isEncrypted()) { - return StorageManager.isNonDefaultBlockEncrypted() ? - DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE - : DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY; - } else if (StorageManager.isEncryptable()) { + if (mInjector.storageManagerIsFileBasedEncryptionEnabled()) { + return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER; + } else if (mInjector.storageManagerIsNonDefaultBlockEncrypted()) { + return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE; + } else if (mInjector.storageManagerIsEncrypted()) { + return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY; + } else if (mInjector.storageManagerIsEncryptable()) { return DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE; } else { return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED; @@ -4879,7 +4904,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void setEncryptionRequested(boolean encrypt) { } - /** * Set whether the screen capture is disabled for the user managed by the specified admin. */ @@ -6037,6 +6061,23 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } + private void ensureCallerPackage(@Nullable String packageName) { + if (packageName == null) { + Preconditions.checkState(isCallerWithSystemUid(), + "Only caller can omit package name"); + } else { + final int callingUid = mInjector.binderGetCallingUid(); + final int userId = mInjector.userHandleGetCallingUserId(); + try { + final ApplicationInfo ai = mIPackageManager.getApplicationInfo( + packageName, 0, userId); + Preconditions.checkState(ai.uid == callingUid, "Unmatching package name"); + } catch (RemoteException e) { + // Shouldn't happen + } + } + } + private boolean isCallerWithSystemUid() { return UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID); } @@ -6122,6 +6163,27 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { pw.println(" "); pw.print(" mPasswordOwner="); pw.println(policy.mPasswordOwner); } + pw.println(); + pw.println("Encryption Status: " + getEncryptionStatusName(getEncryptionStatus())); + } + } + + private String getEncryptionStatusName(int encryptionStatus) { + switch (encryptionStatus) { + case DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE: + return "inactive"; + case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY: + return "block default key"; + case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE: + return "block"; + case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER: + return "per-user"; + case DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED: + return "unsupported"; + case DevicePolicyManager.ENCRYPTION_STATUS_ACTIVATING: + return "activating"; + default: + return "unknown"; } } @@ -8207,11 +8269,16 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { * Returns the target sdk version number that the given packageName was built for * in the given user. */ - private int getTargetSdk(String packageName, int userId) throws RemoteException { - final ApplicationInfo ai = mIPackageManager - .getApplicationInfo(packageName, 0, userId); - final int targetSdkVersion = ai == null ? 0 : ai.targetSdkVersion; - return targetSdkVersion; + private int getTargetSdk(String packageName, int userId) { + final ApplicationInfo ai; + try { + ai = mIPackageManager.getApplicationInfo(packageName, 0, userId); + final int targetSdkVersion = ai == null ? 0 : ai.targetSdkVersion; + return targetSdkVersion; + } catch (RemoteException e) { + // Shouldn't happen + return 0; + } } @Override diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java index db2a9ad3223c..aaec1e9241cf 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerServiceTestable.java @@ -28,6 +28,7 @@ import android.os.PowerManagerInternal; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; +import android.os.storage.StorageManager; import android.view.IWindowManager; import java.io.File; @@ -163,6 +164,26 @@ public class DevicePolicyManagerServiceTestable extends DevicePolicyManagerServi } @Override + boolean storageManagerIsFileBasedEncryptionEnabled() { + return context.storageManager.isFileBasedEncryptionEnabled(); + } + + @Override + boolean storageManagerIsNonDefaultBlockEncrypted() { + return context.storageManager.isNonDefaultBlockEncrypted(); + } + + @Override + boolean storageManagerIsEncrypted() { + return context.storageManager.isEncrypted(); + } + + @Override + boolean storageManagerIsEncryptable() { + return context.storageManager.isEncryptable(); + } + + @Override String getDevicePolicyFilePathForSystemUser() { return context.systemUserDataDir.getAbsolutePath() + "/"; } diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java index ef8e420e53f0..b05309af49ab 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java @@ -39,6 +39,7 @@ import android.os.PowerManagerInternal; import android.os.UserHandle; import android.os.UserManager; import android.os.UserManagerInternal; +import android.os.storage.StorageManager; import android.test.mock.MockContentResolver; import android.test.mock.MockContext; import android.view.IWindowManager; @@ -211,6 +212,24 @@ public class DpmMockContext extends MockContext { } } + public static class StorageManagerForMock { + public boolean isFileBasedEncryptionEnabled() { + return false; + } + + public boolean isNonDefaultBlockEncrypted() { + return false; + } + + public boolean isEncrypted() { + return false; + } + + public boolean isEncryptable() { + return false; + } + } + public final Context realTestContext; /** @@ -239,6 +258,7 @@ public class DpmMockContext extends MockContext { public final IBackupManager ibackupManager; public final IAudioService iaudioService; public final LockPatternUtils lockPatternUtils; + public final StorageManagerForMock storageManager; public final WifiManager wifiManager; public final SettingsForMock settings; public final MockContentResolver contentResolver; @@ -272,6 +292,7 @@ public class DpmMockContext extends MockContext { ibackupManager = mock(IBackupManager.class); iaudioService = mock(IAudioService.class); lockPatternUtils = mock(LockPatternUtils.class); + storageManager = mock(StorageManagerForMock.class); wifiManager = mock(WifiManager.class); settings = mock(SettingsForMock.class); diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java index 2f4beaa36da4..f2c42dbb012b 100644 --- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java @@ -15,13 +15,18 @@ */ package com.android.server.pm; +import static org.mockito.Mockito.mock; + import android.annotation.NonNull; import android.annotation.UserIdInt; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; +import android.content.pm.ILauncherApps; +import android.content.pm.LauncherApps; import android.content.pm.LauncherApps.ShortcutQuery; +import android.content.pm.PackageManager; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutManager; import android.content.pm.ShortcutServiceInternal; @@ -30,10 +35,12 @@ import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.graphics.drawable.Icon; +import android.os.BaseBundle; import android.os.Bundle; import android.os.FileUtils; import android.os.ParcelFileDescriptor; import android.os.UserHandle; +import android.os.UserManager; import android.test.AndroidTestCase; import android.test.mock.MockContext; import android.test.suitebuilder.annotation.SmallTest; @@ -43,6 +50,7 @@ import com.android.frameworks.servicestests.R; import com.android.internal.util.Preconditions; import com.android.server.LocalServices; import com.android.server.SystemService; +import com.android.server.pm.LauncherAppsService.LauncherAppsImpl; import com.android.server.pm.ShortcutService.ConfigConstants; import com.android.server.pm.ShortcutService.FileOutputStreamWithPath; @@ -75,7 +83,11 @@ import java.util.Set; -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner * TODO: Add checks with assertAllNotHaveIcon() + * + * TODO: separate, detailed tests for ShortcutInfo (CTS?) * + * * TODO: Cross-user test (do in CTS?) + * */ @SmallTest public class ShortcutManagerTest extends AndroidTestCase { @@ -87,11 +99,19 @@ public class ShortcutManagerTest extends AndroidTestCase { */ private static final boolean ENABLE_DUMP = false; // DO NOT SUBMIT WITH true - /** Context used in the client side */ - private final class ClientContext extends MockContext { + private class BaseContext extends MockContext { @Override - public String getPackageName() { - return mInjectedClientPackage; + public Object getSystemService(String name) { + switch (name) { + case Context.USER_SERVICE: + return mMockUserManager; + } + throw new UnsupportedOperationException(); + } + + @Override + public PackageManager getPackageManager() { + return mMockPackageManager; } @Override @@ -100,14 +120,18 @@ public class ShortcutManagerTest extends AndroidTestCase { } } - /** Context used in the service side */ - private final class ServiceContext extends MockContext { + /** Context used in the client side */ + private class ClientContext extends BaseContext { @Override - public Resources getResources() { - return ShortcutManagerTest.this.getContext().getResources(); + public String getPackageName() { + return mInjectedClientPackage; } } + /** Context used in the service side */ + private final class ServiceContext extends BaseContext { + } + /** ShortcutService with injection override methods. */ private final class ShortcutServiceTestable extends ShortcutService { public ShortcutServiceTestable(Context context) { @@ -170,7 +194,7 @@ public class ShortcutManagerTest extends AndroidTestCase { } /** ShortcutManager with injection override methods. */ - private final class ShortcutManagerTestable extends ShortcutManager { + private class ShortcutManagerTestable extends ShortcutManager { public ShortcutManagerTestable(Context context, ShortcutServiceTestable service) { super(context, service); } @@ -181,6 +205,27 @@ public class ShortcutManagerTest extends AndroidTestCase { } } + private class LauncherAppImplTestable extends LauncherAppsImpl { + public LauncherAppImplTestable(Context context) { + super(context); + } + + @Override + public void ensureInUserProfiles(UserHandle userToCheck, String message) { + // SKIP + } + + @Override + public void verifyCallingPackage(String callingPackage) { + // SKIP + } + } + + private class LauncherAppsTestable extends LauncherApps { + public LauncherAppsTestable(Context context, ILauncherApps service) { + super(context, service); + } + } public static class ShortcutActivity extends Activity { } @@ -198,6 +243,9 @@ public class ShortcutManagerTest extends AndroidTestCase { private ShortcutManagerTestable mManager; private ShortcutServiceInternal mInternal; + private LauncherAppImplTestable mLauncherAppImpl; + private LauncherAppsTestable mLauncherApps; + private File mInjectedFilePathRoot; private long mInjectedCurrentTimeLillis; @@ -209,6 +257,9 @@ public class ShortcutManagerTest extends AndroidTestCase { private Map<String, Integer> mInjectedPackageUidMap; + private PackageManager mMockPackageManager; + private UserManager mMockUserManager; + private static final String CALLING_PACKAGE_1 = "com.android.test.1"; private static final int CALLING_UID_1 = 10001; @@ -246,6 +297,9 @@ public class ShortcutManagerTest extends AndroidTestCase { mServiceContext = new ServiceContext(); mClientContext = new ClientContext(); + mMockPackageManager = mock(PackageManager.class); + mMockUserManager = mock(UserManager.class); + // Prepare injection values. mInjectedCurrentTimeLillis = START_TIME; @@ -280,6 +334,9 @@ public class ShortcutManagerTest extends AndroidTestCase { mInternal = LocalServices.getService(ShortcutServiceInternal.class); + mLauncherAppImpl = new LauncherAppImplTestable(mServiceContext); + mLauncherApps = new LauncherAppsTestable(mClientContext, mLauncherAppImpl); + // Load the setting file. mService.onBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY); } @@ -315,6 +372,10 @@ public class ShortcutManagerTest extends AndroidTestCase { return UserHandle.getUserId(mInjectedCallingUid); } + private UserHandle getCallingUser() { + return UserHandle.of(getCallingUserId()); + } + /** For debugging */ private void dumpsysOnLogcat() { if (!ENABLE_DUMP) return; @@ -434,7 +495,6 @@ public class ShortcutManagerTest extends AndroidTestCase { return s; } - /** * Make multiple shortcuts with IDs. */ @@ -446,6 +506,10 @@ public class ShortcutManagerTest extends AndroidTestCase { return ret; } + private ShortcutInfo.Builder makeShortcutBuilder() { + return new ShortcutInfo.Builder(mClientContext); + } + /** * Make a shortcut with details. */ @@ -663,6 +727,10 @@ public class ShortcutManagerTest extends AndroidTestCase { } } + private void assertBundleEmpty(BaseBundle b) { + assertTrue(b == null || b.size() == 0); + } + private ShortcutInfo getPackageShortcut(String packageName, String shortcutId, int userId) { return mService.getPackageShortcutForTest(packageName, shortcutId, userId); } @@ -1132,65 +1200,61 @@ public class ShortcutManagerTest extends AndroidTestCase { setCaller(LAUNCHER_1); // Check hasIconResource()/hasIconFile(). - assertShortcutIds(assertAllHaveIconResId(mInternal.getShortcutInfo( - getCallingPackage(), CALLING_PACKAGE_1, Arrays.asList("res32x32"), - getCallingUserId())), "res32x32"); - - assertShortcutIds(assertAllHaveIconResId(mInternal.getShortcutInfo( - getCallingPackage(), CALLING_PACKAGE_1, Arrays.asList("res64x64"), - getCallingUserId())), "res64x64"); - - assertShortcutIds(assertAllHaveIconFile(mInternal.getShortcutInfo( - getCallingPackage(), CALLING_PACKAGE_1, Arrays.asList("bmp32x32"), - getCallingUserId())), "bmp32x32"); - assertShortcutIds(assertAllHaveIconFile(mInternal.getShortcutInfo( - getCallingPackage(), CALLING_PACKAGE_1, Arrays.asList("bmp64x64"), - getCallingUserId())), "bmp64x64"); - assertShortcutIds(assertAllHaveIconFile(mInternal.getShortcutInfo( - getCallingPackage(), CALLING_PACKAGE_1, Arrays.asList("bmp512x512"), - getCallingUserId())), "bmp512x512"); + assertShortcutIds(assertAllHaveIconResId(mLauncherApps.getShortcutInfo( + CALLING_PACKAGE_1, Arrays.asList("res32x32"), + getCallingUser())), "res32x32"); + + assertShortcutIds(assertAllHaveIconResId(mLauncherApps.getShortcutInfo( + CALLING_PACKAGE_1, Arrays.asList("res64x64"), getCallingUser())), + "res64x64"); + + assertShortcutIds(assertAllHaveIconFile(mLauncherApps.getShortcutInfo( + CALLING_PACKAGE_1, Arrays.asList("bmp32x32"), getCallingUser())), + "bmp32x32"); + + assertShortcutIds(assertAllHaveIconFile(mLauncherApps.getShortcutInfo( + CALLING_PACKAGE_1, Arrays.asList("bmp64x64"), getCallingUser())), + "bmp64x64"); + + assertShortcutIds(assertAllHaveIconFile(mLauncherApps.getShortcutInfo( + CALLING_PACKAGE_1, Arrays.asList("bmp512x512"), getCallingUser())), + "bmp512x512"); // Check assertEquals( R.drawable.black_32x32, - mInternal.getShortcutIconResId(getCallingPackage(), - makePackageShortcut(CALLING_PACKAGE_1, "res32x32"), getCallingUserId())); + mLauncherApps.getShortcutIconResId( + makePackageShortcut(CALLING_PACKAGE_1, "res32x32"), getCallingUser())); assertEquals( R.drawable.black_64x64, - mInternal.getShortcutIconResId( - getCallingPackage(), - makePackageShortcut(CALLING_PACKAGE_1, "res64x64"), getCallingUserId())); + mLauncherApps.getShortcutIconResId( + + makePackageShortcut(CALLING_PACKAGE_1, "res64x64"), getCallingUser())); assertEquals( 0, // because it's not a resource - mInternal.getShortcutIconResId( - getCallingPackage(), - makePackageShortcut(CALLING_PACKAGE_1, "bmp32x32"), getCallingUserId())); + mLauncherApps.getShortcutIconResId( + makePackageShortcut(CALLING_PACKAGE_1, "bmp32x32"), getCallingUser())); assertEquals( 0, // because it's not a resource - mInternal.getShortcutIconResId( - getCallingPackage(), - makePackageShortcut(CALLING_PACKAGE_1, "bmp64x64"), getCallingUserId())); + mLauncherApps.getShortcutIconResId( + makePackageShortcut(CALLING_PACKAGE_1, "bmp64x64"), getCallingUser())); assertEquals( 0, // because it's not a resource - mInternal.getShortcutIconResId( - getCallingPackage(), - makePackageShortcut(CALLING_PACKAGE_1, "bmp512x512"), getCallingUserId())); + mLauncherApps.getShortcutIconResId( + makePackageShortcut(CALLING_PACKAGE_1, "bmp512x512"), getCallingUser())); - bmp = pfdToBitmap(mInternal.getShortcutIconFd( - getCallingPackage(), - makePackageShortcut(CALLING_PACKAGE_1, "bmp32x32"), getCallingUserId())); + bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd( + makePackageShortcut(CALLING_PACKAGE_1, "bmp32x32"), getCallingUser())); assertBitmapSize(32, 32, bmp); - bmp = pfdToBitmap(mInternal.getShortcutIconFd( - getCallingPackage(), - makePackageShortcut(CALLING_PACKAGE_1, "bmp64x64"), getCallingUserId())); + bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd( + makePackageShortcut(CALLING_PACKAGE_1, "bmp64x64"), getCallingUser())); assertBitmapSize(64, 64, bmp); - bmp = pfdToBitmap(mInternal.getShortcutIconFd( - getCallingPackage(), - makePackageShortcut(CALLING_PACKAGE_1, "bmp512x512"), getCallingUserId())); + bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd( + makePackageShortcut(CALLING_PACKAGE_1, "bmp512x512"), getCallingUser())); assertBitmapSize(128, 128, bmp); // TODO Test the content URI case too. @@ -1300,11 +1364,146 @@ public class ShortcutManagerTest extends AndroidTestCase { assertFalse(p11_1_3.getName().contains("_")); } + public void testUpdateShortcuts() { + runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> { + assertTrue(mManager.setDynamicShortcuts(Arrays.asList( + makeShortcut("s1"), + makeShortcut("s2"), + makeShortcut("s3"), + makeShortcut("s4"), + makeShortcut("s5") + ))); + }); + runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> { + assertTrue(mManager.setDynamicShortcuts(Arrays.asList( + makeShortcut("s1"), + makeShortcut("s2"), + makeShortcut("s3"), + makeShortcut("s4"), + makeShortcut("s5") + ))); + }); + runWithCaller(LAUNCHER_1, UserHandle.USER_SYSTEM, () -> { + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, Arrays.asList("s2", "s3"), + getCallingUser()); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, Arrays.asList("s4", "s5"), + getCallingUser()); + }); + runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> { + mManager.deleteDynamicShortcut("s1"); + mManager.deleteDynamicShortcut("s2"); + }); + runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> { + mManager.deleteDynamicShortcut("s1"); + mManager.deleteDynamicShortcut("s3"); + mManager.deleteDynamicShortcut("s5"); + }); + runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> { + assertShortcutIds(assertAllDynamic( + mManager.getDynamicShortcuts()), + "s3", "s4", "s5"); + assertShortcutIds(assertAllPinned( + mManager.getPinnedShortcuts()), + "s2", "s3"); + }); + runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> { + assertShortcutIds(assertAllDynamic( + mManager.getDynamicShortcuts()), + "s2", "s4"); + assertShortcutIds(assertAllPinned( + mManager.getPinnedShortcuts()), + "s4", "s5"); + }); + + runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> { + ShortcutInfo s2 = makeShortcutBuilder() + .setId("s2") + .setIcon(Icon.createWithResource(mContext, R.drawable.black_32x32)) + .build(); + + ShortcutInfo s4 = makeShortcutBuilder() + .setId("s4") + .setTitle("new title") + .build(); + + mManager.updateShortcuts(Arrays.asList(s2, s4)); + }); + runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> { + ShortcutInfo s2 = makeShortcutBuilder() + .setId("s2") + .setIntent(makeIntent(Intent.ACTION_ANSWER, ShortcutActivity.class, + "key1", "val1")) + .build(); + + ShortcutInfo s4 = makeShortcutBuilder() + .setId("s4") + .setIntent(new Intent(Intent.ACTION_ALL_APPS)) + .build(); + + mManager.updateShortcuts(Arrays.asList(s2, s4)); + }); + + runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> { + assertShortcutIds(assertAllDynamic( + mManager.getDynamicShortcuts()), + "s3", "s4", "s5"); + assertShortcutIds(assertAllPinned( + mManager.getPinnedShortcuts()), + "s2", "s3"); + + ShortcutInfo s = getCallerShortcut("s2"); + assertTrue(s.hasIconResource()); + assertEquals(R.drawable.black_32x32, s.getIconResourceId()); + assertEquals("Title-s2", s.getTitle()); + + s = getCallerShortcut("s4"); + assertFalse(s.hasIconResource()); + assertEquals(0, s.getIconResourceId()); + assertEquals("new title", s.getTitle()); + }); + runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> { + assertShortcutIds(assertAllDynamic( + mManager.getDynamicShortcuts()), + "s2", "s4"); + assertShortcutIds(assertAllPinned( + mManager.getPinnedShortcuts()), + "s4", "s5"); + + ShortcutInfo s = getCallerShortcut("s2"); + assertFalse(s.hasIconResource()); + assertEquals(0, s.getIconResourceId()); + assertEquals("Title-s2", s.getTitle()); + assertEquals(Intent.ACTION_ANSWER, s.getIntent().getAction()); + assertEquals(1, s.getIntent().getExtras().size()); + + s = getCallerShortcut("s4"); + assertFalse(s.hasIconResource()); + assertEquals(0, s.getIconResourceId()); + assertEquals("Title-s4", s.getTitle()); + assertEquals(Intent.ACTION_ALL_APPS, s.getIntent().getAction()); + assertBundleEmpty(s.getIntent().getExtras()); + }); + // TODO Check with other fields too. + + // TODO Check bitmap removal too. + } + // TODO: updateShortcuts() // TODO: getPinnedShortcuts() // === Test for launcher side APIs === + private static ShortcutQuery buildQuery(long changedSince, + String packageName, ComponentName componentName, + /* @ShortcutQuery.QueryFlags */ int flags) { + final ShortcutQuery q = new ShortcutQuery(); + q.setChangedSince(changedSince); + q.setPackage(packageName); + q.setActivity(componentName); + q.setQueryFlags(flags); + return q; + } + public void testGetShortcuts() { // Set up shortcuts. @@ -1330,56 +1529,55 @@ public class ShortcutManagerTest extends AndroidTestCase { // Get dynamic assertAllDynamic(assertAllHaveTitle(assertAllNotHaveIntents(assertShortcutIds( assertAllNotKeyFieldsOnly( - mInternal.getShortcuts(getCallingPackage(), /* time =*/ 0, CALLING_PACKAGE_1, - /* activity =*/ null, - ShortcutQuery.FLAG_GET_DYNAMIC, getCallingUserId())), + mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1, + /* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())), "s1", "s2")))); // Get pinned assertShortcutIds( - mInternal.getShortcuts(getCallingPackage(), /* time =*/ 0, CALLING_PACKAGE_1, + mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1, /* activity =*/ null, - ShortcutQuery.FLAG_GET_PINNED, getCallingUserId()) + ShortcutQuery.FLAG_GET_PINNED), getCallingUser()) /* none */); // Get both, with timestamp assertAllDynamic(assertAllHaveTitle(assertAllNotHaveIntents(assertShortcutIds( - assertAllNotKeyFieldsOnly(mInternal.getShortcuts(getCallingPackage(), + assertAllNotKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery( /* time =*/ 1000, CALLING_PACKAGE_2, /* activity =*/ null, - ShortcutQuery.FLAG_GET_PINNED | ShortcutQuery.FLAG_GET_DYNAMIC, - getCallingUserId())), + ShortcutQuery.FLAG_GET_PINNED | ShortcutQuery.FLAG_GET_DYNAMIC), + getCallingUser())), "s2", "s3")))); // FLAG_GET_KEY_FIELDS_ONLY assertAllDynamic(assertAllNotHaveTitle(assertAllNotHaveIntents(assertShortcutIds( - assertAllKeyFieldsOnly(mInternal.getShortcuts(getCallingPackage(), + assertAllKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery( /* time =*/ 1000, CALLING_PACKAGE_2, /* activity =*/ null, - ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY, - getCallingUserId())), + ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY), + getCallingUser())), "s2", "s3")))); // Pin some shortcuts. - mInternal.pinShortcuts(getCallingPackage(), CALLING_PACKAGE_2, - Arrays.asList("s3", "s4"), getCallingUserId()); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, + Arrays.asList("s3", "s4"), getCallingUser()); // Pinned ones only assertAllPinned(assertAllHaveTitle(assertAllNotHaveIntents(assertShortcutIds( - assertAllNotKeyFieldsOnly(mInternal.getShortcuts(getCallingPackage(), + assertAllNotKeyFieldsOnly(mLauncherApps.getShortcuts(buildQuery( /* time =*/ 1000, CALLING_PACKAGE_2, /* activity =*/ null, - ShortcutQuery.FLAG_GET_PINNED, - getCallingUserId())), + ShortcutQuery.FLAG_GET_PINNED), + getCallingUser())), "s3")))); // All packages. assertShortcutIds(assertAllNotKeyFieldsOnly( - mInternal.getShortcuts(getCallingPackage(), + mLauncherApps.getShortcuts(buildQuery( /* time =*/ 5000, /* package= */ null, /* activity =*/ null, - ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_PINNED, - getCallingUserId())), + ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_PINNED), + getCallingUser())), "s1", "s3"); // TODO More tests: pinned but dynamic, filter by activity @@ -1423,8 +1621,8 @@ public class ShortcutManagerTest extends AndroidTestCase { // Pin some. setCaller(LAUNCHER_1); - mInternal.pinShortcuts(getCallingPackage(), CALLING_PACKAGE_1, - Arrays.asList("s2"), getCallingUserId()); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, + Arrays.asList("s2"), getCallingUser()); dumpsysOnLogcat(); @@ -1442,20 +1640,20 @@ public class ShortcutManagerTest extends AndroidTestCase { // Note we don't guarantee the orders. list = assertShortcutIds(assertAllHaveTitle(assertAllNotHaveIntents( assertAllNotKeyFieldsOnly( - mInternal.getShortcutInfo(getCallingPackage(), CALLING_PACKAGE_1, - Arrays.asList("s2", "s1", "s3", null), getCallingUserId())))), + mLauncherApps.getShortcutInfo(CALLING_PACKAGE_1, + Arrays.asList("s2", "s1", "s3", null), getCallingUser())))), "s1", "s2"); assertEquals("Title 1", findById(list, "s1").getTitle()); assertEquals("Title 2", findById(list, "s2").getTitle()); assertShortcutIds(assertAllHaveTitle(assertAllNotHaveIntents( - mInternal.getShortcutInfo(getCallingPackage(), CALLING_PACKAGE_1, - Arrays.asList("s3"), getCallingUserId()))) + mLauncherApps.getShortcutInfo(CALLING_PACKAGE_1, + Arrays.asList("s3"), getCallingUser()))) /* none */); list = assertShortcutIds(assertAllHaveTitle(assertAllNotHaveIntents( - mInternal.getShortcutInfo(getCallingPackage(), CALLING_PACKAGE_2, - Arrays.asList("s1", "s2", "s3"), getCallingUserId()))), + mLauncherApps.getShortcutInfo(CALLING_PACKAGE_2, + Arrays.asList("s1", "s2", "s3"), getCallingUser()))), "s1"); assertEquals("ABC", findById(list, "s1").getTitle()); } @@ -1481,14 +1679,14 @@ public class ShortcutManagerTest extends AndroidTestCase { // Pin some. setCaller(LAUNCHER_1); - mInternal.pinShortcuts(getCallingPackage(), CALLING_PACKAGE_1, - Arrays.asList("s2", "s3"), getCallingUserId()); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, + Arrays.asList("s2", "s3"), getCallingUser()); - mInternal.pinShortcuts(getCallingPackage(), CALLING_PACKAGE_2, - Arrays.asList("s3", "s4", "s5"), getCallingUserId()); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, + Arrays.asList("s3", "s4", "s5"), getCallingUser()); - mInternal.pinShortcuts(getCallingPackage(), CALLING_PACKAGE_3, - Arrays.asList("s3"), getCallingUserId()); // Note ID doesn't exist + mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, + Arrays.asList("s3"), getCallingUser()); // Note ID doesn't exist // Delete some. setCaller(CALLING_PACKAGE_1); @@ -1511,18 +1709,18 @@ public class ShortcutManagerTest extends AndroidTestCase { // CALLING_PACKAGE_1 deleted s2, but it's pinned, so it still exists. assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly( - mInternal.getShortcuts(getCallingPackage(), /* time =*/ 0, CALLING_PACKAGE_1, - /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED, getCallingUserId()))), + mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1, + /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))), "s2"); assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly( - mInternal.getShortcuts(getCallingPackage(), /* time =*/ 0, CALLING_PACKAGE_2, - /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED, getCallingUserId()))), + mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2, + /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))), "s3", "s4"); assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly( - mInternal.getShortcuts(getCallingPackage(), /* time =*/ 0, CALLING_PACKAGE_3, - /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED, getCallingUserId()))) + mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_3, + /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))) /* none */); } @@ -1561,11 +1759,11 @@ public class ShortcutManagerTest extends AndroidTestCase { // Pin all. setCaller(LAUNCHER_1); - mInternal.pinShortcuts(getCallingPackage(), CALLING_PACKAGE_1, - Arrays.asList("s1", "s2"), getCallingUserId()); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, + Arrays.asList("s1", "s2"), getCallingUser()); - mInternal.pinShortcuts(getCallingPackage(), CALLING_PACKAGE_2, - Arrays.asList("s1"), getCallingUserId()); + mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, + Arrays.asList("s1"), getCallingUser()); // Just to make it complicated, delete some. setCaller(CALLING_PACKAGE_1); diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/services/usage/java/com/android/server/usage/AppIdleHistory.java index 3e2b43d2af5c..a3313c9741cd 100644 --- a/services/usage/java/com/android/server/usage/AppIdleHistory.java +++ b/services/usage/java/com/android/server/usage/AppIdleHistory.java @@ -274,6 +274,11 @@ public class AppIdleHistory { - (idle ? mScreenOnTimeThreshold : 0) - 1000 /* just a second more */; } + public void clearUsageLocked(String packageName, int userId) { + ArrayMap<String, PackageHistory> userHistory = getUserHistoryLocked(userId); + userHistory.remove(packageName); + } + private boolean hasPassedThresholdsLocked(PackageHistory packageHistory, long elapsedRealtime) { return (packageHistory.lastUsedScreenTime <= getScreenOnTimeLocked(elapsedRealtime) - mScreenOnTimeThreshold) diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java index 8da17852b437..beec40f8b0fa 100644 --- a/services/usage/java/com/android/server/usage/UsageStatsService.java +++ b/services/usage/java/com/android/server/usage/UsageStatsService.java @@ -180,6 +180,7 @@ public class UsageStatsService extends SystemService implements IntentFilter packageFilter = new IntentFilter(); packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED); packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED); + packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); packageFilter.addDataScheme("package"); getContext().registerReceiverAsUser(new PackageReceiver(), UserHandle.ALL, packageFilter, @@ -266,6 +267,12 @@ public class UsageStatsService extends SystemService implements || Intent.ACTION_PACKAGE_CHANGED.equals(action)) { clearCarrierPrivilegedApps(); } + if ((Intent.ACTION_PACKAGE_REMOVED.equals(action) || + Intent.ACTION_PACKAGE_ADDED.equals(action)) + && !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { + clearAppIdleForPackage(intent.getData().getSchemeSpecificPart(), + getSendingUserId()); + } } } @@ -332,6 +339,12 @@ public class UsageStatsService extends SystemService implements } } + void clearAppIdleForPackage(String packageName, int userId) { + synchronized (mLock) { + mAppIdleHistory.clearUsageLocked(packageName, userId); + } + } + private void cleanUpRemovedUsersLocked() { final List<UserInfo> users = mUserManager.getUsers(true); if (users == null || users.size() == 0) { diff --git a/telephony/java/com/android/ims/ImsExternalCallState.aidl b/telephony/java/com/android/ims/ImsExternalCallState.aidl new file mode 100644 index 000000000000..c208702a8c34 --- /dev/null +++ b/telephony/java/com/android/ims/ImsExternalCallState.aidl @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +parcelable ImsExternalCallState; diff --git a/telephony/java/com/android/ims/ImsExternalCallState.java b/telephony/java/com/android/ims/ImsExternalCallState.java new file mode 100644 index 000000000000..edb6bfcf68c0 --- /dev/null +++ b/telephony/java/com/android/ims/ImsExternalCallState.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims; + +import android.net.Uri; +import android.os.Parcel; +import android.os.Parcelable; +import android.telephony.Rlog; + +/* + * This file contains all the api's through which + * information received in Dialog Event Package can be + * queried + */ + +/** + * Parcelable object to handle VICE Dialog Information + * @hide + */ +public class ImsExternalCallState implements Parcelable { + + private static final String TAG = "ImsExternalCallState"; + + // Dialog States + public static final int CALL_STATE_CONFIRMED = 1; + public static final int CALL_STATE_TERMINATED = 2; + // Dialog Id + public int mCallId; + // Number + public Uri mAddress; + public boolean mIsPullable; + // CALL_STATE_CONFIRMED / CALL_STATE_TERMINATED + public int mCallState; + // ImsCallProfile#CALL_TYPE_* + public int mCallType; + public boolean mIsHeld; + + public ImsExternalCallState() { + } + + public ImsExternalCallState(Parcel in) { + mCallId = in.readInt(); + ClassLoader classLoader = ImsExternalCallState.class.getClassLoader(); + mAddress = in.readParcelable(classLoader); + mIsPullable = (in.readInt() != 0); + mCallState = in.readInt(); + mCallType = in.readInt(); + mIsHeld = (in.readInt() != 0); + Rlog.d(TAG, "ImsExternalCallState const = " + + "callid = " + getCallId() + + ", address = " + getAddress() + + ", mCallState = " + getCallState() + + ", calltype = " + getCallType() + + ", isheld = " + isCallHeld()); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mCallId); + out.writeParcelable(mAddress, 0); + out.writeInt(mIsPullable ? 1 : 0); + out.writeInt(mCallState); + out.writeInt(mCallType); + out.writeInt(mIsHeld ? 1 : 0); + } + + public static final Parcelable.Creator<ImsExternalCallState> CREATOR = + new Parcelable.Creator<ImsExternalCallState>() { + @Override + public ImsExternalCallState createFromParcel(Parcel in) { + return new ImsExternalCallState(in); + } + + @Override + public ImsExternalCallState[] newArray(int size) { + return new ImsExternalCallState[size]; + } + }; + + public int getCallId() { + return mCallId; + } + + public Uri getAddress() { + return mAddress; + } + + public boolean isCallPullable() { + return mIsPullable; + } + + public int getCallState() { + return mCallState; + } + + public int getCallType() { + return mCallType; + } + + public boolean isCallHeld() { + return mIsHeld; + } + + @Override + public String toString() { + return "ImsExternalCallState { mCallId = " + mCallId + + ", mAddress = " + mAddress + + ", mIsPullable = " + mIsPullable + + ", mCallState = " + mCallState + + ", mCallType = " + mCallType + + ", mIsHeld = " + mIsHeld + "}"; + } +} diff --git a/telephony/java/com/android/ims/ImsReasonInfo.java b/telephony/java/com/android/ims/ImsReasonInfo.java index 558c1dc1866c..f06d15456ac0 100644 --- a/telephony/java/com/android/ims/ImsReasonInfo.java +++ b/telephony/java/com/android/ims/ImsReasonInfo.java @@ -241,12 +241,12 @@ public class ImsReasonInfo implements Parcelable { public static final int CODE_ANSWERED_ELSEWHERE = 1014; /** - * Call pull request failure from the network. + * For MultiEndpoint - Call Pull request has failed */ public static final int CODE_CALL_PULL_OUT_OF_SYNC = 1015; /** - * Call ended due to being pulled onto another device. + * For MultiEndpoint - Call has been pulled from primary to secondary */ public static final int CODE_CALL_END_CAUSE_CALL_PULL = 1016; diff --git a/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl b/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl new file mode 100644 index 000000000000..70a474ec41da --- /dev/null +++ b/telephony/java/com/android/ims/internal/IImsExternalCallStateListener.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims.internal; + +import com.android.ims.ImsExternalCallState; + +/** + * A listener type for receiving notifications about DEP through IMS + * + * {@hide} + */ +interface IImsExternalCallStateListener { + + /** + * Notifies client when Dialog Event Package update is received + * + * @param List<ImsExternalCallState> - External Call Dialog + * + * @return void. + */ + void notifyRefreshExternalCallState(in List<ImsExternalCallState> externalCallDialogs); + +} + diff --git a/telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl b/telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl new file mode 100644 index 000000000000..1bfb9b2b4d78 --- /dev/null +++ b/telephony/java/com/android/ims/internal/IImsMultiEndpoint.aidl @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.ims.internal; + +import com.android.ims.internal.IImsExternalCallStateListener; + +/** + * Provides the ImsMultiEndpoint interface + * + * {@hide} + */ +interface IImsMultiEndpoint { + /** + * Sets the listener. + */ + void setListener(in IImsExternalCallStateListener listener); + + + /** + * Query api to get the latest Dialog Event Package information + * Should be invoked only after setListener is done + */ + void requestDialogEventPackageState(); +} diff --git a/telephony/java/com/android/ims/internal/IImsService.aidl b/telephony/java/com/android/ims/internal/IImsService.aidl index 30c48d7a839a..a9614a63d872 100644 --- a/telephony/java/com/android/ims/internal/IImsService.aidl +++ b/telephony/java/com/android/ims/internal/IImsService.aidl @@ -19,12 +19,13 @@ package com.android.ims.internal; import android.app.PendingIntent; import com.android.ims.ImsCallProfile; -import com.android.ims.internal.IImsRegistrationListener; import com.android.ims.internal.IImsCallSession; import com.android.ims.internal.IImsCallSessionListener; +import com.android.ims.internal.IImsConfig; import com.android.ims.internal.IImsEcbm; +import com.android.ims.internal.IImsMultiEndpoint; +import com.android.ims.internal.IImsRegistrationListener; import com.android.ims.internal.IImsUt; -import com.android.ims.internal.IImsConfig; import android.os.Message; @@ -75,4 +76,9 @@ interface IImsService { * Used to set current TTY Mode. */ void setUiTTYMode(int serviceId, int uiTtyMode, in Message onComplete); + + /** + * MultiEndpoint interface for DEP. + */ + IImsMultiEndpoint getMultiEndpointInterface(int serviceId); } diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java index bba357e07147..7f90731d2f72 100644 --- a/telephony/java/com/android/internal/telephony/RILConstants.java +++ b/telephony/java/com/android/internal/telephony/RILConstants.java @@ -92,6 +92,11 @@ public interface RILConstants { int NO_SMS_TO_ACK = 48; /* ACK received when there is no SMS to ack */ int NETWORK_ERR = 49; /* Received error from network */ int REQUEST_RATE_LIMITED = 50; /* Operation denied due to overly-frequent requests */ + int SIM_BUSY = 51; /* SIM is busy */ + int SIM_FULL = 52; /* The target EF is full */ + int NETWORK_REJECT = 53; /* Request is rejected by network */ + int OPERATION_NOT_ALLOWED = 54; /* Not allowed the request now */ + int EMPTY_RECORD = 55; /* The request record is empty */ // Below is list of OEM specific error codes which can by used by OEMs in case they don't want to // reveal particular replacement for Generic failure int OEM_ERROR_1 = 501; diff --git a/telephony/java/com/android/internal/telephony/TelephonyProperties.java b/telephony/java/com/android/internal/telephony/TelephonyProperties.java index 645c3a17db14..ea3b5c97c4c9 100644 --- a/telephony/java/com/android/internal/telephony/TelephonyProperties.java +++ b/telephony/java/com/android/internal/telephony/TelephonyProperties.java @@ -217,4 +217,12 @@ public interface TelephonyProperties * or Earpiece, based on the default audio routing strategy. */ static final String PROPERTY_VIDEOCALL_AUDIO_OUTPUT = "persist.radio.call.audio.output"; + + /** + * For MultiEndpoint Feature + * If true: Dial intent is for call pull functionality + * if false: normal dial + */ + static final String EXTRA_IS_CALL_PULL = + "android.telephony.extra.IS_CALL_PULL"; } diff --git a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs b/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs index caa947d2b386..0a1742ef3867 100644 --- a/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs +++ b/tests/CanvasCompare/src/com/android/test/hwuicompare/errorCalculator.rs @@ -14,10 +14,14 @@ void countInterestingRegions(const int32_t *v_in, int32_t *v_out) { for (int x = 0; x < HEIGHT; x += REGION_SIZE) { bool interestingRegion = false; - int regionColor = (int) rsGetElementAt_uchar4(ideal, x, y); + uchar4 regionColor = rsGetElementAt_uchar4(ideal, x, y); for (int i = 0; i < REGION_SIZE && !interestingRegion; i++) { for (int j = 0; j < REGION_SIZE && !interestingRegion; j++) { - interestingRegion |= ((int) rsGetElementAt_uchar4(ideal, x + j, y + i)) != regionColor; + uchar4 testVal = rsGetElementAt_uchar4(ideal, x + j, y + i); + interestingRegion |= (testVal.r != regionColor.r); + interestingRegion |= (testVal.g != regionColor.g); + interestingRegion |= (testVal.b != regionColor.b); + interestingRegion |= (testVal.a != regionColor.a); } } if (interestingRegion) { diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk index d311b3d41a70..85d22ffacd4c 100644 --- a/tools/aapt2/Android.mk +++ b/tools/aapt2/Android.mk @@ -125,10 +125,12 @@ hostStaticLibs := \ libexpat \ libziparchive-host \ libpng \ - libbase + libbase \ + libprotobuf-cpp-lite_static -hostSharedLibs := \ - libprotobuf-cpp-lite +# Do not add any shared libraries. AAPT2 is built to run on many +# environments that may not have the required dependencies. +hostSharedLibs := ifneq ($(strip $(USE_MINGW)),) hostStaticLibs += libz diff --git a/tools/fonts/fontchain_lint.py b/tools/fonts/fontchain_lint.py new file mode 100755 index 000000000000..fb2213cdad57 --- /dev/null +++ b/tools/fonts/fontchain_lint.py @@ -0,0 +1,157 @@ +#!/usr/bin/env python + +import collections +import glob +from os import path +import sys +from xml.etree import ElementTree + +from fontTools import ttLib + +LANG_TO_SCRIPT = { + 'de': 'Latn', + 'en': 'Latn', + 'es': 'Latn', + 'eu': 'Latn', + 'ja': 'Jpan', + 'ko': 'Kore', + 'hu': 'Latn', + 'hy': 'Armn', + 'nb': 'Latn', + 'nn': 'Latn', + 'pt': 'Latn', +} + +def lang_to_script(lang_code): + lang = lang_code.lower() + while lang not in LANG_TO_SCRIPT: + hyphen_idx = lang.rfind('-') + assert hyphen_idx != -1, ( + 'We do not know what script the "%s" language is written in.' + % lang_code) + assumed_script = lang[hyphen_idx+1:] + if len(assumed_script) == 4 and assumed_script.isalpha(): + # This is actually the script + return assumed_script.title() + lang = lang[:hyphen_idx] + return LANG_TO_SCRIPT[lang] + + +def get_best_cmap(font): + font_file, index = font + font_path = path.join(_fonts_dir, font_file) + if index is not None: + ttfont = ttLib.TTFont(font_path, fontNumber=index) + else: + ttfont = ttLib.TTFont(font_path) + all_unicode_cmap = None + bmp_cmap = None + for cmap in ttfont['cmap'].tables: + specifier = (cmap.format, cmap.platformID, cmap.platEncID) + if specifier == (4, 3, 1): + assert bmp_cmap is None, 'More than one BMP cmap in %s' % (font, ) + bmp_cmap = cmap + elif specifier == (12, 3, 10): + assert all_unicode_cmap is None, ( + 'More than one UCS-4 cmap in %s' % (font, )) + all_unicode_cmap = cmap + + return all_unicode_cmap.cmap if all_unicode_cmap else bmp_cmap.cmap + + +def assert_font_supports_any_of_chars(font, chars): + best_cmap = get_best_cmap(font) + for char in chars: + if char in best_cmap: + return + sys.exit('None of characters in %s were found in %s' % (chars, font)) + + +def check_hyphens(hyphens_dir): + # Find all the scripts that need automatic hyphenation + scripts = set() + for hyb_file in glob.iglob(path.join(hyphens_dir, '*.hyb')): + hyb_file = path.basename(hyb_file) + assert hyb_file.startswith('hyph-'), ( + 'Unknown hyphenation file %s' % hyb_file) + lang_code = hyb_file[hyb_file.index('-')+1:hyb_file.index('.')] + scripts.add(lang_to_script(lang_code)) + + HYPHENS = {0x002D, 0x2010} + for script in scripts: + fonts = _script_to_font_map[script] + assert fonts, 'No fonts found for the "%s" script' % script + for font in fonts: + assert_font_supports_any_of_chars(font, HYPHENS) + + +def parse_fonts_xml(fonts_xml_path): + global _script_to_font_map, _fallback_chain + _script_to_font_map = collections.defaultdict(set) + _fallback_chain = [] + tree = ElementTree.parse(fonts_xml_path) + for family in tree.findall('family'): + name = family.get('name') + variant = family.get('variant') + langs = family.get('lang') + if name: + assert variant is None, ( + 'No variant expected for LGC font %s.' % name) + assert langs is None, ( + 'No language expected for LGC fonts %s.' % name) + else: + assert variant in {None, 'elegant', 'compact'}, ( + 'Unexpected value for variant: %s' % variant) + + if langs: + langs = langs.split() + scripts = {lang_to_script(lang) for lang in langs} + else: + scripts = set() + + for child in family: + assert child.tag == 'font', ( + 'Unknown tag <%s>' % child.tag) + font_file = child.text + weight = int(child.get('weight')) + assert weight % 100 == 0, ( + 'Font weight "%d" is not a multiple of 100.' % weight) + + style = child.get('style') + assert style in {'normal', 'italic'}, ( + 'Unknown style "%s"' % style) + + index = child.get('index') + if index: + index = int(index) + + _fallback_chain.append(( + name, + frozenset(scripts), + variant, + weight, + style, + (font_file, index))) + + if name: # non-empty names are used for default LGC fonts + map_scripts = {'Latn', 'Grek', 'Cyrl'} + else: + map_scripts = scripts + for script in map_scripts: + _script_to_font_map[script].add((font_file, index)) + + +def main(): + target_out = sys.argv[1] + global _fonts_dir + _fonts_dir = path.join(target_out, 'fonts') + + fonts_xml_path = path.join(target_out, 'etc', 'fonts.xml') + parse_fonts_xml(fonts_xml_path) + + hyphens_dir = path.join(target_out, 'usr', 'hyphen-data') + check_hyphens(hyphens_dir) + + +if __name__ == '__main__': + main() diff --git a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java index e3bb3e318749..6d8ecd7c1b96 100644 --- a/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java +++ b/tools/layoutlib/bridge/src/android/graphics/Bitmap_Delegate.java @@ -67,7 +67,7 @@ public final class Bitmap_Delegate { // ---- delegate manager ---- private static final DelegateManager<Bitmap_Delegate> sManager = - new DelegateManager<Bitmap_Delegate>(Bitmap_Delegate.class); + new DelegateManager<>(Bitmap_Delegate.class); private static long sFinalizer = -1; // ---- delegate helper data ---- @@ -314,7 +314,7 @@ public final class Bitmap_Delegate { @LayoutlibDelegate /*package*/ static boolean nativeRecycle(long nativeBitmap) { - sManager.removeJavaReferenceFor(nativeBitmap); + // In our case reycle() is a no-op. We will let the finalizer to dispose the bitmap. return true; } diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index a5bfd3c094bc..823fd26c7904 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -21,7 +21,6 @@ import android.annotation.SdkConstant.SdkConstantType; import android.annotation.SystemApi; import android.content.Context; import android.net.ConnectivityManager; -import android.net.ConnectivityManager.NetworkCallback; import android.net.DhcpInfo; import android.net.Network; import android.net.NetworkCapabilities; @@ -666,17 +665,15 @@ public class WifiManager { private final int mTargetSdkVersion; private static final int INVALID_KEY = 0; - private static int sListenerKey = 1; - private static final SparseArray sListenerMap = new SparseArray(); - private static final Object sListenerMapLock = new Object(); + private int mListenerKey = 1; + private final SparseArray mListenerMap = new SparseArray(); + private final Object mListenerMapLock = new Object(); - private static AsyncChannel sAsyncChannel; - private static CountDownLatch sConnected; - private static ConnectivityManager sCM; + private AsyncChannel mAsyncChannel; + private CountDownLatch mConnected; - private static final Object sThreadRefLock = new Object(); - private static int sThreadRefCount; - private static HandlerThread sHandlerThread; + /* TODO(b/27432949): Use a common connectivity thread for this. */ + private HandlerThread mHandlerThread; /** * Create a new WifiManager instance. @@ -1482,7 +1479,7 @@ public class WifiManager { */ public void getTxPacketCount(TxPacketCountListener listener) { validateChannel(); - sAsyncChannel.sendMessage(RSSI_PKTCNT_FETCH, 0, putListener(listener)); + mAsyncChannel.sendMessage(RSSI_PKTCNT_FETCH, 0, putListener(listener)); } /** @@ -1846,25 +1843,34 @@ public class WifiManager { public void onFailure(int reason); } - private static class ServiceHandler extends Handler { + // Ensure that multiple ServiceHandler threads do not interleave message dispatch. + private static final Object sServiceHandlerDispatchLock = new Object(); + + private class ServiceHandler extends Handler { ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message message) { + synchronized (sServiceHandlerDispatchLock) { + dispatchMessageToListeners(message); + } + } + + private void dispatchMessageToListeners(Message message) { Object listener = removeListener(message.arg2); switch (message.what) { case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: if (message.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { - sAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); + mAsyncChannel.sendMessage(AsyncChannel.CMD_CHANNEL_FULL_CONNECTION); } else { Log.e(TAG, "Failed to set up channel connection"); // This will cause all further async API calls on the WifiManager // to fail and throw an exception - sAsyncChannel = null; + mAsyncChannel = null; } - sConnected.countDown(); + mConnected.countDown(); break; case AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED: // Ignore @@ -1873,7 +1879,7 @@ public class WifiManager { Log.e(TAG, "Channel connection lost"); // This will cause all further async API calls on the WifiManager // to fail and throw an exception - sAsyncChannel = null; + mAsyncChannel = null; getLooper().quit(); break; /* ActionListeners grouped together */ @@ -1899,8 +1905,8 @@ public class WifiManager { WpsResult result = (WpsResult) message.obj; ((WpsCallback) listener).onStarted(result.pin); //Listener needs to stay until completion or failure - synchronized(sListenerMapLock) { - sListenerMap.put(message.arg2, listener); + synchronized (mListenerMapLock) { + mListenerMap.put(message.arg2, listener); } } break; @@ -1945,54 +1951,50 @@ public class WifiManager { } } - private static int putListener(Object listener) { + private int putListener(Object listener) { if (listener == null) return INVALID_KEY; int key; - synchronized (sListenerMapLock) { + synchronized (mListenerMapLock) { do { - key = sListenerKey++; + key = mListenerKey++; } while (key == INVALID_KEY); - sListenerMap.put(key, listener); + mListenerMap.put(key, listener); } return key; } - private static Object removeListener(int key) { + private Object removeListener(int key) { if (key == INVALID_KEY) return null; - synchronized (sListenerMapLock) { - Object listener = sListenerMap.get(key); - sListenerMap.remove(key); + synchronized (mListenerMapLock) { + Object listener = mListenerMap.get(key); + mListenerMap.remove(key); return listener; } } private void init() { - synchronized (sThreadRefLock) { - if (++sThreadRefCount == 1) { - Messenger messenger = getWifiServiceMessenger(); - if (messenger == null) { - sAsyncChannel = null; - return; - } + Messenger messenger = getWifiServiceMessenger(); + if (messenger == null) { + mAsyncChannel = null; + return; + } - sHandlerThread = new HandlerThread("WifiManager"); - sAsyncChannel = new AsyncChannel(); - sConnected = new CountDownLatch(1); - - sHandlerThread.start(); - Handler handler = new ServiceHandler(sHandlerThread.getLooper()); - sAsyncChannel.connect(mContext, handler, messenger); - try { - sConnected.await(); - } catch (InterruptedException e) { - Log.e(TAG, "interrupted wait at init"); - } - } + mHandlerThread = new HandlerThread("WifiManager"); + mAsyncChannel = new AsyncChannel(); + mConnected = new CountDownLatch(1); + + mHandlerThread.start(); + Handler handler = new ServiceHandler(mHandlerThread.getLooper()); + mAsyncChannel.connect(mContext, handler, messenger); + try { + mConnected.await(); + } catch (InterruptedException e) { + Log.e(TAG, "interrupted wait at init"); } } private void validateChannel() { - if (sAsyncChannel == null) throw new IllegalStateException( + if (mAsyncChannel == null) throw new IllegalStateException( "No permission to access and change wifi or a bad initialization"); } @@ -2017,7 +2019,7 @@ public class WifiManager { validateChannel(); // Use INVALID_NETWORK_ID for arg1 when passing a config object // arg1 is used to pass network id when the network already exists - sAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID, + mAsyncChannel.sendMessage(CONNECT_NETWORK, WifiConfiguration.INVALID_NETWORK_ID, putListener(listener), config); } @@ -2037,7 +2039,7 @@ public class WifiManager { public void connect(int networkId, ActionListener listener) { if (networkId < 0) throw new IllegalArgumentException("Network id cannot be negative"); validateChannel(); - sAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener)); + mAsyncChannel.sendMessage(CONNECT_NETWORK, networkId, putListener(listener)); } /** @@ -2061,7 +2063,7 @@ public class WifiManager { public void save(WifiConfiguration config, ActionListener listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); validateChannel(); - sAsyncChannel.sendMessage(SAVE_NETWORK, 0, putListener(listener), config); + mAsyncChannel.sendMessage(SAVE_NETWORK, 0, putListener(listener), config); } /** @@ -2080,7 +2082,7 @@ public class WifiManager { public void forget(int netId, ActionListener listener) { if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); validateChannel(); - sAsyncChannel.sendMessage(FORGET_NETWORK, netId, putListener(listener)); + mAsyncChannel.sendMessage(FORGET_NETWORK, netId, putListener(listener)); } /** @@ -2095,7 +2097,7 @@ public class WifiManager { public void disable(int netId, ActionListener listener) { if (netId < 0) throw new IllegalArgumentException("Network id cannot be negative"); validateChannel(); - sAsyncChannel.sendMessage(DISABLE_NETWORK, netId, putListener(listener)); + mAsyncChannel.sendMessage(DISABLE_NETWORK, netId, putListener(listener)); } /** @@ -2124,7 +2126,7 @@ public class WifiManager { public void startWps(WpsInfo config, WpsCallback listener) { if (config == null) throw new IllegalArgumentException("config cannot be null"); validateChannel(); - sAsyncChannel.sendMessage(START_WPS, 0, putListener(listener), config); + mAsyncChannel.sendMessage(START_WPS, 0, putListener(listener), config); } /** @@ -2136,7 +2138,7 @@ public class WifiManager { */ public void cancelWps(WpsCallback listener) { validateChannel(); - sAsyncChannel.sendMessage(CANCEL_WPS, 0, putListener(listener)); + mAsyncChannel.sendMessage(CANCEL_WPS, 0, putListener(listener)); } /** @@ -2601,10 +2603,8 @@ public class WifiManager { protected void finalize() throws Throwable { try { - synchronized (sThreadRefLock) { - if (--sThreadRefCount == 0 && sAsyncChannel != null) { - sAsyncChannel.disconnect(); - } + if (mAsyncChannel != null) { + mAsyncChannel.disconnect(); } } finally { super.finalize(); |