diff options
917 files changed, 19945 insertions, 5548 deletions
diff --git a/Android.mk b/Android.mk index 7551a8708bd4..0bd6b7f925d2 100644 --- a/Android.mk +++ b/Android.mk @@ -829,6 +829,7 @@ framework_docs_LOCAL_DROIDDOC_OPTIONS := \ -since $(SRC_API_DIR)/21.txt 21 \ -since $(SRC_API_DIR)/22.txt 22 \ -since $(SRC_API_DIR)/23.txt 23 \ + -since ./frameworks/base/api/current.txt N \ -werror -hide 111 -hide 113 \ -overview $(LOCAL_PATH)/core/java/overview.html @@ -872,9 +873,11 @@ framework_docs_SDK_VERSION:=6.0 framework_docs_SDK_REL_ID:=1 framework_docs_LOCAL_DROIDDOC_OPTIONS += \ + -hdf sdk.codename N \ + -hdf sdk.preview.version 2 \ -hdf sdk.version $(framework_docs_SDK_VERSION) \ -hdf sdk.rel.id $(framework_docs_SDK_REL_ID) \ - -hdf sdk.preview 0 + -hdf sdk.preview 1 # ==== the api stubs and current.xml =========================== include $(CLEAR_VARS) @@ -1029,23 +1032,24 @@ LOCAL_DROIDDOC_OPTIONS:=\ -offlinemode \ -title "Android SDK" \ -proofread $(OUT_DOCS)/$(LOCAL_MODULE)-proofread.txt \ - -todo $(OUT_DOCS)/$(LOCAL_MODULE)-docs-todo.html \ -sdkvalues $(OUT_DOCS) \ - -hdf android.whichdoc offline + -hdf android.whichdoc offline \ + -referenceonly -LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk +LOCAL_DROIDDOC_CUSTOM_TEMPLATE_DIR:=build/tools/droiddoc/templates-sdk-refonly include $(BUILD_DROIDDOC) static_doc_index_redirect := $(out_dir)/index.html $(static_doc_index_redirect): \ - $(LOCAL_PATH)/docs/docs-documentation-redirect.html | $(ACP) + $(LOCAL_PATH)/docs/docs-preview-index.html | $(ACP) $(hide) mkdir -p $(dir $@) $(hide) $(ACP) $< $@ $(full_target): $(static_doc_index_redirect) $(full_target): $(framework_built) + # ==== docs for the web (on the androiddevdocs app engine server) ======================= include $(CLEAR_VARS) diff --git a/api/current.txt b/api/current.txt index cc386db74ef4..1944157d04b8 100644 --- a/api/current.txt +++ b/api/current.txt @@ -879,6 +879,7 @@ package android { field public static final int nextFocusLeft = 16842977; // 0x10100e1 field public static final int nextFocusRight = 16842978; // 0x10100e2 field public static final int nextFocusUp = 16842979; // 0x10100e3 + field public static final int nfcAntennaPositionDrawable = 16844063; // 0x101051f field public static final int noHistory = 16843309; // 0x101022d field public static final int normalScreens = 16843397; // 0x1010285 field public static final int notificationTimeout = 16843651; // 0x1010383 @@ -5978,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"; @@ -8112,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"; @@ -8142,6 +8144,7 @@ package android.content { field public static final java.lang.String SENSOR_SERVICE = "sensor"; field public static final java.lang.String SHORTCUT_SERVICE = "shortcut"; field public static final java.lang.String STORAGE_SERVICE = "storage"; + field public static final java.lang.String SYSTEM_HEALTH_SERVICE = "systemhealth"; field public static final java.lang.String TELECOM_SERVICE = "telecom"; field public static final java.lang.String TELEPHONY_SERVICE = "phone"; field public static final java.lang.String TELEPHONY_SUBSCRIPTION_SERVICE = "telephony_subscription_service"; @@ -9325,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; @@ -9560,6 +9564,7 @@ package android.content.pm { method public java.lang.String[] getNames() throws java.io.IOException; method public java.io.InputStream openRead(java.lang.String) throws java.io.IOException; method public java.io.OutputStream openWrite(java.lang.String, long, long) throws java.io.IOException; + method public void removeSplit(java.lang.String) throws java.io.IOException; method public void setStagingProgress(float); } @@ -9994,6 +9999,7 @@ package android.content.pm { method public int getWeight(); method public boolean hasIconFile(); method public boolean hasIconResource(); + method public boolean hasKeyFieldsOnly(); method public boolean isDynamic(); method public boolean isPinned(); method public void writeToParcel(android.os.Parcel, int); @@ -10004,6 +10010,7 @@ package android.content.pm { field public static final int FLAG_DYNAMIC = 1; // 0x1 field public static final int FLAG_HAS_ICON_FILE = 8; // 0x8 field public static final int FLAG_HAS_ICON_RES = 4; // 0x4 + field public static final int FLAG_KEY_FIELDS_ONLY = 16; // 0x10 field public static final int FLAG_PINNED = 2; // 0x2 } @@ -10024,6 +10031,7 @@ package android.content.pm { method public void deleteAllDynamicShortcuts(); method public void deleteDynamicShortcut(java.lang.String); method public java.util.List<android.content.pm.ShortcutInfo> getDynamicShortcuts(); + method public int getIconMaxDimensions(); method public int getMaxDynamicShortcutCount(); method public java.util.List<android.content.pm.ShortcutInfo> getPinnedShortcuts(); method public long getRateLimitResetTime(); @@ -12907,7 +12915,8 @@ package android.graphics.drawable { method public int getGradientType(); method public int getOpacity(); method public android.graphics.drawable.GradientDrawable.Orientation getOrientation(); - method public boolean isUseLevel(); + method public int getShape(); + method public boolean getUseLevel(); method public void setAlpha(int); method public void setColor(int); method public void setColor(android.content.res.ColorStateList); @@ -13769,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); @@ -19242,24 +19252,6 @@ package android.location { method public boolean hasFullBiasNanos(); method public boolean hasLeapSecond(); method public boolean hasTimeUncertaintyNanos(); - method public void reset(); - method public void resetBiasNanos(); - method public void resetBiasUncertaintyNanos(); - method public void resetDriftNanosPerSecond(); - method public void resetDriftUncertaintyNanosPerSecond(); - method public void resetFullBiasNanos(); - method public void resetLeapSecond(); - method public void resetTimeUncertaintyNanos(); - method public void set(android.location.GnssClock); - method public void setBiasNanos(double); - method public void setBiasUncertaintyNanos(double); - method public void setDriftNanosPerSecond(double); - method public void setDriftUncertaintyNanosPerSecond(double); - method public void setFullBiasNanos(long); - method public void setHardwareClockDiscontinuityCount(int); - method public void setLeapSecond(int); - method public void setTimeNanos(long); - method public void setTimeUncertaintyNanos(double); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.location.GnssClock> CREATOR; } @@ -19290,31 +19282,6 @@ package android.location { method public boolean hasCarrierPhaseUncertainty(); method public boolean hasSnrInDb(); method public boolean isPseudorangeRateCorrected(); - method public void reset(); - method public void resetCarrierCycles(); - method public void resetCarrierFrequencyHz(); - method public void resetCarrierPhase(); - method public void resetCarrierPhaseUncertainty(); - method public void resetSnrInDb(); - method public void set(android.location.GnssMeasurement); - method public void setAccumulatedDeltaRangeMeters(double); - method public void setAccumulatedDeltaRangeState(int); - method public void setAccumulatedDeltaRangeUncertaintyMeters(double); - method public void setCarrierCycles(long); - method public void setCarrierFrequencyHz(float); - method public void setCarrierPhase(double); - method public void setCarrierPhaseUncertainty(double); - method public void setCn0DbHz(double); - method public void setConstellationType(int); - method public void setMultipathIndicator(int); - method public void setPseudorangeRateMetersPerSecond(double); - method public void setPseudorangeRateUncertaintyMetersPerSecond(double); - method public void setReceivedSvTimeNanos(long); - method public void setReceivedSvTimeUncertaintyNanos(long); - method public void setSnrInDb(double); - method public void setState(int); - method public void setSvid(int); - method public void setTimeOffsetNanos(double); method public void writeToParcel(android.os.Parcel, int); field public static final int ADR_STATE_CYCLE_SLIP = 4; // 0x4 field public static final int ADR_STATE_RESET = 2; // 0x2 @@ -19364,14 +19331,6 @@ package android.location { method public int getSubmessageId(); method public int getSvid(); method public int getType(); - method public void reset(); - method public void set(android.location.GnssNavigationMessage); - method public void setData(byte[]); - method public void setMessageId(int); - method public void setStatus(int); - method public void setSubmessageId(int); - method public void setSvid(int); - method public void setType(int); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessage> CREATOR; field public static final int STATUS_PARITY_PASSED = 1; // 0x1 @@ -20227,37 +20186,129 @@ package android.media { field public static final int ORIENTATION_TRANSVERSE = 7; // 0x7 field public static final int ORIENTATION_UNDEFINED = 0; // 0x0 field public static final java.lang.String TAG_APERTURE = "FNumber"; + field public static final java.lang.String TAG_APERTURE_VALUE = "ApertureValue"; + field public static final java.lang.String TAG_ARTIST = "Artist"; + field public static final java.lang.String TAG_BITS_PER_SAMPLE = "BitsPerSample"; + field public static final java.lang.String TAG_BRIGHTNESS_VALUE = "BrightnessValue"; + field public static final java.lang.String TAG_CFA_PATTERN = "CFAPattern"; + field public static final java.lang.String TAG_COLOR_SPACE = "ColorSpace"; + field public static final java.lang.String TAG_COMPONENTS_CONFIGURATION = "ComponentsConfiguration"; + field public static final java.lang.String TAG_COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel"; + field public static final java.lang.String TAG_COMPRESSION = "Compression"; + field public static final java.lang.String TAG_CONTRAST = "Contrast"; + field public static final java.lang.String TAG_COPYRIGHT = "Copyright"; + field public static final java.lang.String TAG_CUSTOM_RENDERED = "CustomRendered"; field public static final java.lang.String TAG_DATETIME = "DateTime"; field public static final java.lang.String TAG_DATETIME_DIGITIZED = "DateTimeDigitized"; + field public static final java.lang.String TAG_DATETIME_ORIGINAL = "DateTimeOriginal"; + field public static final java.lang.String TAG_DEVICE_SETTING_DESCRIPTION = "DeviceSettingDescription"; field public static final java.lang.String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio"; + field public static final java.lang.String TAG_EXIF_VERSION = "ExifVersion"; field public static final java.lang.String TAG_EXPOSURE_BIAS_VALUE = "ExposureBiasValue"; + field public static final java.lang.String TAG_EXPOSURE_INDEX = "ExposureIndex"; field public static final java.lang.String TAG_EXPOSURE_MODE = "ExposureMode"; field public static final java.lang.String TAG_EXPOSURE_PROGRAM = "ExposureProgram"; field public static final java.lang.String TAG_EXPOSURE_TIME = "ExposureTime"; + field public static final java.lang.String TAG_FILE_SOURCE = "FileSource"; field public static final java.lang.String TAG_FLASH = "Flash"; + field public static final java.lang.String TAG_FLASHPIX_VERSION = "FlashpixVersion"; + field public static final java.lang.String TAG_FLASH_ENERGY = "FlashEnergy"; field public static final java.lang.String TAG_FOCAL_LENGTH = "FocalLength"; + field public static final java.lang.String TAG_FOCAL_LENGTH_IN_35MM_FILM = "FocalLengthIn35mmFilm"; + field public static final java.lang.String TAG_FOCAL_PLANE_RESOLUTION_UNIT = "FocalPlaneResolutionUnit"; + field public static final java.lang.String TAG_FOCAL_PLANE_X_RESOLUTION = "FocalPlaneXResolution"; + field public static final java.lang.String TAG_FOCAL_PLANE_Y_RESOLUTION = "FocalPlaneYResolution"; + field public static final java.lang.String TAG_F_NUMBER = "FNumber"; + field public static final java.lang.String TAG_GAIN_CONTROL = "GainControl"; field public static final java.lang.String TAG_GPS_ALTITUDE = "GPSAltitude"; field public static final java.lang.String TAG_GPS_ALTITUDE_REF = "GPSAltitudeRef"; + field public static final java.lang.String TAG_GPS_AREA_INFORMATION = "GPSAreaInformation"; field public static final java.lang.String TAG_GPS_DATESTAMP = "GPSDateStamp"; + field public static final java.lang.String TAG_GPS_DEST_BEARING = "GPSDestBearing"; + field public static final java.lang.String TAG_GPS_DEST_BEARING_REF = "GPSDestBearingRef"; + field public static final java.lang.String TAG_GPS_DEST_DISTANCE = "GPSDestDistance"; + field public static final java.lang.String TAG_GPS_DEST_DISTANCE_REF = "GPSDestDistanceRef"; + field public static final java.lang.String TAG_GPS_DEST_LATITUDE = "GPSDestLatitude"; + field public static final java.lang.String TAG_GPS_DEST_LATITUDE_REF = "GPSDestLatitudeRef"; + field public static final java.lang.String TAG_GPS_DEST_LONGITUDE = "GPSDestLongitude"; + field public static final java.lang.String TAG_GPS_DEST_LONGITUDE_REF = "GPSDestLongitudeRef"; + field public static final java.lang.String TAG_GPS_DIFFERENTIAL = "GPSDifferential"; + field public static final java.lang.String TAG_GPS_DOP = "GPSDOP"; + field public static final java.lang.String TAG_GPS_IMG_DIRECTION = "GPSImgDirection"; + field public static final java.lang.String TAG_GPS_IMG_DIRECTION_REF = "GPSImgDirectionRef"; field public static final java.lang.String TAG_GPS_LATITUDE = "GPSLatitude"; field public static final java.lang.String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef"; field public static final java.lang.String TAG_GPS_LONGITUDE = "GPSLongitude"; field public static final java.lang.String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef"; + field public static final java.lang.String TAG_GPS_MAP_DATUM = "GPSMapDatum"; + field public static final java.lang.String TAG_GPS_MEASURE_MODE = "GPSMeasureMode"; field public static final java.lang.String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod"; + field public static final java.lang.String TAG_GPS_SATELLITES = "GPSSatellites"; + field public static final java.lang.String TAG_GPS_SPEED = "GPSSpeed"; + field public static final java.lang.String TAG_GPS_SPEED_REF = "GPSSpeedRef"; + field public static final java.lang.String TAG_GPS_STATUS = "GPSStatus"; field public static final java.lang.String TAG_GPS_TIMESTAMP = "GPSTimeStamp"; + field public static final java.lang.String TAG_GPS_TRACK = "GPSTrack"; + field public static final java.lang.String TAG_GPS_TRACK_REF = "GPSTrackRef"; + field public static final java.lang.String TAG_GPS_VERSION_ID = "GPSVersionID"; + field public static final java.lang.String TAG_IMAGE_DESCRIPTION = "ImageDescription"; field public static final java.lang.String TAG_IMAGE_LENGTH = "ImageLength"; + field public static final java.lang.String TAG_IMAGE_UNIQUE_ID = "ImageUniqueID"; field public static final java.lang.String TAG_IMAGE_WIDTH = "ImageWidth"; + field public static final java.lang.String TAG_INTEROPERABILITY_INDEX = "InteroperabilityIndex"; field public static final java.lang.String TAG_ISO = "ISOSpeedRatings"; + field public static final java.lang.String TAG_ISO_SPEED_RATINGS = "ISOSpeedRatings"; + field public static final java.lang.String TAG_JPEG_INTERCHANGE_FORMAT = "JPEGInterchangeFormat"; + field public static final java.lang.String TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = "JPEGInterchangeFormatLength"; field public static final java.lang.String TAG_LIGHT_SOURCE = "LightSource"; field public static final java.lang.String TAG_MAKE = "Make"; + field public static final java.lang.String TAG_MAKER_NOTE = "MakerNote"; + field public static final java.lang.String TAG_MAX_APERTURE_VALUE = "MaxApertureValue"; field public static final java.lang.String TAG_METERING_MODE = "MeteringMode"; field public static final java.lang.String TAG_MODEL = "Model"; + field public static final java.lang.String TAG_OECF = "OECF"; field public static final java.lang.String TAG_ORIENTATION = "Orientation"; + field public static final java.lang.String TAG_PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation"; + field public static final java.lang.String TAG_PIXEL_X_DIMENSION = "PixelXDimension"; + field public static final java.lang.String TAG_PIXEL_Y_DIMENSION = "PixelYDimension"; + field public static final java.lang.String TAG_PLANAR_CONFIGURATION = "PlanarConfiguration"; + field public static final java.lang.String TAG_PRIMARY_CHROMATICITIES = "PrimaryChromaticities"; + field public static final java.lang.String TAG_REFERENCE_BLACK_WHITE = "ReferenceBlackWhite"; + field public static final java.lang.String TAG_RELATED_SOUND_FILE = "RelatedSoundFile"; + field public static final java.lang.String TAG_RESOLUTION_UNIT = "ResolutionUnit"; + field public static final java.lang.String TAG_ROWS_PER_STRIP = "RowsPerStrip"; + field public static final java.lang.String TAG_SAMPLES_PER_PIXEL = "SamplesPerPixel"; + field public static final java.lang.String TAG_SATURATION = "Saturation"; + field public static final java.lang.String TAG_SCENE_CAPTURE_TYPE = "SceneCaptureType"; + field public static final java.lang.String TAG_SCENE_TYPE = "SceneType"; + field public static final java.lang.String TAG_SENSING_METHOD = "SensingMethod"; + field public static final java.lang.String TAG_SHARPNESS = "Sharpness"; + field public static final java.lang.String TAG_SHUTTER_SPEED_VALUE = "ShutterSpeedValue"; + field public static final java.lang.String TAG_SOFTWARE = "Software"; + field public static final java.lang.String TAG_SPATIAL_FREQUENCY_RESPONSE = "SpatialFrequencyResponse"; + field public static final java.lang.String TAG_SPECTRAL_SENSITIVITY = "SpectralSensitivity"; + field public static final java.lang.String TAG_STRIP_BYTE_COUNTS = "StripByteCounts"; + field public static final java.lang.String TAG_STRIP_OFFSETS = "StripOffsets"; + field public static final java.lang.String TAG_SUBJECT_AREA = "SubjectArea"; field public static final java.lang.String TAG_SUBJECT_DISTANCE = "SubjectDistance"; + field public static final java.lang.String TAG_SUBJECT_DISTANCE_RANGE = "SubjectDistanceRange"; + field public static final java.lang.String TAG_SUBJECT_LOCATION = "SubjectLocation"; field public static final java.lang.String TAG_SUBSEC_TIME = "SubSecTime"; field public static final java.lang.String TAG_SUBSEC_TIME_DIG = "SubSecTimeDigitized"; + field public static final java.lang.String TAG_SUBSEC_TIME_DIGITIZED = "SubSecTimeDigitized"; field public static final java.lang.String TAG_SUBSEC_TIME_ORIG = "SubSecTimeOriginal"; + field public static final java.lang.String TAG_SUBSEC_TIME_ORIGINAL = "SubSecTimeOriginal"; + field public static final java.lang.String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength"; + field public static final java.lang.String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth"; + field public static final java.lang.String TAG_TRANSFER_FUNCTION = "TransferFunction"; + field public static final java.lang.String TAG_USER_COMMENT = "UserComment"; field public static final java.lang.String TAG_WHITE_BALANCE = "WhiteBalance"; + field public static final java.lang.String TAG_WHITE_POINT = "WhitePoint"; + field public static final java.lang.String TAG_X_RESOLUTION = "XResolution"; + field public static final java.lang.String TAG_Y_CB_CR_COEFFICIENTS = "YCbCrCoefficients"; + field public static final java.lang.String TAG_Y_CB_CR_POSITIONING = "YCbCrPositioning"; + field public static final java.lang.String TAG_Y_CB_CR_SUB_SAMPLING = "YCbCrSubSampling"; + field public static final java.lang.String TAG_Y_RESOLUTION = "YResolution"; field public static final int WHITEBALANCE_AUTO = 0; // 0x0 field public static final int WHITEBALANCE_MANUAL = 1; // 0x1 } @@ -20983,6 +21034,7 @@ package android.media { field public static final java.lang.String KEY_DURATION = "durationUs"; field public static final java.lang.String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level"; field public static final java.lang.String KEY_FRAME_RATE = "frame-rate"; + field public static final java.lang.String KEY_HDR_STATIC_INFO = "hdr-static-info"; field public static final java.lang.String KEY_HEIGHT = "height"; field public static final java.lang.String KEY_INTRA_REFRESH_PERIOD = "intra-refresh-period"; field public static final java.lang.String KEY_IS_ADTS = "is-adts"; @@ -29080,7 +29132,6 @@ package android.os { ctor public PersistableBundle(); ctor public PersistableBundle(int); ctor public PersistableBundle(android.os.PersistableBundle); - ctor public PersistableBundle(android.os.Bundle); method public java.lang.Object clone(); method public int describeContents(); method public android.os.PersistableBundle getPersistableBundle(java.lang.String); @@ -29124,6 +29175,7 @@ package android.os { public class Process { ctor public Process(); method public static final long getElapsedCpuTime(); + method public static final int[] getExclusiveCores(); method public static final int getGidForName(java.lang.String); method public static final long getStartElapsedRealtime(); method public static final long getStartUptimeMillis(); @@ -29408,6 +29460,147 @@ package android.os { } +package android.os.health { + + public class HealthStats { + method public java.lang.String getDataType(); + method public long getMeasurement(int); + method public int getMeasurementKeyAt(int); + method public int getMeasurementKeyCount(); + method public java.util.Map<java.lang.String, java.lang.Long> getMeasurements(int); + method public int getMeasurementsKeyAt(int); + method public int getMeasurementsKeyCount(); + method public java.util.Map<java.lang.String, android.os.health.HealthStats> getStats(int); + method public int getStatsKeyAt(int); + method public int getStatsKeyCount(); + method public android.os.health.TimerStat getTimer(int); + method public int getTimerCount(int); + method public int getTimerKeyAt(int); + method public int getTimerKeyCount(); + method public long getTimerTime(int); + method public java.util.Map<java.lang.String, android.os.health.TimerStat> getTimers(int); + method public int getTimersKeyAt(int); + method public int getTimersKeyCount(); + method public boolean hasMeasurement(int); + method public boolean hasMeasurements(int); + method public boolean hasStats(int); + method public boolean hasTimer(int); + method public boolean hasTimers(int); + } + + public final class PackageHealthStats { + field public static final int MEASUREMENTS_WAKEUP_ALARMS_COUNT = 40002; // 0x9c42 + field public static final int STATS_SERVICES = 40001; // 0x9c41 + } + + public final class PidHealthStats { + field public static final int MEASUREMENT_WAKE_NESTING_COUNT = 20001; // 0x4e21 + field public static final int MEASUREMENT_WAKE_START_MS = 20003; // 0x4e23 + field public static final int MEASUREMENT_WAKE_SUM_MS = 20002; // 0x4e22 + } + + public final class ProcessHealthStats { + field public static final int MEASUREMENT_ANR_COUNT = 30005; // 0x7535 + field public static final int MEASUREMENT_CRASHES_COUNT = 30004; // 0x7534 + field public static final int MEASUREMENT_FOREGROUND_MS = 30006; // 0x7536 + field public static final int MEASUREMENT_STARTS_COUNT = 30003; // 0x7533 + field public static final int MEASUREMENT_SYSTEM_TIME_MS = 30002; // 0x7532 + field public static final int MEASUREMENT_USER_TIME_MS = 30001; // 0x7531 + } + + public final class ServiceHealthStats { + field public static final int MEASUREMENT_LAUNCH_COUNT = 50002; // 0xc352 + field public static final int MEASUREMENT_START_SERVICE_COUNT = 50001; // 0xc351 + } + + public class SystemHealthManager { + method public static android.os.health.SystemHealthManager from(android.content.Context); + method public android.os.health.HealthStats takeMyUidSnapshot(); + method public android.os.health.HealthStats takeUidSnapshot(int); + method public android.os.health.HealthStats[] takeUidSnapshots(int[]); + } + + public class TimerStat implements android.os.Parcelable { + ctor public TimerStat(); + ctor public TimerStat(int, long); + ctor public TimerStat(android.os.Parcel); + method public int describeContents(); + method public int getCount(); + method public long getTime(); + method public void setCount(int); + method public void setTime(long); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.os.health.TimerStat> CREATOR; + } + + public final class UidHealthStats { + field public static final int MEASUREMENT_BLUETOOTH_IDLE_MS = 10020; // 0x2724 + field public static final int MEASUREMENT_BLUETOOTH_POWER_MAMS = 10023; // 0x2727 + field public static final int MEASUREMENT_BLUETOOTH_RX_BYTES = 10052; // 0x2744 + field public static final int MEASUREMENT_BLUETOOTH_RX_MS = 10021; // 0x2725 + field public static final int MEASUREMENT_BLUETOOTH_RX_PACKETS = 10058; // 0x274a + field public static final int MEASUREMENT_BLUETOOTH_TX_BYTES = 10053; // 0x2745 + field public static final int MEASUREMENT_BLUETOOTH_TX_MS = 10022; // 0x2726 + field public static final int MEASUREMENT_BLUETOOTH_TX_PACKETS = 10059; // 0x274b + field public static final int MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT = 10046; // 0x273e + field public static final int MEASUREMENT_CPU_POWER_MAUS = 10064; // 0x2750 + field public static final int MEASUREMENT_MOBILE_IDLE_MS = 10024; // 0x2728 + field public static final int MEASUREMENT_MOBILE_POWER_MAMS = 10027; // 0x272b + field public static final int MEASUREMENT_MOBILE_RX_BYTES = 10048; // 0x2740 + field public static final int MEASUREMENT_MOBILE_RX_MS = 10025; // 0x2729 + field public static final int MEASUREMENT_MOBILE_RX_PACKETS = 10054; // 0x2746 + field public static final int MEASUREMENT_MOBILE_TX_BYTES = 10049; // 0x2741 + field public static final int MEASUREMENT_MOBILE_TX_MS = 10026; // 0x272a + field public static final int MEASUREMENT_MOBILE_TX_PACKETS = 10055; // 0x2747 + field public static final int MEASUREMENT_OTHER_USER_ACTIVITY_COUNT = 10045; // 0x273d + field public static final int MEASUREMENT_REALTIME_BATTERY_MS = 10001; // 0x2711 + field public static final int MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS = 10003; // 0x2713 + field public static final int MEASUREMENT_SYSTEM_CPU_TIME_US = 10063; // 0x274f + field public static final int MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT = 10047; // 0x273f + field public static final int MEASUREMENT_UPTIME_BATTERY_MS = 10002; // 0x2712 + field public static final int MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS = 10004; // 0x2714 + field public static final int MEASUREMENT_USER_CPU_TIME_US = 10062; // 0x274e + field public static final int MEASUREMENT_WIFI_FULL_LOCK_MS = 10029; // 0x272d + field public static final int MEASUREMENT_WIFI_IDLE_MS = 10016; // 0x2720 + field public static final int MEASUREMENT_WIFI_MULTICAST_MS = 10031; // 0x272f + field public static final int MEASUREMENT_WIFI_POWER_MAMS = 10019; // 0x2723 + field public static final int MEASUREMENT_WIFI_RUNNING_MS = 10028; // 0x272c + field public static final int MEASUREMENT_WIFI_RX_BYTES = 10050; // 0x2742 + field public static final int MEASUREMENT_WIFI_RX_MS = 10017; // 0x2721 + field public static final int MEASUREMENT_WIFI_RX_PACKETS = 10056; // 0x2748 + field public static final int MEASUREMENT_WIFI_TX_BYTES = 10051; // 0x2743 + field public static final int MEASUREMENT_WIFI_TX_MS = 10018; // 0x2722 + field public static final int MEASUREMENT_WIFI_TX_PACKETS = 10057; // 0x2749 + field public static final int STATS_PACKAGES = 10015; // 0x271f + field public static final int STATS_PIDS = 10013; // 0x271d + field public static final int STATS_PROCESSES = 10014; // 0x271e + field public static final int TIMERS_JOBS = 10010; // 0x271a + field public static final int TIMERS_SENSORS = 10012; // 0x271c + field public static final int TIMERS_SYNCS = 10009; // 0x2719 + field public static final int TIMERS_WAKELOCKS_DRAW = 10008; // 0x2718 + field public static final int TIMERS_WAKELOCKS_FULL = 10005; // 0x2715 + field public static final int TIMERS_WAKELOCKS_PARTIAL = 10006; // 0x2716 + field public static final int TIMERS_WAKELOCKS_WINDOW = 10007; // 0x2717 + field public static final int TIMER_AUDIO = 10032; // 0x2730 + field public static final int TIMER_BLUETOOTH_SCAN = 10037; // 0x2735 + field public static final int TIMER_CAMERA = 10035; // 0x2733 + field public static final int TIMER_FLASHLIGHT = 10034; // 0x2732 + field public static final int TIMER_FOREGROUND_ACTIVITY = 10036; // 0x2734 + field public static final int TIMER_GPS_SENSOR = 10011; // 0x271b + field public static final int TIMER_MOBILE_RADIO_ACTIVE = 10061; // 0x274d + field public static final int TIMER_PROCESS_STATE_BACKGROUND_MS = 10042; // 0x273a + field public static final int TIMER_PROCESS_STATE_CACHED_MS = 10043; // 0x273b + field public static final int TIMER_PROCESS_STATE_FOREGROUND_MS = 10041; // 0x2739 + field public static final int TIMER_PROCESS_STATE_FOREGROUND_SERVICE_MS = 10039; // 0x2737 + field public static final int TIMER_PROCESS_STATE_TOP_MS = 10038; // 0x2736 + field public static final int TIMER_PROCESS_STATE_TOP_SLEEPING_MS = 10040; // 0x2738 + field public static final int TIMER_VIBRATOR = 10044; // 0x273c + field public static final int TIMER_VIDEO = 10033; // 0x2731 + field public static final int TIMER_WIFI_SCAN = 10030; // 0x272e + } + +} + package android.os.storage { public abstract class OnObbStateChangeListener { @@ -50719,6 +50912,7 @@ package java.lang { public abstract interface Iterable { method public default void forEach(java.util.function.Consumer<? super T>); method public abstract java.util.Iterator<T> iterator(); + method public default java.util.Spliterator<T> spliterator(); } public class LinkageError extends java.lang.Error { @@ -57139,6 +57333,7 @@ package java.util { method public E removeLast(); method public boolean removeLastOccurrence(java.lang.Object); method public int size(); + method public java.util.Spliterator<E> spliterator(); } public class ArrayList extends java.util.AbstractList implements java.lang.Cloneable java.util.List java.util.RandomAccess java.io.Serializable { @@ -57150,6 +57345,7 @@ package java.util { method public void forEach(java.util.function.Consumer<? super E>); method public E get(int); method public int size(); + method public java.util.Spliterator<E> spliterator(); method public void trimToSize(); } @@ -57250,6 +57446,14 @@ package java.util { method public static void sort(java.lang.Object[], int, int); method public static void sort(T[], java.util.Comparator<? super T>); method public static void sort(T[], int, int, java.util.Comparator<? super T>); + method public static java.util.Spliterator<T> spliterator(T[]); + method public static java.util.Spliterator<T> spliterator(T[], int, int); + method public static java.util.Spliterator.OfInt spliterator(int[]); + method public static java.util.Spliterator.OfInt spliterator(int[], int, int); + method public static java.util.Spliterator.OfLong spliterator(long[]); + method public static java.util.Spliterator.OfLong spliterator(long[], int, int); + method public static java.util.Spliterator.OfDouble spliterator(double[]); + method public static java.util.Spliterator.OfDouble spliterator(double[], int, int); method public static java.lang.String toString(long[]); method public static java.lang.String toString(int[]); method public static java.lang.String toString(short[]); @@ -57593,6 +57797,17 @@ package java.util { method public abstract int size(); } + public class DoubleSummaryStatistics implements java.util.function.DoubleConsumer { + ctor public DoubleSummaryStatistics(); + method public void accept(double); + method public void combine(java.util.DoubleSummaryStatistics); + method public final double getAverage(); + method public final long getCount(); + method public final double getMax(); + method public final double getMin(); + method public final double getSum(); + } + public class DuplicateFormatFlagsException extends java.util.IllegalFormatException { ctor public DuplicateFormatFlagsException(java.lang.String); method public java.lang.String getFlags(); @@ -57738,6 +57953,7 @@ package java.util { method public java.lang.Object clone(); method public java.util.Iterator<E> iterator(); method public int size(); + method public java.util.Spliterator<E> spliterator(); } public class Hashtable extends java.util.Dictionary implements java.lang.Cloneable java.util.Map java.io.Serializable { @@ -57815,6 +58031,17 @@ package java.util { ctor public InputMismatchException(java.lang.String); } + public class IntSummaryStatistics implements java.util.function.IntConsumer { + ctor public IntSummaryStatistics(); + method public void accept(int); + method public void combine(java.util.IntSummaryStatistics); + method public final double getAverage(); + method public final long getCount(); + method public final int getMax(); + method public final int getMin(); + method public final long getSum(); + } + public class InvalidPropertiesFormatException extends java.io.IOException { ctor public InvalidPropertiesFormatException(java.lang.Throwable); ctor public InvalidPropertiesFormatException(java.lang.String); @@ -57871,6 +58098,7 @@ package java.util { method public E removeLast(); method public boolean removeLastOccurrence(java.lang.Object); method public int size(); + method public java.util.Spliterator<E> spliterator(); } public abstract interface List implements java.util.Collection { @@ -58006,6 +58234,18 @@ package java.util { enum_constant public static final java.util.Locale.Category FORMAT; } + public class LongSummaryStatistics implements java.util.function.IntConsumer java.util.function.LongConsumer { + ctor public LongSummaryStatistics(); + method public void accept(int); + method public void accept(long); + method public void combine(java.util.LongSummaryStatistics); + method public final double getAverage(); + method public final long getCount(); + method public final long getMax(); + method public final long getMin(); + method public final long getSum(); + } + public abstract interface Map { method public abstract void clear(); method public abstract boolean containsKey(java.lang.Object); @@ -58025,6 +58265,8 @@ package java.util { } public static abstract interface Map.Entry { + method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByKey(); + method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByKey(java.util.Comparator<? super K>); method public abstract boolean equals(java.lang.Object); method public abstract K getKey(); method public abstract V getValue(); @@ -58203,6 +58445,7 @@ package java.util { public class PriorityQueue extends java.util.AbstractQueue implements java.io.Serializable { ctor public PriorityQueue(); ctor public PriorityQueue(int); + ctor public PriorityQueue(java.util.Comparator<? super E>); ctor public PriorityQueue(int, java.util.Comparator<? super E>); ctor public PriorityQueue(java.util.Collection<? extends E>); ctor public PriorityQueue(java.util.PriorityQueue<? extends E>); @@ -58213,6 +58456,7 @@ package java.util { method public E peek(); method public E poll(); method public int size(); + method public final java.util.Spliterator<E> spliterator(); } public class Properties extends java.util.Hashtable { @@ -58455,6 +58699,111 @@ package java.util { method public abstract java.util.SortedSet<E> tailSet(E); } + public abstract interface Spliterator { + method public abstract int characteristics(); + method public abstract long estimateSize(); + method public default void forEachRemaining(java.util.function.Consumer<? super T>); + method public default java.util.Comparator<? super T> getComparator(); + method public default long getExactSizeIfKnown(); + method public default boolean hasCharacteristics(int); + method public abstract boolean tryAdvance(java.util.function.Consumer<? super T>); + method public abstract java.util.Spliterator<T> trySplit(); + field public static final int CONCURRENT = 4096; // 0x1000 + field public static final int DISTINCT = 1; // 0x1 + field public static final int IMMUTABLE = 1024; // 0x400 + field public static final int NONNULL = 256; // 0x100 + field public static final int ORDERED = 16; // 0x10 + field public static final int SIZED = 64; // 0x40 + field public static final int SORTED = 4; // 0x4 + field public static final int SUBSIZED = 16384; // 0x4000 + } + + public static abstract interface Spliterator.OfDouble implements java.util.Spliterator.OfPrimitive { + method public default void forEachRemaining(java.util.function.DoubleConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Double>); + method public abstract boolean tryAdvance(java.util.function.DoubleConsumer); + method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Double>); + method public abstract java.util.Spliterator.OfDouble trySplit(); + } + + public static abstract interface Spliterator.OfInt implements java.util.Spliterator.OfPrimitive { + method public default void forEachRemaining(java.util.function.IntConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Integer>); + method public abstract boolean tryAdvance(java.util.function.IntConsumer); + method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Integer>); + method public abstract java.util.Spliterator.OfInt trySplit(); + } + + public static abstract interface Spliterator.OfLong implements java.util.Spliterator.OfPrimitive { + method public default void forEachRemaining(java.util.function.LongConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Long>); + method public abstract boolean tryAdvance(java.util.function.LongConsumer); + method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Long>); + method public abstract java.util.Spliterator.OfLong trySplit(); + } + + public static abstract interface Spliterator.OfPrimitive implements java.util.Spliterator { + method public default void forEachRemaining(T_CONS); + method public abstract boolean tryAdvance(T_CONS); + method public abstract T_SPLITR trySplit(); + } + + public final class Spliterators { + method public static java.util.Spliterator.OfDouble emptyDoubleSpliterator(); + method public static java.util.Spliterator.OfInt emptyIntSpliterator(); + method public static java.util.Spliterator.OfLong emptyLongSpliterator(); + method public static java.util.Spliterator<T> emptySpliterator(); + method public static java.util.Iterator<T> iterator(java.util.Spliterator<? extends T>); + method public static java.util.PrimitiveIterator.OfInt iterator(java.util.Spliterator.OfInt); + method public static java.util.PrimitiveIterator.OfLong iterator(java.util.Spliterator.OfLong); + method public static java.util.PrimitiveIterator.OfDouble iterator(java.util.Spliterator.OfDouble); + method public static java.util.Spliterator<T> spliterator(java.lang.Object[], int); + method public static java.util.Spliterator<T> spliterator(java.lang.Object[], int, int, int); + method public static java.util.Spliterator.OfInt spliterator(int[], int); + method public static java.util.Spliterator.OfInt spliterator(int[], int, int, int); + method public static java.util.Spliterator.OfLong spliterator(long[], int); + method public static java.util.Spliterator.OfLong spliterator(long[], int, int, int); + method public static java.util.Spliterator.OfDouble spliterator(double[], int); + method public static java.util.Spliterator.OfDouble spliterator(double[], int, int, int); + method public static java.util.Spliterator<T> spliterator(java.util.Collection<? extends T>, int); + method public static java.util.Spliterator<T> spliterator(java.util.Iterator<? extends T>, long, int); + method public static java.util.Spliterator.OfInt spliterator(java.util.PrimitiveIterator.OfInt, long, int); + method public static java.util.Spliterator.OfLong spliterator(java.util.PrimitiveIterator.OfLong, long, int); + method public static java.util.Spliterator.OfDouble spliterator(java.util.PrimitiveIterator.OfDouble, long, int); + method public static java.util.Spliterator<T> spliteratorUnknownSize(java.util.Iterator<? extends T>, int); + method public static java.util.Spliterator.OfInt spliteratorUnknownSize(java.util.PrimitiveIterator.OfInt, int); + method public static java.util.Spliterator.OfLong spliteratorUnknownSize(java.util.PrimitiveIterator.OfLong, int); + method public static java.util.Spliterator.OfDouble spliteratorUnknownSize(java.util.PrimitiveIterator.OfDouble, int); + } + + public static abstract class Spliterators.AbstractDoubleSpliterator implements java.util.Spliterator.OfDouble { + ctor protected Spliterators.AbstractDoubleSpliterator(long, int); + method public int characteristics(); + method public long estimateSize(); + method public java.util.Spliterator.OfDouble trySplit(); + } + + public static abstract class Spliterators.AbstractIntSpliterator implements java.util.Spliterator.OfInt { + ctor protected Spliterators.AbstractIntSpliterator(long, int); + method public int characteristics(); + method public long estimateSize(); + method public java.util.Spliterator.OfInt trySplit(); + } + + public static abstract class Spliterators.AbstractLongSpliterator implements java.util.Spliterator.OfLong { + ctor protected Spliterators.AbstractLongSpliterator(long, int); + method public int characteristics(); + method public long estimateSize(); + method public java.util.Spliterator.OfLong trySplit(); + } + + public static abstract class Spliterators.AbstractSpliterator implements java.util.Spliterator { + ctor protected Spliterators.AbstractSpliterator(long, int); + method public int characteristics(); + method public long estimateSize(); + method public java.util.Spliterator<T> trySplit(); + } + public class Stack extends java.util.Vector { ctor public Stack(); method public boolean empty(); @@ -58464,6 +58813,15 @@ package java.util { method public synchronized int search(java.lang.Object); } + public final class StringJoiner { + ctor public StringJoiner(java.lang.CharSequence); + ctor public StringJoiner(java.lang.CharSequence, java.lang.CharSequence, java.lang.CharSequence); + method public java.util.StringJoiner add(java.lang.CharSequence); + method public int length(); + method public java.util.StringJoiner merge(java.util.StringJoiner); + method public java.util.StringJoiner setEmptyValue(java.lang.CharSequence); + } + public class StringTokenizer implements java.util.Enumeration { ctor public StringTokenizer(java.lang.String, java.lang.String, boolean); ctor public StringTokenizer(java.lang.String, java.lang.String); @@ -58585,6 +58943,7 @@ package java.util { method public E pollFirst(); method public E pollLast(); method public int size(); + method public java.util.Spliterator<E> spliterator(); method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean); method public java.util.SortedSet<E> subSet(E, E); method public java.util.NavigableSet<E> tailSet(E, boolean); @@ -58641,6 +59000,7 @@ package java.util { method public synchronized void setElementAt(E, int); method public synchronized void setSize(int); method public synchronized int size(); + method public java.util.Spliterator<E> spliterator(); method public synchronized void trimToSize(); field protected int capacityIncrement; field protected int elementCount; diff --git a/api/system-current.txt b/api/system-current.txt index 7823b3cd16ba..cf175cc2d374 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -974,6 +974,7 @@ package android { field public static final int nextFocusLeft = 16842977; // 0x10100e1 field public static final int nextFocusRight = 16842978; // 0x10100e2 field public static final int nextFocusUp = 16842979; // 0x10100e3 + field public static final int nfcAntennaPositionDrawable = 16844063; // 0x101051f field public static final int noHistory = 16843309; // 0x101022d field public static final int normalScreens = 16843397; // 0x1010285 field public static final int notificationTimeout = 16843651; // 0x1010383 @@ -6129,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"; @@ -8415,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"; @@ -8448,6 +8450,7 @@ package android.content { field public static final java.lang.String SENSOR_SERVICE = "sensor"; field public static final java.lang.String SHORTCUT_SERVICE = "shortcut"; field public static final java.lang.String STORAGE_SERVICE = "storage"; + field public static final java.lang.String SYSTEM_HEALTH_SERVICE = "systemhealth"; field public static final java.lang.String TELECOM_SERVICE = "telecom"; field public static final java.lang.String TELEPHONY_SERVICE = "phone"; field public static final java.lang.String TELEPHONY_SUBSCRIPTION_SERVICE = "telephony_subscription_service"; @@ -9647,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; @@ -9894,6 +9898,7 @@ package android.content.pm { method public java.lang.String[] getNames() throws java.io.IOException; method public java.io.InputStream openRead(java.lang.String) throws java.io.IOException; method public java.io.OutputStream openWrite(java.lang.String, long, long) throws java.io.IOException; + method public void removeSplit(java.lang.String) throws java.io.IOException; method public void setStagingProgress(float); } @@ -9927,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); @@ -10388,6 +10394,7 @@ package android.content.pm { method public int getWeight(); method public boolean hasIconFile(); method public boolean hasIconResource(); + method public boolean hasKeyFieldsOnly(); method public boolean isDynamic(); method public boolean isPinned(); method public void writeToParcel(android.os.Parcel, int); @@ -10398,6 +10405,7 @@ package android.content.pm { field public static final int FLAG_DYNAMIC = 1; // 0x1 field public static final int FLAG_HAS_ICON_FILE = 8; // 0x8 field public static final int FLAG_HAS_ICON_RES = 4; // 0x4 + field public static final int FLAG_KEY_FIELDS_ONLY = 16; // 0x10 field public static final int FLAG_PINNED = 2; // 0x2 } @@ -10418,6 +10426,7 @@ package android.content.pm { method public void deleteAllDynamicShortcuts(); method public void deleteDynamicShortcut(java.lang.String); method public java.util.List<android.content.pm.ShortcutInfo> getDynamicShortcuts(); + method public int getIconMaxDimensions(); method public int getMaxDynamicShortcutCount(); method public java.util.List<android.content.pm.ShortcutInfo> getPinnedShortcuts(); method public long getRateLimitResetTime(); @@ -13301,7 +13310,8 @@ package android.graphics.drawable { method public int getGradientType(); method public int getOpacity(); method public android.graphics.drawable.GradientDrawable.Orientation getOrientation(); - method public boolean isUseLevel(); + method public int getShape(); + method public boolean getUseLevel(); method public void setAlpha(int); method public void setColor(int); method public void setColor(android.content.res.ColorStateList); @@ -14170,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); @@ -20415,24 +20426,6 @@ package android.location { method public boolean hasFullBiasNanos(); method public boolean hasLeapSecond(); method public boolean hasTimeUncertaintyNanos(); - method public void reset(); - method public void resetBiasNanos(); - method public void resetBiasUncertaintyNanos(); - method public void resetDriftNanosPerSecond(); - method public void resetDriftUncertaintyNanosPerSecond(); - method public void resetFullBiasNanos(); - method public void resetLeapSecond(); - method public void resetTimeUncertaintyNanos(); - method public void set(android.location.GnssClock); - method public void setBiasNanos(double); - method public void setBiasUncertaintyNanos(double); - method public void setDriftNanosPerSecond(double); - method public void setDriftUncertaintyNanosPerSecond(double); - method public void setFullBiasNanos(long); - method public void setHardwareClockDiscontinuityCount(int); - method public void setLeapSecond(int); - method public void setTimeNanos(long); - method public void setTimeUncertaintyNanos(double); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.location.GnssClock> CREATOR; } @@ -20463,31 +20456,6 @@ package android.location { method public boolean hasCarrierPhaseUncertainty(); method public boolean hasSnrInDb(); method public boolean isPseudorangeRateCorrected(); - method public void reset(); - method public void resetCarrierCycles(); - method public void resetCarrierFrequencyHz(); - method public void resetCarrierPhase(); - method public void resetCarrierPhaseUncertainty(); - method public void resetSnrInDb(); - method public void set(android.location.GnssMeasurement); - method public void setAccumulatedDeltaRangeMeters(double); - method public void setAccumulatedDeltaRangeState(int); - method public void setAccumulatedDeltaRangeUncertaintyMeters(double); - method public void setCarrierCycles(long); - method public void setCarrierFrequencyHz(float); - method public void setCarrierPhase(double); - method public void setCarrierPhaseUncertainty(double); - method public void setCn0DbHz(double); - method public void setConstellationType(int); - method public void setMultipathIndicator(int); - method public void setPseudorangeRateMetersPerSecond(double); - method public void setPseudorangeRateUncertaintyMetersPerSecond(double); - method public void setReceivedSvTimeNanos(long); - method public void setReceivedSvTimeUncertaintyNanos(long); - method public void setSnrInDb(double); - method public void setState(int); - method public void setSvid(int); - method public void setTimeOffsetNanos(double); method public void writeToParcel(android.os.Parcel, int); field public static final int ADR_STATE_CYCLE_SLIP = 4; // 0x4 field public static final int ADR_STATE_RESET = 2; // 0x2 @@ -20537,14 +20505,6 @@ package android.location { method public int getSubmessageId(); method public int getSvid(); method public int getType(); - method public void reset(); - method public void set(android.location.GnssNavigationMessage); - method public void setData(byte[]); - method public void setMessageId(int); - method public void setStatus(int); - method public void setSubmessageId(int); - method public void setSvid(int); - method public void setType(int); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator<android.location.GnssNavigationMessage> CREATOR; field public static final int STATUS_PARITY_PASSED = 1; // 0x1 @@ -21719,37 +21679,129 @@ package android.media { field public static final int ORIENTATION_TRANSVERSE = 7; // 0x7 field public static final int ORIENTATION_UNDEFINED = 0; // 0x0 field public static final java.lang.String TAG_APERTURE = "FNumber"; + field public static final java.lang.String TAG_APERTURE_VALUE = "ApertureValue"; + field public static final java.lang.String TAG_ARTIST = "Artist"; + field public static final java.lang.String TAG_BITS_PER_SAMPLE = "BitsPerSample"; + field public static final java.lang.String TAG_BRIGHTNESS_VALUE = "BrightnessValue"; + field public static final java.lang.String TAG_CFA_PATTERN = "CFAPattern"; + field public static final java.lang.String TAG_COLOR_SPACE = "ColorSpace"; + field public static final java.lang.String TAG_COMPONENTS_CONFIGURATION = "ComponentsConfiguration"; + field public static final java.lang.String TAG_COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel"; + field public static final java.lang.String TAG_COMPRESSION = "Compression"; + field public static final java.lang.String TAG_CONTRAST = "Contrast"; + field public static final java.lang.String TAG_COPYRIGHT = "Copyright"; + field public static final java.lang.String TAG_CUSTOM_RENDERED = "CustomRendered"; field public static final java.lang.String TAG_DATETIME = "DateTime"; field public static final java.lang.String TAG_DATETIME_DIGITIZED = "DateTimeDigitized"; + field public static final java.lang.String TAG_DATETIME_ORIGINAL = "DateTimeOriginal"; + field public static final java.lang.String TAG_DEVICE_SETTING_DESCRIPTION = "DeviceSettingDescription"; field public static final java.lang.String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio"; + field public static final java.lang.String TAG_EXIF_VERSION = "ExifVersion"; field public static final java.lang.String TAG_EXPOSURE_BIAS_VALUE = "ExposureBiasValue"; + field public static final java.lang.String TAG_EXPOSURE_INDEX = "ExposureIndex"; field public static final java.lang.String TAG_EXPOSURE_MODE = "ExposureMode"; field public static final java.lang.String TAG_EXPOSURE_PROGRAM = "ExposureProgram"; field public static final java.lang.String TAG_EXPOSURE_TIME = "ExposureTime"; + field public static final java.lang.String TAG_FILE_SOURCE = "FileSource"; field public static final java.lang.String TAG_FLASH = "Flash"; + field public static final java.lang.String TAG_FLASHPIX_VERSION = "FlashpixVersion"; + field public static final java.lang.String TAG_FLASH_ENERGY = "FlashEnergy"; field public static final java.lang.String TAG_FOCAL_LENGTH = "FocalLength"; + field public static final java.lang.String TAG_FOCAL_LENGTH_IN_35MM_FILM = "FocalLengthIn35mmFilm"; + field public static final java.lang.String TAG_FOCAL_PLANE_RESOLUTION_UNIT = "FocalPlaneResolutionUnit"; + field public static final java.lang.String TAG_FOCAL_PLANE_X_RESOLUTION = "FocalPlaneXResolution"; + field public static final java.lang.String TAG_FOCAL_PLANE_Y_RESOLUTION = "FocalPlaneYResolution"; + field public static final java.lang.String TAG_F_NUMBER = "FNumber"; + field public static final java.lang.String TAG_GAIN_CONTROL = "GainControl"; field public static final java.lang.String TAG_GPS_ALTITUDE = "GPSAltitude"; field public static final java.lang.String TAG_GPS_ALTITUDE_REF = "GPSAltitudeRef"; + field public static final java.lang.String TAG_GPS_AREA_INFORMATION = "GPSAreaInformation"; field public static final java.lang.String TAG_GPS_DATESTAMP = "GPSDateStamp"; + field public static final java.lang.String TAG_GPS_DEST_BEARING = "GPSDestBearing"; + field public static final java.lang.String TAG_GPS_DEST_BEARING_REF = "GPSDestBearingRef"; + field public static final java.lang.String TAG_GPS_DEST_DISTANCE = "GPSDestDistance"; + field public static final java.lang.String TAG_GPS_DEST_DISTANCE_REF = "GPSDestDistanceRef"; + field public static final java.lang.String TAG_GPS_DEST_LATITUDE = "GPSDestLatitude"; + field public static final java.lang.String TAG_GPS_DEST_LATITUDE_REF = "GPSDestLatitudeRef"; + field public static final java.lang.String TAG_GPS_DEST_LONGITUDE = "GPSDestLongitude"; + field public static final java.lang.String TAG_GPS_DEST_LONGITUDE_REF = "GPSDestLongitudeRef"; + field public static final java.lang.String TAG_GPS_DIFFERENTIAL = "GPSDifferential"; + field public static final java.lang.String TAG_GPS_DOP = "GPSDOP"; + field public static final java.lang.String TAG_GPS_IMG_DIRECTION = "GPSImgDirection"; + field public static final java.lang.String TAG_GPS_IMG_DIRECTION_REF = "GPSImgDirectionRef"; field public static final java.lang.String TAG_GPS_LATITUDE = "GPSLatitude"; field public static final java.lang.String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef"; field public static final java.lang.String TAG_GPS_LONGITUDE = "GPSLongitude"; field public static final java.lang.String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef"; + field public static final java.lang.String TAG_GPS_MAP_DATUM = "GPSMapDatum"; + field public static final java.lang.String TAG_GPS_MEASURE_MODE = "GPSMeasureMode"; field public static final java.lang.String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod"; + field public static final java.lang.String TAG_GPS_SATELLITES = "GPSSatellites"; + field public static final java.lang.String TAG_GPS_SPEED = "GPSSpeed"; + field public static final java.lang.String TAG_GPS_SPEED_REF = "GPSSpeedRef"; + field public static final java.lang.String TAG_GPS_STATUS = "GPSStatus"; field public static final java.lang.String TAG_GPS_TIMESTAMP = "GPSTimeStamp"; + field public static final java.lang.String TAG_GPS_TRACK = "GPSTrack"; + field public static final java.lang.String TAG_GPS_TRACK_REF = "GPSTrackRef"; + field public static final java.lang.String TAG_GPS_VERSION_ID = "GPSVersionID"; + field public static final java.lang.String TAG_IMAGE_DESCRIPTION = "ImageDescription"; field public static final java.lang.String TAG_IMAGE_LENGTH = "ImageLength"; + field public static final java.lang.String TAG_IMAGE_UNIQUE_ID = "ImageUniqueID"; field public static final java.lang.String TAG_IMAGE_WIDTH = "ImageWidth"; + field public static final java.lang.String TAG_INTEROPERABILITY_INDEX = "InteroperabilityIndex"; field public static final java.lang.String TAG_ISO = "ISOSpeedRatings"; + field public static final java.lang.String TAG_ISO_SPEED_RATINGS = "ISOSpeedRatings"; + field public static final java.lang.String TAG_JPEG_INTERCHANGE_FORMAT = "JPEGInterchangeFormat"; + field public static final java.lang.String TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = "JPEGInterchangeFormatLength"; field public static final java.lang.String TAG_LIGHT_SOURCE = "LightSource"; field public static final java.lang.String TAG_MAKE = "Make"; + field public static final java.lang.String TAG_MAKER_NOTE = "MakerNote"; + field public static final java.lang.String TAG_MAX_APERTURE_VALUE = "MaxApertureValue"; field public static final java.lang.String TAG_METERING_MODE = "MeteringMode"; field public static final java.lang.String TAG_MODEL = "Model"; + field public static final java.lang.String TAG_OECF = "OECF"; field public static final java.lang.String TAG_ORIENTATION = "Orientation"; + field public static final java.lang.String TAG_PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation"; + field public static final java.lang.String TAG_PIXEL_X_DIMENSION = "PixelXDimension"; + field public static final java.lang.String TAG_PIXEL_Y_DIMENSION = "PixelYDimension"; + field public static final java.lang.String TAG_PLANAR_CONFIGURATION = "PlanarConfiguration"; + field public static final java.lang.String TAG_PRIMARY_CHROMATICITIES = "PrimaryChromaticities"; + field public static final java.lang.String TAG_REFERENCE_BLACK_WHITE = "ReferenceBlackWhite"; + field public static final java.lang.String TAG_RELATED_SOUND_FILE = "RelatedSoundFile"; + field public static final java.lang.String TAG_RESOLUTION_UNIT = "ResolutionUnit"; + field public static final java.lang.String TAG_ROWS_PER_STRIP = "RowsPerStrip"; + field public static final java.lang.String TAG_SAMPLES_PER_PIXEL = "SamplesPerPixel"; + field public static final java.lang.String TAG_SATURATION = "Saturation"; + field public static final java.lang.String TAG_SCENE_CAPTURE_TYPE = "SceneCaptureType"; + field public static final java.lang.String TAG_SCENE_TYPE = "SceneType"; + field public static final java.lang.String TAG_SENSING_METHOD = "SensingMethod"; + field public static final java.lang.String TAG_SHARPNESS = "Sharpness"; + field public static final java.lang.String TAG_SHUTTER_SPEED_VALUE = "ShutterSpeedValue"; + field public static final java.lang.String TAG_SOFTWARE = "Software"; + field public static final java.lang.String TAG_SPATIAL_FREQUENCY_RESPONSE = "SpatialFrequencyResponse"; + field public static final java.lang.String TAG_SPECTRAL_SENSITIVITY = "SpectralSensitivity"; + field public static final java.lang.String TAG_STRIP_BYTE_COUNTS = "StripByteCounts"; + field public static final java.lang.String TAG_STRIP_OFFSETS = "StripOffsets"; + field public static final java.lang.String TAG_SUBJECT_AREA = "SubjectArea"; field public static final java.lang.String TAG_SUBJECT_DISTANCE = "SubjectDistance"; + field public static final java.lang.String TAG_SUBJECT_DISTANCE_RANGE = "SubjectDistanceRange"; + field public static final java.lang.String TAG_SUBJECT_LOCATION = "SubjectLocation"; field public static final java.lang.String TAG_SUBSEC_TIME = "SubSecTime"; field public static final java.lang.String TAG_SUBSEC_TIME_DIG = "SubSecTimeDigitized"; + field public static final java.lang.String TAG_SUBSEC_TIME_DIGITIZED = "SubSecTimeDigitized"; field public static final java.lang.String TAG_SUBSEC_TIME_ORIG = "SubSecTimeOriginal"; + field public static final java.lang.String TAG_SUBSEC_TIME_ORIGINAL = "SubSecTimeOriginal"; + field public static final java.lang.String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength"; + field public static final java.lang.String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth"; + field public static final java.lang.String TAG_TRANSFER_FUNCTION = "TransferFunction"; + field public static final java.lang.String TAG_USER_COMMENT = "UserComment"; field public static final java.lang.String TAG_WHITE_BALANCE = "WhiteBalance"; + field public static final java.lang.String TAG_WHITE_POINT = "WhitePoint"; + field public static final java.lang.String TAG_X_RESOLUTION = "XResolution"; + field public static final java.lang.String TAG_Y_CB_CR_COEFFICIENTS = "YCbCrCoefficients"; + field public static final java.lang.String TAG_Y_CB_CR_POSITIONING = "YCbCrPositioning"; + field public static final java.lang.String TAG_Y_CB_CR_SUB_SAMPLING = "YCbCrSubSampling"; + field public static final java.lang.String TAG_Y_RESOLUTION = "YResolution"; field public static final int WHITEBALANCE_AUTO = 0; // 0x0 field public static final int WHITEBALANCE_MANUAL = 1; // 0x1 } @@ -22475,6 +22527,7 @@ package android.media { field public static final java.lang.String KEY_DURATION = "durationUs"; field public static final java.lang.String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level"; field public static final java.lang.String KEY_FRAME_RATE = "frame-rate"; + field public static final java.lang.String KEY_HDR_STATIC_INFO = "hdr-static-info"; field public static final java.lang.String KEY_HEIGHT = "height"; field public static final java.lang.String KEY_INTRA_REFRESH_PERIOD = "intra-refresh-period"; field public static final java.lang.String KEY_IS_ADTS = "is-adts"; @@ -23777,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; } @@ -31360,7 +31414,6 @@ package android.os { ctor public PersistableBundle(); ctor public PersistableBundle(int); ctor public PersistableBundle(android.os.PersistableBundle); - ctor public PersistableBundle(android.os.Bundle); method public java.lang.Object clone(); method public int describeContents(); method public android.os.PersistableBundle getPersistableBundle(java.lang.String); @@ -31412,6 +31465,7 @@ package android.os { public class Process { ctor public Process(); method public static final long getElapsedCpuTime(); + method public static final int[] getExclusiveCores(); method public static final int getGidForName(java.lang.String); method public static final long getStartElapsedRealtime(); method public static final long getStartUptimeMillis(); @@ -31757,6 +31811,147 @@ package android.os { } +package android.os.health { + + public class HealthStats { + method public java.lang.String getDataType(); + method public long getMeasurement(int); + method public int getMeasurementKeyAt(int); + method public int getMeasurementKeyCount(); + method public java.util.Map<java.lang.String, java.lang.Long> getMeasurements(int); + method public int getMeasurementsKeyAt(int); + method public int getMeasurementsKeyCount(); + method public java.util.Map<java.lang.String, android.os.health.HealthStats> getStats(int); + method public int getStatsKeyAt(int); + method public int getStatsKeyCount(); + method public android.os.health.TimerStat getTimer(int); + method public int getTimerCount(int); + method public int getTimerKeyAt(int); + method public int getTimerKeyCount(); + method public long getTimerTime(int); + method public java.util.Map<java.lang.String, android.os.health.TimerStat> getTimers(int); + method public int getTimersKeyAt(int); + method public int getTimersKeyCount(); + method public boolean hasMeasurement(int); + method public boolean hasMeasurements(int); + method public boolean hasStats(int); + method public boolean hasTimer(int); + method public boolean hasTimers(int); + } + + public final class PackageHealthStats { + field public static final int MEASUREMENTS_WAKEUP_ALARMS_COUNT = 40002; // 0x9c42 + field public static final int STATS_SERVICES = 40001; // 0x9c41 + } + + public final class PidHealthStats { + field public static final int MEASUREMENT_WAKE_NESTING_COUNT = 20001; // 0x4e21 + field public static final int MEASUREMENT_WAKE_START_MS = 20003; // 0x4e23 + field public static final int MEASUREMENT_WAKE_SUM_MS = 20002; // 0x4e22 + } + + public final class ProcessHealthStats { + field public static final int MEASUREMENT_ANR_COUNT = 30005; // 0x7535 + field public static final int MEASUREMENT_CRASHES_COUNT = 30004; // 0x7534 + field public static final int MEASUREMENT_FOREGROUND_MS = 30006; // 0x7536 + field public static final int MEASUREMENT_STARTS_COUNT = 30003; // 0x7533 + field public static final int MEASUREMENT_SYSTEM_TIME_MS = 30002; // 0x7532 + field public static final int MEASUREMENT_USER_TIME_MS = 30001; // 0x7531 + } + + public final class ServiceHealthStats { + field public static final int MEASUREMENT_LAUNCH_COUNT = 50002; // 0xc352 + field public static final int MEASUREMENT_START_SERVICE_COUNT = 50001; // 0xc351 + } + + public class SystemHealthManager { + method public static android.os.health.SystemHealthManager from(android.content.Context); + method public android.os.health.HealthStats takeMyUidSnapshot(); + method public android.os.health.HealthStats takeUidSnapshot(int); + method public android.os.health.HealthStats[] takeUidSnapshots(int[]); + } + + public class TimerStat implements android.os.Parcelable { + ctor public TimerStat(); + ctor public TimerStat(int, long); + ctor public TimerStat(android.os.Parcel); + method public int describeContents(); + method public int getCount(); + method public long getTime(); + method public void setCount(int); + method public void setTime(long); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.os.health.TimerStat> CREATOR; + } + + public final class UidHealthStats { + field public static final int MEASUREMENT_BLUETOOTH_IDLE_MS = 10020; // 0x2724 + field public static final int MEASUREMENT_BLUETOOTH_POWER_MAMS = 10023; // 0x2727 + field public static final int MEASUREMENT_BLUETOOTH_RX_BYTES = 10052; // 0x2744 + field public static final int MEASUREMENT_BLUETOOTH_RX_MS = 10021; // 0x2725 + field public static final int MEASUREMENT_BLUETOOTH_RX_PACKETS = 10058; // 0x274a + field public static final int MEASUREMENT_BLUETOOTH_TX_BYTES = 10053; // 0x2745 + field public static final int MEASUREMENT_BLUETOOTH_TX_MS = 10022; // 0x2726 + field public static final int MEASUREMENT_BLUETOOTH_TX_PACKETS = 10059; // 0x274b + field public static final int MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT = 10046; // 0x273e + field public static final int MEASUREMENT_CPU_POWER_MAUS = 10064; // 0x2750 + field public static final int MEASUREMENT_MOBILE_IDLE_MS = 10024; // 0x2728 + field public static final int MEASUREMENT_MOBILE_POWER_MAMS = 10027; // 0x272b + field public static final int MEASUREMENT_MOBILE_RX_BYTES = 10048; // 0x2740 + field public static final int MEASUREMENT_MOBILE_RX_MS = 10025; // 0x2729 + field public static final int MEASUREMENT_MOBILE_RX_PACKETS = 10054; // 0x2746 + field public static final int MEASUREMENT_MOBILE_TX_BYTES = 10049; // 0x2741 + field public static final int MEASUREMENT_MOBILE_TX_MS = 10026; // 0x272a + field public static final int MEASUREMENT_MOBILE_TX_PACKETS = 10055; // 0x2747 + field public static final int MEASUREMENT_OTHER_USER_ACTIVITY_COUNT = 10045; // 0x273d + field public static final int MEASUREMENT_REALTIME_BATTERY_MS = 10001; // 0x2711 + field public static final int MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS = 10003; // 0x2713 + field public static final int MEASUREMENT_SYSTEM_CPU_TIME_US = 10063; // 0x274f + field public static final int MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT = 10047; // 0x273f + field public static final int MEASUREMENT_UPTIME_BATTERY_MS = 10002; // 0x2712 + field public static final int MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS = 10004; // 0x2714 + field public static final int MEASUREMENT_USER_CPU_TIME_US = 10062; // 0x274e + field public static final int MEASUREMENT_WIFI_FULL_LOCK_MS = 10029; // 0x272d + field public static final int MEASUREMENT_WIFI_IDLE_MS = 10016; // 0x2720 + field public static final int MEASUREMENT_WIFI_MULTICAST_MS = 10031; // 0x272f + field public static final int MEASUREMENT_WIFI_POWER_MAMS = 10019; // 0x2723 + field public static final int MEASUREMENT_WIFI_RUNNING_MS = 10028; // 0x272c + field public static final int MEASUREMENT_WIFI_RX_BYTES = 10050; // 0x2742 + field public static final int MEASUREMENT_WIFI_RX_MS = 10017; // 0x2721 + field public static final int MEASUREMENT_WIFI_RX_PACKETS = 10056; // 0x2748 + field public static final int MEASUREMENT_WIFI_TX_BYTES = 10051; // 0x2743 + field public static final int MEASUREMENT_WIFI_TX_MS = 10018; // 0x2722 + field public static final int MEASUREMENT_WIFI_TX_PACKETS = 10057; // 0x2749 + field public static final int STATS_PACKAGES = 10015; // 0x271f + field public static final int STATS_PIDS = 10013; // 0x271d + field public static final int STATS_PROCESSES = 10014; // 0x271e + field public static final int TIMERS_JOBS = 10010; // 0x271a + field public static final int TIMERS_SENSORS = 10012; // 0x271c + field public static final int TIMERS_SYNCS = 10009; // 0x2719 + field public static final int TIMERS_WAKELOCKS_DRAW = 10008; // 0x2718 + field public static final int TIMERS_WAKELOCKS_FULL = 10005; // 0x2715 + field public static final int TIMERS_WAKELOCKS_PARTIAL = 10006; // 0x2716 + field public static final int TIMERS_WAKELOCKS_WINDOW = 10007; // 0x2717 + field public static final int TIMER_AUDIO = 10032; // 0x2730 + field public static final int TIMER_BLUETOOTH_SCAN = 10037; // 0x2735 + field public static final int TIMER_CAMERA = 10035; // 0x2733 + field public static final int TIMER_FLASHLIGHT = 10034; // 0x2732 + field public static final int TIMER_FOREGROUND_ACTIVITY = 10036; // 0x2734 + field public static final int TIMER_GPS_SENSOR = 10011; // 0x271b + field public static final int TIMER_MOBILE_RADIO_ACTIVE = 10061; // 0x274d + field public static final int TIMER_PROCESS_STATE_BACKGROUND_MS = 10042; // 0x273a + field public static final int TIMER_PROCESS_STATE_CACHED_MS = 10043; // 0x273b + field public static final int TIMER_PROCESS_STATE_FOREGROUND_MS = 10041; // 0x2739 + field public static final int TIMER_PROCESS_STATE_FOREGROUND_SERVICE_MS = 10039; // 0x2737 + field public static final int TIMER_PROCESS_STATE_TOP_MS = 10038; // 0x2736 + field public static final int TIMER_PROCESS_STATE_TOP_SLEEPING_MS = 10040; // 0x2738 + field public static final int TIMER_VIBRATOR = 10044; // 0x273c + field public static final int TIMER_VIDEO = 10033; // 0x2731 + field public static final int TIMER_WIFI_SCAN = 10030; // 0x272e + } + +} + package android.os.storage { public abstract class OnObbStateChangeListener { @@ -53817,6 +54012,7 @@ package java.lang { public abstract interface Iterable { method public default void forEach(java.util.function.Consumer<? super T>); method public abstract java.util.Iterator<T> iterator(); + method public default java.util.Spliterator<T> spliterator(); } public class LinkageError extends java.lang.Error { @@ -60237,6 +60433,7 @@ package java.util { method public E removeLast(); method public boolean removeLastOccurrence(java.lang.Object); method public int size(); + method public java.util.Spliterator<E> spliterator(); } public class ArrayList extends java.util.AbstractList implements java.lang.Cloneable java.util.List java.util.RandomAccess java.io.Serializable { @@ -60248,6 +60445,7 @@ package java.util { method public void forEach(java.util.function.Consumer<? super E>); method public E get(int); method public int size(); + method public java.util.Spliterator<E> spliterator(); method public void trimToSize(); } @@ -60348,6 +60546,14 @@ package java.util { method public static void sort(java.lang.Object[], int, int); method public static void sort(T[], java.util.Comparator<? super T>); method public static void sort(T[], int, int, java.util.Comparator<? super T>); + method public static java.util.Spliterator<T> spliterator(T[]); + method public static java.util.Spliterator<T> spliterator(T[], int, int); + method public static java.util.Spliterator.OfInt spliterator(int[]); + method public static java.util.Spliterator.OfInt spliterator(int[], int, int); + method public static java.util.Spliterator.OfLong spliterator(long[]); + method public static java.util.Spliterator.OfLong spliterator(long[], int, int); + method public static java.util.Spliterator.OfDouble spliterator(double[]); + method public static java.util.Spliterator.OfDouble spliterator(double[], int, int); method public static java.lang.String toString(long[]); method public static java.lang.String toString(int[]); method public static java.lang.String toString(short[]); @@ -60691,6 +60897,17 @@ package java.util { method public abstract int size(); } + public class DoubleSummaryStatistics implements java.util.function.DoubleConsumer { + ctor public DoubleSummaryStatistics(); + method public void accept(double); + method public void combine(java.util.DoubleSummaryStatistics); + method public final double getAverage(); + method public final long getCount(); + method public final double getMax(); + method public final double getMin(); + method public final double getSum(); + } + public class DuplicateFormatFlagsException extends java.util.IllegalFormatException { ctor public DuplicateFormatFlagsException(java.lang.String); method public java.lang.String getFlags(); @@ -60836,6 +61053,7 @@ package java.util { method public java.lang.Object clone(); method public java.util.Iterator<E> iterator(); method public int size(); + method public java.util.Spliterator<E> spliterator(); } public class Hashtable extends java.util.Dictionary implements java.lang.Cloneable java.util.Map java.io.Serializable { @@ -60913,6 +61131,17 @@ package java.util { ctor public InputMismatchException(java.lang.String); } + public class IntSummaryStatistics implements java.util.function.IntConsumer { + ctor public IntSummaryStatistics(); + method public void accept(int); + method public void combine(java.util.IntSummaryStatistics); + method public final double getAverage(); + method public final long getCount(); + method public final int getMax(); + method public final int getMin(); + method public final long getSum(); + } + public class InvalidPropertiesFormatException extends java.io.IOException { ctor public InvalidPropertiesFormatException(java.lang.Throwable); ctor public InvalidPropertiesFormatException(java.lang.String); @@ -60969,6 +61198,7 @@ package java.util { method public E removeLast(); method public boolean removeLastOccurrence(java.lang.Object); method public int size(); + method public java.util.Spliterator<E> spliterator(); } public abstract interface List implements java.util.Collection { @@ -61104,6 +61334,18 @@ package java.util { enum_constant public static final java.util.Locale.Category FORMAT; } + public class LongSummaryStatistics implements java.util.function.IntConsumer java.util.function.LongConsumer { + ctor public LongSummaryStatistics(); + method public void accept(int); + method public void accept(long); + method public void combine(java.util.LongSummaryStatistics); + method public final double getAverage(); + method public final long getCount(); + method public final long getMax(); + method public final long getMin(); + method public final long getSum(); + } + public abstract interface Map { method public abstract void clear(); method public abstract boolean containsKey(java.lang.Object); @@ -61123,6 +61365,8 @@ package java.util { } public static abstract interface Map.Entry { + method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByKey(); + method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByKey(java.util.Comparator<? super K>); method public abstract boolean equals(java.lang.Object); method public abstract K getKey(); method public abstract V getValue(); @@ -61301,6 +61545,7 @@ package java.util { public class PriorityQueue extends java.util.AbstractQueue implements java.io.Serializable { ctor public PriorityQueue(); ctor public PriorityQueue(int); + ctor public PriorityQueue(java.util.Comparator<? super E>); ctor public PriorityQueue(int, java.util.Comparator<? super E>); ctor public PriorityQueue(java.util.Collection<? extends E>); ctor public PriorityQueue(java.util.PriorityQueue<? extends E>); @@ -61311,6 +61556,7 @@ package java.util { method public E peek(); method public E poll(); method public int size(); + method public final java.util.Spliterator<E> spliterator(); } public class Properties extends java.util.Hashtable { @@ -61553,6 +61799,111 @@ package java.util { method public abstract java.util.SortedSet<E> tailSet(E); } + public abstract interface Spliterator { + method public abstract int characteristics(); + method public abstract long estimateSize(); + method public default void forEachRemaining(java.util.function.Consumer<? super T>); + method public default java.util.Comparator<? super T> getComparator(); + method public default long getExactSizeIfKnown(); + method public default boolean hasCharacteristics(int); + method public abstract boolean tryAdvance(java.util.function.Consumer<? super T>); + method public abstract java.util.Spliterator<T> trySplit(); + field public static final int CONCURRENT = 4096; // 0x1000 + field public static final int DISTINCT = 1; // 0x1 + field public static final int IMMUTABLE = 1024; // 0x400 + field public static final int NONNULL = 256; // 0x100 + field public static final int ORDERED = 16; // 0x10 + field public static final int SIZED = 64; // 0x40 + field public static final int SORTED = 4; // 0x4 + field public static final int SUBSIZED = 16384; // 0x4000 + } + + public static abstract interface Spliterator.OfDouble implements java.util.Spliterator.OfPrimitive { + method public default void forEachRemaining(java.util.function.DoubleConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Double>); + method public abstract boolean tryAdvance(java.util.function.DoubleConsumer); + method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Double>); + method public abstract java.util.Spliterator.OfDouble trySplit(); + } + + public static abstract interface Spliterator.OfInt implements java.util.Spliterator.OfPrimitive { + method public default void forEachRemaining(java.util.function.IntConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Integer>); + method public abstract boolean tryAdvance(java.util.function.IntConsumer); + method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Integer>); + method public abstract java.util.Spliterator.OfInt trySplit(); + } + + public static abstract interface Spliterator.OfLong implements java.util.Spliterator.OfPrimitive { + method public default void forEachRemaining(java.util.function.LongConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Long>); + method public abstract boolean tryAdvance(java.util.function.LongConsumer); + method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Long>); + method public abstract java.util.Spliterator.OfLong trySplit(); + } + + public static abstract interface Spliterator.OfPrimitive implements java.util.Spliterator { + method public default void forEachRemaining(T_CONS); + method public abstract boolean tryAdvance(T_CONS); + method public abstract T_SPLITR trySplit(); + } + + public final class Spliterators { + method public static java.util.Spliterator.OfDouble emptyDoubleSpliterator(); + method public static java.util.Spliterator.OfInt emptyIntSpliterator(); + method public static java.util.Spliterator.OfLong emptyLongSpliterator(); + method public static java.util.Spliterator<T> emptySpliterator(); + method public static java.util.Iterator<T> iterator(java.util.Spliterator<? extends T>); + method public static java.util.PrimitiveIterator.OfInt iterator(java.util.Spliterator.OfInt); + method public static java.util.PrimitiveIterator.OfLong iterator(java.util.Spliterator.OfLong); + method public static java.util.PrimitiveIterator.OfDouble iterator(java.util.Spliterator.OfDouble); + method public static java.util.Spliterator<T> spliterator(java.lang.Object[], int); + method public static java.util.Spliterator<T> spliterator(java.lang.Object[], int, int, int); + method public static java.util.Spliterator.OfInt spliterator(int[], int); + method public static java.util.Spliterator.OfInt spliterator(int[], int, int, int); + method public static java.util.Spliterator.OfLong spliterator(long[], int); + method public static java.util.Spliterator.OfLong spliterator(long[], int, int, int); + method public static java.util.Spliterator.OfDouble spliterator(double[], int); + method public static java.util.Spliterator.OfDouble spliterator(double[], int, int, int); + method public static java.util.Spliterator<T> spliterator(java.util.Collection<? extends T>, int); + method public static java.util.Spliterator<T> spliterator(java.util.Iterator<? extends T>, long, int); + method public static java.util.Spliterator.OfInt spliterator(java.util.PrimitiveIterator.OfInt, long, int); + method public static java.util.Spliterator.OfLong spliterator(java.util.PrimitiveIterator.OfLong, long, int); + method public static java.util.Spliterator.OfDouble spliterator(java.util.PrimitiveIterator.OfDouble, long, int); + method public static java.util.Spliterator<T> spliteratorUnknownSize(java.util.Iterator<? extends T>, int); + method public static java.util.Spliterator.OfInt spliteratorUnknownSize(java.util.PrimitiveIterator.OfInt, int); + method public static java.util.Spliterator.OfLong spliteratorUnknownSize(java.util.PrimitiveIterator.OfLong, int); + method public static java.util.Spliterator.OfDouble spliteratorUnknownSize(java.util.PrimitiveIterator.OfDouble, int); + } + + public static abstract class Spliterators.AbstractDoubleSpliterator implements java.util.Spliterator.OfDouble { + ctor protected Spliterators.AbstractDoubleSpliterator(long, int); + method public int characteristics(); + method public long estimateSize(); + method public java.util.Spliterator.OfDouble trySplit(); + } + + public static abstract class Spliterators.AbstractIntSpliterator implements java.util.Spliterator.OfInt { + ctor protected Spliterators.AbstractIntSpliterator(long, int); + method public int characteristics(); + method public long estimateSize(); + method public java.util.Spliterator.OfInt trySplit(); + } + + public static abstract class Spliterators.AbstractLongSpliterator implements java.util.Spliterator.OfLong { + ctor protected Spliterators.AbstractLongSpliterator(long, int); + method public int characteristics(); + method public long estimateSize(); + method public java.util.Spliterator.OfLong trySplit(); + } + + public static abstract class Spliterators.AbstractSpliterator implements java.util.Spliterator { + ctor protected Spliterators.AbstractSpliterator(long, int); + method public int characteristics(); + method public long estimateSize(); + method public java.util.Spliterator<T> trySplit(); + } + public class Stack extends java.util.Vector { ctor public Stack(); method public boolean empty(); @@ -61562,6 +61913,15 @@ package java.util { method public synchronized int search(java.lang.Object); } + public final class StringJoiner { + ctor public StringJoiner(java.lang.CharSequence); + ctor public StringJoiner(java.lang.CharSequence, java.lang.CharSequence, java.lang.CharSequence); + method public java.util.StringJoiner add(java.lang.CharSequence); + method public int length(); + method public java.util.StringJoiner merge(java.util.StringJoiner); + method public java.util.StringJoiner setEmptyValue(java.lang.CharSequence); + } + public class StringTokenizer implements java.util.Enumeration { ctor public StringTokenizer(java.lang.String, java.lang.String, boolean); ctor public StringTokenizer(java.lang.String, java.lang.String); @@ -61683,6 +62043,7 @@ package java.util { method public E pollFirst(); method public E pollLast(); method public int size(); + method public java.util.Spliterator<E> spliterator(); method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean); method public java.util.SortedSet<E> subSet(E, E); method public java.util.NavigableSet<E> tailSet(E, boolean); @@ -61739,6 +62100,7 @@ package java.util { method public synchronized void setElementAt(E, int); method public synchronized void setSize(int); method public synchronized int size(); + method public java.util.Spliterator<E> spliterator(); method public synchronized void trimToSize(); field protected int capacityIncrement; field protected int elementCount; diff --git a/api/test-current.txt b/api/test-current.txt index a478793a70bf..b8f7326c853a 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -879,6 +879,7 @@ package android { field public static final int nextFocusLeft = 16842977; // 0x10100e1 field public static final int nextFocusRight = 16842978; // 0x10100e2 field public static final int nextFocusUp = 16842979; // 0x10100e3 + field public static final int nfcAntennaPositionDrawable = 16844063; // 0x101051f field public static final int noHistory = 16843309; // 0x101022d field public static final int normalScreens = 16843397; // 0x1010285 field public static final int notificationTimeout = 16843651; // 0x1010383 @@ -5982,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"; @@ -8118,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"; @@ -8148,6 +8150,7 @@ package android.content { field public static final java.lang.String SENSOR_SERVICE = "sensor"; field public static final java.lang.String SHORTCUT_SERVICE = "shortcut"; field public static final java.lang.String STORAGE_SERVICE = "storage"; + field public static final java.lang.String SYSTEM_HEALTH_SERVICE = "systemhealth"; field public static final java.lang.String TELECOM_SERVICE = "telecom"; field public static final java.lang.String TELEPHONY_SERVICE = "phone"; field public static final java.lang.String TELEPHONY_SUBSCRIPTION_SERVICE = "telephony_subscription_service"; @@ -9334,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; @@ -9569,6 +9573,7 @@ package android.content.pm { method public java.lang.String[] getNames() throws java.io.IOException; method public java.io.InputStream openRead(java.lang.String) throws java.io.IOException; method public java.io.OutputStream openWrite(java.lang.String, long, long) throws java.io.IOException; + method public void removeSplit(java.lang.String) throws java.io.IOException; method public void setStagingProgress(float); } @@ -10004,6 +10009,7 @@ package android.content.pm { method public int getWeight(); method public boolean hasIconFile(); method public boolean hasIconResource(); + method public boolean hasKeyFieldsOnly(); method public boolean isDynamic(); method public boolean isPinned(); method public void writeToParcel(android.os.Parcel, int); @@ -10014,6 +10020,7 @@ package android.content.pm { field public static final int FLAG_DYNAMIC = 1; // 0x1 field public static final int FLAG_HAS_ICON_FILE = 8; // 0x8 field public static final int FLAG_HAS_ICON_RES = 4; // 0x4 + field public static final int FLAG_KEY_FIELDS_ONLY = 16; // 0x10 field public static final int FLAG_PINNED = 2; // 0x2 } @@ -10034,6 +10041,7 @@ package android.content.pm { method public void deleteAllDynamicShortcuts(); method public void deleteDynamicShortcut(java.lang.String); method public java.util.List<android.content.pm.ShortcutInfo> getDynamicShortcuts(); + method public int getIconMaxDimensions(); method public int getMaxDynamicShortcutCount(); method public java.util.List<android.content.pm.ShortcutInfo> getPinnedShortcuts(); method public long getRateLimitResetTime(); @@ -12917,7 +12925,8 @@ package android.graphics.drawable { method public int getGradientType(); method public int getOpacity(); method public android.graphics.drawable.GradientDrawable.Orientation getOrientation(); - method public boolean isUseLevel(); + method public int getShape(); + method public boolean getUseLevel(); method public void setAlpha(int); method public void setColor(int); method public void setColor(android.content.res.ColorStateList); @@ -13779,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); @@ -19235,6 +19245,7 @@ package android.location { } public final class GnssClock implements android.os.Parcelable { + ctor public GnssClock(); method public int describeContents(); method public double getBiasNanos(); method public double getBiasUncertaintyNanos(); @@ -19275,6 +19286,7 @@ package android.location { } public final class GnssMeasurement implements android.os.Parcelable { + ctor public GnssMeasurement(); method public int describeContents(); method public double getAccumulatedDeltaRangeMeters(); method public int getAccumulatedDeltaRangeState(); @@ -19317,6 +19329,7 @@ package android.location { method public void setCn0DbHz(double); method public void setConstellationType(int); method public void setMultipathIndicator(int); + method public void setPseudorangeRateCorrected(boolean); method public void setPseudorangeRateMetersPerSecond(double); method public void setPseudorangeRateUncertaintyMetersPerSecond(double); method public void setReceivedSvTimeNanos(long); @@ -19367,6 +19380,7 @@ package android.location { } public final class GnssNavigationMessage implements android.os.Parcelable { + ctor public GnssNavigationMessage(); method public int describeContents(); method public byte[] getData(); method public int getMessageId(); @@ -20238,37 +20252,129 @@ package android.media { field public static final int ORIENTATION_TRANSVERSE = 7; // 0x7 field public static final int ORIENTATION_UNDEFINED = 0; // 0x0 field public static final java.lang.String TAG_APERTURE = "FNumber"; + field public static final java.lang.String TAG_APERTURE_VALUE = "ApertureValue"; + field public static final java.lang.String TAG_ARTIST = "Artist"; + field public static final java.lang.String TAG_BITS_PER_SAMPLE = "BitsPerSample"; + field public static final java.lang.String TAG_BRIGHTNESS_VALUE = "BrightnessValue"; + field public static final java.lang.String TAG_CFA_PATTERN = "CFAPattern"; + field public static final java.lang.String TAG_COLOR_SPACE = "ColorSpace"; + field public static final java.lang.String TAG_COMPONENTS_CONFIGURATION = "ComponentsConfiguration"; + field public static final java.lang.String TAG_COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel"; + field public static final java.lang.String TAG_COMPRESSION = "Compression"; + field public static final java.lang.String TAG_CONTRAST = "Contrast"; + field public static final java.lang.String TAG_COPYRIGHT = "Copyright"; + field public static final java.lang.String TAG_CUSTOM_RENDERED = "CustomRendered"; field public static final java.lang.String TAG_DATETIME = "DateTime"; field public static final java.lang.String TAG_DATETIME_DIGITIZED = "DateTimeDigitized"; + field public static final java.lang.String TAG_DATETIME_ORIGINAL = "DateTimeOriginal"; + field public static final java.lang.String TAG_DEVICE_SETTING_DESCRIPTION = "DeviceSettingDescription"; field public static final java.lang.String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio"; + field public static final java.lang.String TAG_EXIF_VERSION = "ExifVersion"; field public static final java.lang.String TAG_EXPOSURE_BIAS_VALUE = "ExposureBiasValue"; + field public static final java.lang.String TAG_EXPOSURE_INDEX = "ExposureIndex"; field public static final java.lang.String TAG_EXPOSURE_MODE = "ExposureMode"; field public static final java.lang.String TAG_EXPOSURE_PROGRAM = "ExposureProgram"; field public static final java.lang.String TAG_EXPOSURE_TIME = "ExposureTime"; + field public static final java.lang.String TAG_FILE_SOURCE = "FileSource"; field public static final java.lang.String TAG_FLASH = "Flash"; + field public static final java.lang.String TAG_FLASHPIX_VERSION = "FlashpixVersion"; + field public static final java.lang.String TAG_FLASH_ENERGY = "FlashEnergy"; field public static final java.lang.String TAG_FOCAL_LENGTH = "FocalLength"; + field public static final java.lang.String TAG_FOCAL_LENGTH_IN_35MM_FILM = "FocalLengthIn35mmFilm"; + field public static final java.lang.String TAG_FOCAL_PLANE_RESOLUTION_UNIT = "FocalPlaneResolutionUnit"; + field public static final java.lang.String TAG_FOCAL_PLANE_X_RESOLUTION = "FocalPlaneXResolution"; + field public static final java.lang.String TAG_FOCAL_PLANE_Y_RESOLUTION = "FocalPlaneYResolution"; + field public static final java.lang.String TAG_F_NUMBER = "FNumber"; + field public static final java.lang.String TAG_GAIN_CONTROL = "GainControl"; field public static final java.lang.String TAG_GPS_ALTITUDE = "GPSAltitude"; field public static final java.lang.String TAG_GPS_ALTITUDE_REF = "GPSAltitudeRef"; + field public static final java.lang.String TAG_GPS_AREA_INFORMATION = "GPSAreaInformation"; field public static final java.lang.String TAG_GPS_DATESTAMP = "GPSDateStamp"; + field public static final java.lang.String TAG_GPS_DEST_BEARING = "GPSDestBearing"; + field public static final java.lang.String TAG_GPS_DEST_BEARING_REF = "GPSDestBearingRef"; + field public static final java.lang.String TAG_GPS_DEST_DISTANCE = "GPSDestDistance"; + field public static final java.lang.String TAG_GPS_DEST_DISTANCE_REF = "GPSDestDistanceRef"; + field public static final java.lang.String TAG_GPS_DEST_LATITUDE = "GPSDestLatitude"; + field public static final java.lang.String TAG_GPS_DEST_LATITUDE_REF = "GPSDestLatitudeRef"; + field public static final java.lang.String TAG_GPS_DEST_LONGITUDE = "GPSDestLongitude"; + field public static final java.lang.String TAG_GPS_DEST_LONGITUDE_REF = "GPSDestLongitudeRef"; + field public static final java.lang.String TAG_GPS_DIFFERENTIAL = "GPSDifferential"; + field public static final java.lang.String TAG_GPS_DOP = "GPSDOP"; + field public static final java.lang.String TAG_GPS_IMG_DIRECTION = "GPSImgDirection"; + field public static final java.lang.String TAG_GPS_IMG_DIRECTION_REF = "GPSImgDirectionRef"; field public static final java.lang.String TAG_GPS_LATITUDE = "GPSLatitude"; field public static final java.lang.String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef"; field public static final java.lang.String TAG_GPS_LONGITUDE = "GPSLongitude"; field public static final java.lang.String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef"; + field public static final java.lang.String TAG_GPS_MAP_DATUM = "GPSMapDatum"; + field public static final java.lang.String TAG_GPS_MEASURE_MODE = "GPSMeasureMode"; field public static final java.lang.String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod"; + field public static final java.lang.String TAG_GPS_SATELLITES = "GPSSatellites"; + field public static final java.lang.String TAG_GPS_SPEED = "GPSSpeed"; + field public static final java.lang.String TAG_GPS_SPEED_REF = "GPSSpeedRef"; + field public static final java.lang.String TAG_GPS_STATUS = "GPSStatus"; field public static final java.lang.String TAG_GPS_TIMESTAMP = "GPSTimeStamp"; + field public static final java.lang.String TAG_GPS_TRACK = "GPSTrack"; + field public static final java.lang.String TAG_GPS_TRACK_REF = "GPSTrackRef"; + field public static final java.lang.String TAG_GPS_VERSION_ID = "GPSVersionID"; + field public static final java.lang.String TAG_IMAGE_DESCRIPTION = "ImageDescription"; field public static final java.lang.String TAG_IMAGE_LENGTH = "ImageLength"; + field public static final java.lang.String TAG_IMAGE_UNIQUE_ID = "ImageUniqueID"; field public static final java.lang.String TAG_IMAGE_WIDTH = "ImageWidth"; + field public static final java.lang.String TAG_INTEROPERABILITY_INDEX = "InteroperabilityIndex"; field public static final java.lang.String TAG_ISO = "ISOSpeedRatings"; + field public static final java.lang.String TAG_ISO_SPEED_RATINGS = "ISOSpeedRatings"; + field public static final java.lang.String TAG_JPEG_INTERCHANGE_FORMAT = "JPEGInterchangeFormat"; + field public static final java.lang.String TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = "JPEGInterchangeFormatLength"; field public static final java.lang.String TAG_LIGHT_SOURCE = "LightSource"; field public static final java.lang.String TAG_MAKE = "Make"; + field public static final java.lang.String TAG_MAKER_NOTE = "MakerNote"; + field public static final java.lang.String TAG_MAX_APERTURE_VALUE = "MaxApertureValue"; field public static final java.lang.String TAG_METERING_MODE = "MeteringMode"; field public static final java.lang.String TAG_MODEL = "Model"; + field public static final java.lang.String TAG_OECF = "OECF"; field public static final java.lang.String TAG_ORIENTATION = "Orientation"; + field public static final java.lang.String TAG_PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation"; + field public static final java.lang.String TAG_PIXEL_X_DIMENSION = "PixelXDimension"; + field public static final java.lang.String TAG_PIXEL_Y_DIMENSION = "PixelYDimension"; + field public static final java.lang.String TAG_PLANAR_CONFIGURATION = "PlanarConfiguration"; + field public static final java.lang.String TAG_PRIMARY_CHROMATICITIES = "PrimaryChromaticities"; + field public static final java.lang.String TAG_REFERENCE_BLACK_WHITE = "ReferenceBlackWhite"; + field public static final java.lang.String TAG_RELATED_SOUND_FILE = "RelatedSoundFile"; + field public static final java.lang.String TAG_RESOLUTION_UNIT = "ResolutionUnit"; + field public static final java.lang.String TAG_ROWS_PER_STRIP = "RowsPerStrip"; + field public static final java.lang.String TAG_SAMPLES_PER_PIXEL = "SamplesPerPixel"; + field public static final java.lang.String TAG_SATURATION = "Saturation"; + field public static final java.lang.String TAG_SCENE_CAPTURE_TYPE = "SceneCaptureType"; + field public static final java.lang.String TAG_SCENE_TYPE = "SceneType"; + field public static final java.lang.String TAG_SENSING_METHOD = "SensingMethod"; + field public static final java.lang.String TAG_SHARPNESS = "Sharpness"; + field public static final java.lang.String TAG_SHUTTER_SPEED_VALUE = "ShutterSpeedValue"; + field public static final java.lang.String TAG_SOFTWARE = "Software"; + field public static final java.lang.String TAG_SPATIAL_FREQUENCY_RESPONSE = "SpatialFrequencyResponse"; + field public static final java.lang.String TAG_SPECTRAL_SENSITIVITY = "SpectralSensitivity"; + field public static final java.lang.String TAG_STRIP_BYTE_COUNTS = "StripByteCounts"; + field public static final java.lang.String TAG_STRIP_OFFSETS = "StripOffsets"; + field public static final java.lang.String TAG_SUBJECT_AREA = "SubjectArea"; field public static final java.lang.String TAG_SUBJECT_DISTANCE = "SubjectDistance"; + field public static final java.lang.String TAG_SUBJECT_DISTANCE_RANGE = "SubjectDistanceRange"; + field public static final java.lang.String TAG_SUBJECT_LOCATION = "SubjectLocation"; field public static final java.lang.String TAG_SUBSEC_TIME = "SubSecTime"; field public static final java.lang.String TAG_SUBSEC_TIME_DIG = "SubSecTimeDigitized"; + field public static final java.lang.String TAG_SUBSEC_TIME_DIGITIZED = "SubSecTimeDigitized"; field public static final java.lang.String TAG_SUBSEC_TIME_ORIG = "SubSecTimeOriginal"; + field public static final java.lang.String TAG_SUBSEC_TIME_ORIGINAL = "SubSecTimeOriginal"; + field public static final java.lang.String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength"; + field public static final java.lang.String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth"; + field public static final java.lang.String TAG_TRANSFER_FUNCTION = "TransferFunction"; + field public static final java.lang.String TAG_USER_COMMENT = "UserComment"; field public static final java.lang.String TAG_WHITE_BALANCE = "WhiteBalance"; + field public static final java.lang.String TAG_WHITE_POINT = "WhitePoint"; + field public static final java.lang.String TAG_X_RESOLUTION = "XResolution"; + field public static final java.lang.String TAG_Y_CB_CR_COEFFICIENTS = "YCbCrCoefficients"; + field public static final java.lang.String TAG_Y_CB_CR_POSITIONING = "YCbCrPositioning"; + field public static final java.lang.String TAG_Y_CB_CR_SUB_SAMPLING = "YCbCrSubSampling"; + field public static final java.lang.String TAG_Y_RESOLUTION = "YResolution"; field public static final int WHITEBALANCE_AUTO = 0; // 0x0 field public static final int WHITEBALANCE_MANUAL = 1; // 0x1 } @@ -20994,6 +21100,7 @@ package android.media { field public static final java.lang.String KEY_DURATION = "durationUs"; field public static final java.lang.String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level"; field public static final java.lang.String KEY_FRAME_RATE = "frame-rate"; + field public static final java.lang.String KEY_HDR_STATIC_INFO = "hdr-static-info"; field public static final java.lang.String KEY_HEIGHT = "height"; field public static final java.lang.String KEY_INTRA_REFRESH_PERIOD = "intra-refresh-period"; field public static final java.lang.String KEY_IS_ADTS = "is-adts"; @@ -29091,7 +29198,6 @@ package android.os { ctor public PersistableBundle(); ctor public PersistableBundle(int); ctor public PersistableBundle(android.os.PersistableBundle); - ctor public PersistableBundle(android.os.Bundle); method public java.lang.Object clone(); method public int describeContents(); method public android.os.PersistableBundle getPersistableBundle(java.lang.String); @@ -29135,6 +29241,7 @@ package android.os { public class Process { ctor public Process(); method public static final long getElapsedCpuTime(); + method public static final int[] getExclusiveCores(); method public static final int getGidForName(java.lang.String); method public static final long getStartElapsedRealtime(); method public static final long getStartUptimeMillis(); @@ -29420,6 +29527,147 @@ package android.os { } +package android.os.health { + + public class HealthStats { + method public java.lang.String getDataType(); + method public long getMeasurement(int); + method public int getMeasurementKeyAt(int); + method public int getMeasurementKeyCount(); + method public java.util.Map<java.lang.String, java.lang.Long> getMeasurements(int); + method public int getMeasurementsKeyAt(int); + method public int getMeasurementsKeyCount(); + method public java.util.Map<java.lang.String, android.os.health.HealthStats> getStats(int); + method public int getStatsKeyAt(int); + method public int getStatsKeyCount(); + method public android.os.health.TimerStat getTimer(int); + method public int getTimerCount(int); + method public int getTimerKeyAt(int); + method public int getTimerKeyCount(); + method public long getTimerTime(int); + method public java.util.Map<java.lang.String, android.os.health.TimerStat> getTimers(int); + method public int getTimersKeyAt(int); + method public int getTimersKeyCount(); + method public boolean hasMeasurement(int); + method public boolean hasMeasurements(int); + method public boolean hasStats(int); + method public boolean hasTimer(int); + method public boolean hasTimers(int); + } + + public final class PackageHealthStats { + field public static final int MEASUREMENTS_WAKEUP_ALARMS_COUNT = 40002; // 0x9c42 + field public static final int STATS_SERVICES = 40001; // 0x9c41 + } + + public final class PidHealthStats { + field public static final int MEASUREMENT_WAKE_NESTING_COUNT = 20001; // 0x4e21 + field public static final int MEASUREMENT_WAKE_START_MS = 20003; // 0x4e23 + field public static final int MEASUREMENT_WAKE_SUM_MS = 20002; // 0x4e22 + } + + public final class ProcessHealthStats { + field public static final int MEASUREMENT_ANR_COUNT = 30005; // 0x7535 + field public static final int MEASUREMENT_CRASHES_COUNT = 30004; // 0x7534 + field public static final int MEASUREMENT_FOREGROUND_MS = 30006; // 0x7536 + field public static final int MEASUREMENT_STARTS_COUNT = 30003; // 0x7533 + field public static final int MEASUREMENT_SYSTEM_TIME_MS = 30002; // 0x7532 + field public static final int MEASUREMENT_USER_TIME_MS = 30001; // 0x7531 + } + + public final class ServiceHealthStats { + field public static final int MEASUREMENT_LAUNCH_COUNT = 50002; // 0xc352 + field public static final int MEASUREMENT_START_SERVICE_COUNT = 50001; // 0xc351 + } + + public class SystemHealthManager { + method public static android.os.health.SystemHealthManager from(android.content.Context); + method public android.os.health.HealthStats takeMyUidSnapshot(); + method public android.os.health.HealthStats takeUidSnapshot(int); + method public android.os.health.HealthStats[] takeUidSnapshots(int[]); + } + + public class TimerStat implements android.os.Parcelable { + ctor public TimerStat(); + ctor public TimerStat(int, long); + ctor public TimerStat(android.os.Parcel); + method public int describeContents(); + method public int getCount(); + method public long getTime(); + method public void setCount(int); + method public void setTime(long); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.os.health.TimerStat> CREATOR; + } + + public final class UidHealthStats { + field public static final int MEASUREMENT_BLUETOOTH_IDLE_MS = 10020; // 0x2724 + field public static final int MEASUREMENT_BLUETOOTH_POWER_MAMS = 10023; // 0x2727 + field public static final int MEASUREMENT_BLUETOOTH_RX_BYTES = 10052; // 0x2744 + field public static final int MEASUREMENT_BLUETOOTH_RX_MS = 10021; // 0x2725 + field public static final int MEASUREMENT_BLUETOOTH_RX_PACKETS = 10058; // 0x274a + field public static final int MEASUREMENT_BLUETOOTH_TX_BYTES = 10053; // 0x2745 + field public static final int MEASUREMENT_BLUETOOTH_TX_MS = 10022; // 0x2726 + field public static final int MEASUREMENT_BLUETOOTH_TX_PACKETS = 10059; // 0x274b + field public static final int MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT = 10046; // 0x273e + field public static final int MEASUREMENT_CPU_POWER_MAUS = 10064; // 0x2750 + field public static final int MEASUREMENT_MOBILE_IDLE_MS = 10024; // 0x2728 + field public static final int MEASUREMENT_MOBILE_POWER_MAMS = 10027; // 0x272b + field public static final int MEASUREMENT_MOBILE_RX_BYTES = 10048; // 0x2740 + field public static final int MEASUREMENT_MOBILE_RX_MS = 10025; // 0x2729 + field public static final int MEASUREMENT_MOBILE_RX_PACKETS = 10054; // 0x2746 + field public static final int MEASUREMENT_MOBILE_TX_BYTES = 10049; // 0x2741 + field public static final int MEASUREMENT_MOBILE_TX_MS = 10026; // 0x272a + field public static final int MEASUREMENT_MOBILE_TX_PACKETS = 10055; // 0x2747 + field public static final int MEASUREMENT_OTHER_USER_ACTIVITY_COUNT = 10045; // 0x273d + field public static final int MEASUREMENT_REALTIME_BATTERY_MS = 10001; // 0x2711 + field public static final int MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS = 10003; // 0x2713 + field public static final int MEASUREMENT_SYSTEM_CPU_TIME_US = 10063; // 0x274f + field public static final int MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT = 10047; // 0x273f + field public static final int MEASUREMENT_UPTIME_BATTERY_MS = 10002; // 0x2712 + field public static final int MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS = 10004; // 0x2714 + field public static final int MEASUREMENT_USER_CPU_TIME_US = 10062; // 0x274e + field public static final int MEASUREMENT_WIFI_FULL_LOCK_MS = 10029; // 0x272d + field public static final int MEASUREMENT_WIFI_IDLE_MS = 10016; // 0x2720 + field public static final int MEASUREMENT_WIFI_MULTICAST_MS = 10031; // 0x272f + field public static final int MEASUREMENT_WIFI_POWER_MAMS = 10019; // 0x2723 + field public static final int MEASUREMENT_WIFI_RUNNING_MS = 10028; // 0x272c + field public static final int MEASUREMENT_WIFI_RX_BYTES = 10050; // 0x2742 + field public static final int MEASUREMENT_WIFI_RX_MS = 10017; // 0x2721 + field public static final int MEASUREMENT_WIFI_RX_PACKETS = 10056; // 0x2748 + field public static final int MEASUREMENT_WIFI_TX_BYTES = 10051; // 0x2743 + field public static final int MEASUREMENT_WIFI_TX_MS = 10018; // 0x2722 + field public static final int MEASUREMENT_WIFI_TX_PACKETS = 10057; // 0x2749 + field public static final int STATS_PACKAGES = 10015; // 0x271f + field public static final int STATS_PIDS = 10013; // 0x271d + field public static final int STATS_PROCESSES = 10014; // 0x271e + field public static final int TIMERS_JOBS = 10010; // 0x271a + field public static final int TIMERS_SENSORS = 10012; // 0x271c + field public static final int TIMERS_SYNCS = 10009; // 0x2719 + field public static final int TIMERS_WAKELOCKS_DRAW = 10008; // 0x2718 + field public static final int TIMERS_WAKELOCKS_FULL = 10005; // 0x2715 + field public static final int TIMERS_WAKELOCKS_PARTIAL = 10006; // 0x2716 + field public static final int TIMERS_WAKELOCKS_WINDOW = 10007; // 0x2717 + field public static final int TIMER_AUDIO = 10032; // 0x2730 + field public static final int TIMER_BLUETOOTH_SCAN = 10037; // 0x2735 + field public static final int TIMER_CAMERA = 10035; // 0x2733 + field public static final int TIMER_FLASHLIGHT = 10034; // 0x2732 + field public static final int TIMER_FOREGROUND_ACTIVITY = 10036; // 0x2734 + field public static final int TIMER_GPS_SENSOR = 10011; // 0x271b + field public static final int TIMER_MOBILE_RADIO_ACTIVE = 10061; // 0x274d + field public static final int TIMER_PROCESS_STATE_BACKGROUND_MS = 10042; // 0x273a + field public static final int TIMER_PROCESS_STATE_CACHED_MS = 10043; // 0x273b + field public static final int TIMER_PROCESS_STATE_FOREGROUND_MS = 10041; // 0x2739 + field public static final int TIMER_PROCESS_STATE_FOREGROUND_SERVICE_MS = 10039; // 0x2737 + field public static final int TIMER_PROCESS_STATE_TOP_MS = 10038; // 0x2736 + field public static final int TIMER_PROCESS_STATE_TOP_SLEEPING_MS = 10040; // 0x2738 + field public static final int TIMER_VIBRATOR = 10044; // 0x273c + field public static final int TIMER_VIDEO = 10033; // 0x2731 + field public static final int TIMER_WIFI_SCAN = 10030; // 0x272e + } + +} + package android.os.storage { public abstract class OnObbStateChangeListener { @@ -50738,6 +50986,7 @@ package java.lang { public abstract interface Iterable { method public default void forEach(java.util.function.Consumer<? super T>); method public abstract java.util.Iterator<T> iterator(); + method public default java.util.Spliterator<T> spliterator(); } public class LinkageError extends java.lang.Error { @@ -57158,6 +57407,7 @@ package java.util { method public E removeLast(); method public boolean removeLastOccurrence(java.lang.Object); method public int size(); + method public java.util.Spliterator<E> spliterator(); } public class ArrayList extends java.util.AbstractList implements java.lang.Cloneable java.util.List java.util.RandomAccess java.io.Serializable { @@ -57169,6 +57419,7 @@ package java.util { method public void forEach(java.util.function.Consumer<? super E>); method public E get(int); method public int size(); + method public java.util.Spliterator<E> spliterator(); method public void trimToSize(); } @@ -57269,6 +57520,14 @@ package java.util { method public static void sort(java.lang.Object[], int, int); method public static void sort(T[], java.util.Comparator<? super T>); method public static void sort(T[], int, int, java.util.Comparator<? super T>); + method public static java.util.Spliterator<T> spliterator(T[]); + method public static java.util.Spliterator<T> spliterator(T[], int, int); + method public static java.util.Spliterator.OfInt spliterator(int[]); + method public static java.util.Spliterator.OfInt spliterator(int[], int, int); + method public static java.util.Spliterator.OfLong spliterator(long[]); + method public static java.util.Spliterator.OfLong spliterator(long[], int, int); + method public static java.util.Spliterator.OfDouble spliterator(double[]); + method public static java.util.Spliterator.OfDouble spliterator(double[], int, int); method public static java.lang.String toString(long[]); method public static java.lang.String toString(int[]); method public static java.lang.String toString(short[]); @@ -57612,6 +57871,17 @@ package java.util { method public abstract int size(); } + public class DoubleSummaryStatistics implements java.util.function.DoubleConsumer { + ctor public DoubleSummaryStatistics(); + method public void accept(double); + method public void combine(java.util.DoubleSummaryStatistics); + method public final double getAverage(); + method public final long getCount(); + method public final double getMax(); + method public final double getMin(); + method public final double getSum(); + } + public class DuplicateFormatFlagsException extends java.util.IllegalFormatException { ctor public DuplicateFormatFlagsException(java.lang.String); method public java.lang.String getFlags(); @@ -57757,6 +58027,7 @@ package java.util { method public java.lang.Object clone(); method public java.util.Iterator<E> iterator(); method public int size(); + method public java.util.Spliterator<E> spliterator(); } public class Hashtable extends java.util.Dictionary implements java.lang.Cloneable java.util.Map java.io.Serializable { @@ -57834,6 +58105,17 @@ package java.util { ctor public InputMismatchException(java.lang.String); } + public class IntSummaryStatistics implements java.util.function.IntConsumer { + ctor public IntSummaryStatistics(); + method public void accept(int); + method public void combine(java.util.IntSummaryStatistics); + method public final double getAverage(); + method public final long getCount(); + method public final int getMax(); + method public final int getMin(); + method public final long getSum(); + } + public class InvalidPropertiesFormatException extends java.io.IOException { ctor public InvalidPropertiesFormatException(java.lang.Throwable); ctor public InvalidPropertiesFormatException(java.lang.String); @@ -57890,6 +58172,7 @@ package java.util { method public E removeLast(); method public boolean removeLastOccurrence(java.lang.Object); method public int size(); + method public java.util.Spliterator<E> spliterator(); } public abstract interface List implements java.util.Collection { @@ -58025,6 +58308,18 @@ package java.util { enum_constant public static final java.util.Locale.Category FORMAT; } + public class LongSummaryStatistics implements java.util.function.IntConsumer java.util.function.LongConsumer { + ctor public LongSummaryStatistics(); + method public void accept(int); + method public void accept(long); + method public void combine(java.util.LongSummaryStatistics); + method public final double getAverage(); + method public final long getCount(); + method public final long getMax(); + method public final long getMin(); + method public final long getSum(); + } + public abstract interface Map { method public abstract void clear(); method public abstract boolean containsKey(java.lang.Object); @@ -58044,6 +58339,8 @@ package java.util { } public static abstract interface Map.Entry { + method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByKey(); + method public static java.util.Comparator<java.util.Map.Entry<K, V>> comparingByKey(java.util.Comparator<? super K>); method public abstract boolean equals(java.lang.Object); method public abstract K getKey(); method public abstract V getValue(); @@ -58222,6 +58519,7 @@ package java.util { public class PriorityQueue extends java.util.AbstractQueue implements java.io.Serializable { ctor public PriorityQueue(); ctor public PriorityQueue(int); + ctor public PriorityQueue(java.util.Comparator<? super E>); ctor public PriorityQueue(int, java.util.Comparator<? super E>); ctor public PriorityQueue(java.util.Collection<? extends E>); ctor public PriorityQueue(java.util.PriorityQueue<? extends E>); @@ -58232,6 +58530,7 @@ package java.util { method public E peek(); method public E poll(); method public int size(); + method public final java.util.Spliterator<E> spliterator(); } public class Properties extends java.util.Hashtable { @@ -58474,6 +58773,111 @@ package java.util { method public abstract java.util.SortedSet<E> tailSet(E); } + public abstract interface Spliterator { + method public abstract int characteristics(); + method public abstract long estimateSize(); + method public default void forEachRemaining(java.util.function.Consumer<? super T>); + method public default java.util.Comparator<? super T> getComparator(); + method public default long getExactSizeIfKnown(); + method public default boolean hasCharacteristics(int); + method public abstract boolean tryAdvance(java.util.function.Consumer<? super T>); + method public abstract java.util.Spliterator<T> trySplit(); + field public static final int CONCURRENT = 4096; // 0x1000 + field public static final int DISTINCT = 1; // 0x1 + field public static final int IMMUTABLE = 1024; // 0x400 + field public static final int NONNULL = 256; // 0x100 + field public static final int ORDERED = 16; // 0x10 + field public static final int SIZED = 64; // 0x40 + field public static final int SORTED = 4; // 0x4 + field public static final int SUBSIZED = 16384; // 0x4000 + } + + public static abstract interface Spliterator.OfDouble implements java.util.Spliterator.OfPrimitive { + method public default void forEachRemaining(java.util.function.DoubleConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Double>); + method public abstract boolean tryAdvance(java.util.function.DoubleConsumer); + method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Double>); + method public abstract java.util.Spliterator.OfDouble trySplit(); + } + + public static abstract interface Spliterator.OfInt implements java.util.Spliterator.OfPrimitive { + method public default void forEachRemaining(java.util.function.IntConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Integer>); + method public abstract boolean tryAdvance(java.util.function.IntConsumer); + method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Integer>); + method public abstract java.util.Spliterator.OfInt trySplit(); + } + + public static abstract interface Spliterator.OfLong implements java.util.Spliterator.OfPrimitive { + method public default void forEachRemaining(java.util.function.LongConsumer); + method public default void forEachRemaining(java.util.function.Consumer<? super java.lang.Long>); + method public abstract boolean tryAdvance(java.util.function.LongConsumer); + method public default boolean tryAdvance(java.util.function.Consumer<? super java.lang.Long>); + method public abstract java.util.Spliterator.OfLong trySplit(); + } + + public static abstract interface Spliterator.OfPrimitive implements java.util.Spliterator { + method public default void forEachRemaining(T_CONS); + method public abstract boolean tryAdvance(T_CONS); + method public abstract T_SPLITR trySplit(); + } + + public final class Spliterators { + method public static java.util.Spliterator.OfDouble emptyDoubleSpliterator(); + method public static java.util.Spliterator.OfInt emptyIntSpliterator(); + method public static java.util.Spliterator.OfLong emptyLongSpliterator(); + method public static java.util.Spliterator<T> emptySpliterator(); + method public static java.util.Iterator<T> iterator(java.util.Spliterator<? extends T>); + method public static java.util.PrimitiveIterator.OfInt iterator(java.util.Spliterator.OfInt); + method public static java.util.PrimitiveIterator.OfLong iterator(java.util.Spliterator.OfLong); + method public static java.util.PrimitiveIterator.OfDouble iterator(java.util.Spliterator.OfDouble); + method public static java.util.Spliterator<T> spliterator(java.lang.Object[], int); + method public static java.util.Spliterator<T> spliterator(java.lang.Object[], int, int, int); + method public static java.util.Spliterator.OfInt spliterator(int[], int); + method public static java.util.Spliterator.OfInt spliterator(int[], int, int, int); + method public static java.util.Spliterator.OfLong spliterator(long[], int); + method public static java.util.Spliterator.OfLong spliterator(long[], int, int, int); + method public static java.util.Spliterator.OfDouble spliterator(double[], int); + method public static java.util.Spliterator.OfDouble spliterator(double[], int, int, int); + method public static java.util.Spliterator<T> spliterator(java.util.Collection<? extends T>, int); + method public static java.util.Spliterator<T> spliterator(java.util.Iterator<? extends T>, long, int); + method public static java.util.Spliterator.OfInt spliterator(java.util.PrimitiveIterator.OfInt, long, int); + method public static java.util.Spliterator.OfLong spliterator(java.util.PrimitiveIterator.OfLong, long, int); + method public static java.util.Spliterator.OfDouble spliterator(java.util.PrimitiveIterator.OfDouble, long, int); + method public static java.util.Spliterator<T> spliteratorUnknownSize(java.util.Iterator<? extends T>, int); + method public static java.util.Spliterator.OfInt spliteratorUnknownSize(java.util.PrimitiveIterator.OfInt, int); + method public static java.util.Spliterator.OfLong spliteratorUnknownSize(java.util.PrimitiveIterator.OfLong, int); + method public static java.util.Spliterator.OfDouble spliteratorUnknownSize(java.util.PrimitiveIterator.OfDouble, int); + } + + public static abstract class Spliterators.AbstractDoubleSpliterator implements java.util.Spliterator.OfDouble { + ctor protected Spliterators.AbstractDoubleSpliterator(long, int); + method public int characteristics(); + method public long estimateSize(); + method public java.util.Spliterator.OfDouble trySplit(); + } + + public static abstract class Spliterators.AbstractIntSpliterator implements java.util.Spliterator.OfInt { + ctor protected Spliterators.AbstractIntSpliterator(long, int); + method public int characteristics(); + method public long estimateSize(); + method public java.util.Spliterator.OfInt trySplit(); + } + + public static abstract class Spliterators.AbstractLongSpliterator implements java.util.Spliterator.OfLong { + ctor protected Spliterators.AbstractLongSpliterator(long, int); + method public int characteristics(); + method public long estimateSize(); + method public java.util.Spliterator.OfLong trySplit(); + } + + public static abstract class Spliterators.AbstractSpliterator implements java.util.Spliterator { + ctor protected Spliterators.AbstractSpliterator(long, int); + method public int characteristics(); + method public long estimateSize(); + method public java.util.Spliterator<T> trySplit(); + } + public class Stack extends java.util.Vector { ctor public Stack(); method public boolean empty(); @@ -58483,6 +58887,15 @@ package java.util { method public synchronized int search(java.lang.Object); } + public final class StringJoiner { + ctor public StringJoiner(java.lang.CharSequence); + ctor public StringJoiner(java.lang.CharSequence, java.lang.CharSequence, java.lang.CharSequence); + method public java.util.StringJoiner add(java.lang.CharSequence); + method public int length(); + method public java.util.StringJoiner merge(java.util.StringJoiner); + method public java.util.StringJoiner setEmptyValue(java.lang.CharSequence); + } + public class StringTokenizer implements java.util.Enumeration { ctor public StringTokenizer(java.lang.String, java.lang.String, boolean); ctor public StringTokenizer(java.lang.String, java.lang.String); @@ -58604,6 +59017,7 @@ package java.util { method public E pollFirst(); method public E pollLast(); method public int size(); + method public java.util.Spliterator<E> spliterator(); method public java.util.NavigableSet<E> subSet(E, boolean, E, boolean); method public java.util.SortedSet<E> subSet(E, E); method public java.util.NavigableSet<E> tailSet(E, boolean); @@ -58660,6 +59074,7 @@ package java.util { method public synchronized void setElementAt(E, int); method public synchronized void setSize(int); method public synchronized int size(); + method public java.util.Spliterator<E> spliterator(); method public synchronized void trimToSize(); field protected int capacityIncrement; field protected int elementCount; diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp index c469ae4a0961..7bf073b4b1a1 100644 --- a/cmds/screencap/screencap.cpp +++ b/cmds/screencap/screencap.cpp @@ -67,30 +67,6 @@ static SkColorType flinger2skia(PixelFormat f) } } -static status_t vinfoToPixelFormat(const fb_var_screeninfo& vinfo, - uint32_t* bytespp, uint32_t* f) -{ - - switch (vinfo.bits_per_pixel) { - case 16: - *f = PIXEL_FORMAT_RGB_565; - *bytespp = 2; - break; - case 24: - *f = PIXEL_FORMAT_RGB_888; - *bytespp = 3; - break; - case 32: - // TODO: do better decoding of vinfo here - *f = PIXEL_FORMAT_RGBX_8888; - *bytespp = 4; - break; - default: - return BAD_VALUE; - } - return NO_ERROR; -} - static status_t notifyMediaScanner(const char* fileName) { String8 cmd("am broadcast -a android.intent.action.MEDIA_SCANNER_SCAN_FILE -d file://"); String8 fileUrl("\""); @@ -147,7 +123,7 @@ int main(int argc, char** argv) png = true; } } - + if (fd == -1) { usage(pname); return 1; @@ -195,28 +171,6 @@ int main(int argc, char** argv) s = screenshot.getStride(); f = screenshot.getFormat(); size = screenshot.getSize(); - } else { - const char* fbpath = "/dev/graphics/fb0"; - int fb = open(fbpath, O_RDONLY); - if (fb >= 0) { - struct fb_var_screeninfo vinfo; - if (ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) == 0) { - uint32_t bytespp; - if (vinfoToPixelFormat(vinfo, &bytespp, &f) == NO_ERROR) { - size_t offset = (vinfo.xoffset + vinfo.yoffset*vinfo.xres) * bytespp; - w = vinfo.xres; - h = vinfo.yres; - s = vinfo.xres; - size = w*h*bytespp; - mapsize = offset + size; - mapbase = mmap(0, mapsize, PROT_READ, MAP_PRIVATE, fb, 0); - if (mapbase != MAP_FAILED) { - base = (void const *)((char const *)mapbase + offset); - } - } - } - close(fb); - } } if (base != NULL) { 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/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java index 6fbb430ec8be..8b62ef9d568f 100644 --- a/core/java/android/app/ActivityManagerNative.java +++ b/core/java/android/app/ActivityManagerNative.java @@ -838,6 +838,12 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM resizePinnedStack(bounds, tempPinnedTaskBounds); return true; } + case SWAP_DOCKED_AND_FULLSCREEN_STACK: { + data.enforceInterface(IActivityManager.descriptor); + swapDockedAndFullscreenStack(); + reply.writeNoException(); + return true; + } case RESIZE_DOCKED_STACK_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); final boolean hasBounds = data.readInt() != 0; @@ -3895,6 +3901,17 @@ class ActivityManagerProxy implements IActivityManager reply.recycle(); } @Override + public void swapDockedAndFullscreenStack() throws RemoteException + { + Parcel data = Parcel.obtain(); + Parcel reply = Parcel.obtain(); + data.writeInterfaceToken(IActivityManager.descriptor); + mRemote.transact(SWAP_DOCKED_AND_FULLSCREEN_STACK, data, reply, 0); + reply.readException(); + data.recycle(); + reply.recycle(); + } + @Override public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds, Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index a452d2047088..060ac5e578e4 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1793,24 +1793,9 @@ public final class ActivityThread { * Resources if one has already been created. */ Resources getTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs, - String[] libDirs, int displayId, Configuration overrideConfiguration, - LoadedApk pkgInfo) { - return mResourcesManager.getTopLevelResources(resDir, splitResDirs, overlayDirs, libDirs, - displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo(), - pkgInfo.getClassLoader()); - } - - /** - * Creates a new top level resources for the given package. Will always create a new - * Resources, regardless if one has already been created. - */ - Resources getNewTopLevelResources(String resDir, String[] splitResDirs, String[] overlayDirs, - String[] libDirs, int displayId, Configuration overrideConfiguration, - LoadedApk pkgInfo) { - mResourcesManager.removeTopLevelResources( - resDir, displayId, overrideConfiguration, pkgInfo.getCompatibilityInfo()); - return getTopLevelResources(resDir, splitResDirs, overlayDirs, libDirs, - displayId, overrideConfiguration, pkgInfo); + String[] libDirs, int displayId, LoadedApk pkgInfo) { + return mResourcesManager.getResources(null, resDir, splitResDirs, overlayDirs, libDirs, + displayId, null, pkgInfo.getCompatibilityInfo(), pkgInfo.getClassLoader()); } final Handler getHandler() { @@ -2624,7 +2609,7 @@ public final class ActivityThread { } ContextImpl appContext = ContextImpl.createActivityContext( - this, r.packageInfo, displayId, r.overrideConfig); + this, r.packageInfo, r.token, displayId, r.overrideConfig); appContext.setOuterContext(activity); Context baseContext = appContext; @@ -3481,14 +3466,9 @@ public final class ActivityThread { if (!r.activity.mFinished && willBeVisible && r.activity.mDecor != null && !r.hideForNow) { if (r.newConfig != null) { - r.tmpConfig.setTo(r.newConfig); - if (r.overrideConfig != null) { - r.tmpConfig.updateFrom(r.overrideConfig); - } + performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Resuming activity " - + r.activityInfo.name + " with newConfig " + r.tmpConfig); - performConfigurationChanged(r.activity, r.tmpConfig, REPORT_TO_ACTIVITY); - freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); + + r.activityInfo.name + " with newConfig " + r.activity.mCurrentConfig); r.newConfig = null; } if (localLOGV) Slog.v(TAG, "Resuming " + r + " with isForward=" @@ -3722,10 +3702,9 @@ public final class ActivityThread { } catch (RemoteException ex) { if (ex instanceof TransactionTooLargeException && activity.packageInfo.getTargetSdkVersion() < Build.VERSION_CODES.N) { - Log.e(TAG, "App tried sending too much data in instance state", ex); + Log.e(TAG, "App sent too much data in instance state, so it was ignored", ex); return; } - throw ex.rethrowFromSystemServer(); } } @@ -3834,14 +3813,10 @@ public final class ActivityThread { } } if (r.newConfig != null) { - r.tmpConfig.setTo(r.newConfig); - if (r.overrideConfig != null) { - r.tmpConfig.updateFrom(r.overrideConfig); - } + performConfigurationChangedForActivity(r, r.newConfig, REPORT_TO_ACTIVITY); if (DEBUG_CONFIGURATION) Slog.v(TAG, "Updating activity vis " - + r.activityInfo.name + " with new config " + r.tmpConfig); - performConfigurationChanged(r.activity, r.tmpConfig, REPORT_TO_ACTIVITY); - freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); + + r.activityInfo.name + " with new config " + + r.activity.mCurrentConfig); r.newConfig = null; } } else { @@ -4546,8 +4521,44 @@ public final class ActivityThread { return callbacks; } - private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config, - boolean reportToActivity) { + /** + * Updates the configuration for an Activity. The ActivityClientRecord's + * {@link ActivityClientRecord#overrideConfig} is used to compute the final Configuration for + * that Activity. {@link ActivityClientRecord#tmpConfig} is used as a temporary for delivering + * the updated Configuration. + * @param r ActivityClientRecord representing the Activity. + * @param newBaseConfig The new configuration to use. This may be augmented with + * {@link ActivityClientRecord#overrideConfig}. + * @param reportToActivity true if the change should be reported to the Activity's callback. + */ + private void performConfigurationChangedForActivity(ActivityClientRecord r, + Configuration newBaseConfig, + boolean reportToActivity) { + r.tmpConfig.setTo(newBaseConfig); + if (r.overrideConfig != null) { + r.tmpConfig.updateFrom(r.overrideConfig); + } + performConfigurationChanged(r.activity, r.token, r.tmpConfig, r.overrideConfig, + reportToActivity); + freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(r.tmpConfig)); + } + + /** + * Decides whether to update an Activity's configuration and whether to tell the + * Activity/Component about it. + * @param cb The component callback to notify of configuration change. + * @param activityToken The Activity binder token for which this configuration change happened. + * If the change is global, this is null. + * @param newConfig The new configuration. + * @param overrideConfig The override config that differentiates the Activity's configuration + * from the base global configuration. + * @param reportToActivity Notify the Activity of the change. + */ + private void performConfigurationChanged(ComponentCallbacks2 cb, + IBinder activityToken, + Configuration newConfig, + Configuration overrideConfig, + boolean reportToActivity) { // Only for Activity objects, check that they actually call up to their // superclass implementation. ComponentCallbacks2 is an interface, so // we check the runtime type and act accordingly. @@ -4564,7 +4575,7 @@ public final class ActivityThread { // If the new config is the same as the config this Activity // is already running with then don't bother calling // onConfigurationChanged - int diff = activity.mCurrentConfig.diff(config); + int diff = activity.mCurrentConfig.diff(newConfig); if (diff != 0) { // If this activity doesn't handle any of the config changes then don't bother // calling onConfigurationChanged as we're going to destroy it. @@ -4579,21 +4590,31 @@ public final class ActivityThread { } } - if (DEBUG_CONFIGURATION) Slog.v(TAG, "Config callback " + cb - + ": shouldChangeConfig=" + shouldChangeConfig); + if (DEBUG_CONFIGURATION) { + Slog.v(TAG, "Config callback " + cb + ": shouldChangeConfig=" + shouldChangeConfig); + } + if (shouldChangeConfig) { + if (activityToken != null) { + // We only update an Activity's configuration if this is not a global + // configuration change. This must also be done before the callback, + // or else we violate the contract that the new resources are available + // in {@link ComponentCallbacks2#onConfigurationChanged(Configuration)}. + mResourcesManager.updateResourcesForActivity(activityToken, overrideConfig); + } + if (reportToActivity) { - cb.onConfigurationChanged(config); + cb.onConfigurationChanged(newConfig); } if (activity != null) { if (reportToActivity && !activity.mCalled) { throw new SuperNotCalledException( "Activity " + activity.getLocalClassName() + - " did not call through to super.onConfigurationChanged()"); + " did not call through to super.onConfigurationChanged()"); } activity.mConfigChangeFlags = 0; - activity.mCurrentConfig = new Configuration(config); + activity.mCurrentConfig = new Configuration(newConfig); } } } @@ -4610,7 +4631,8 @@ public final class ActivityThread { mCompatConfiguration = new Configuration(); } mCompatConfiguration.setTo(mConfiguration); - if (mResourcesManager.applyCompatConfiguration(displayDensity, mCompatConfiguration)) { + if (mResourcesManager.applyCompatConfigurationLocked(displayDensity, + mCompatConfiguration)) { config = mCompatConfiguration; } return config; @@ -4662,7 +4684,8 @@ public final class ActivityThread { if (callbacks != null) { final int N = callbacks.size(); for (int i=0; i<N; i++) { - performConfigurationChanged(callbacks.get(i), config, REPORT_TO_ACTIVITY); + performConfigurationChanged(callbacks.get(i), null, config, null, + REPORT_TO_ACTIVITY); } } } @@ -4688,15 +4711,8 @@ public final class ActivityThread { if (DEBUG_CONFIGURATION) Slog.v(TAG, "Handle activity config changed: " + r.activityInfo.name + ", with callback=" + reportToActivity); - r.tmpConfig.setTo(mCompatConfiguration); - if (data.overrideConfig != null) { - r.overrideConfig = data.overrideConfig; - r.tmpConfig.updateFrom(data.overrideConfig); - } - performConfigurationChanged(r.activity, r.tmpConfig, reportToActivity); - - freeTextLayoutCachesIfNeeded(r.activity.mCurrentConfig.diff(mCompatConfiguration)); - + r.overrideConfig = data.overrideConfig; + performConfigurationChangedForActivity(r, mCompatConfiguration, reportToActivity); mSomeActivitiesChanged = true; } @@ -5033,21 +5049,25 @@ public final class ActivityThread { */ TimeZone.setDefault(null); - /* - * Initialize the default locales in this process for the reasons we set the time zone. - * - * We do this through ResourcesManager, since we need to do locale negotiation. - */ - mResourcesManager.setDefaultLocalesLocked(data.config.getLocales()); - - /* - * Update the system configuration since its preloaded and might not - * reflect configuration changes. The configuration object passed - * in AppBindData can be safely assumed to be up to date - */ - mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); - mCurDefaultDisplayDpi = data.config.densityDpi; - applyCompatConfiguration(mCurDefaultDisplayDpi); + synchronized (mResourcesManager) { + /* + * Initialize the default locales in this process for the reasons we set the time zone. + * + * We do this through ResourcesManager, since we need to do locale negotiation. + */ + mResourcesManager.setDefaultLocalesLocked(data.config.getLocales()); + + /* + * Update the system configuration since its preloaded and might not + * reflect configuration changes. The configuration object passed + * in AppBindData can be safely assumed to be up to date + */ + mResourcesManager.applyConfigurationToResourcesLocked(data.config, data.compatInfo); + mCurDefaultDisplayDpi = data.config.densityDpi; + + // This calls mResourcesManager so keep it within the synchronized block. + applyCompatConfiguration(mCurDefaultDisplayDpi); + } data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo); diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java index 455f8694f1a6..b08142add4d8 100644 --- a/core/java/android/app/AlarmManager.java +++ b/core/java/android/app/AlarmManager.java @@ -985,11 +985,16 @@ public class AlarmManager { /** * Gets information about the next alarm clock currently scheduled. * - * The alarm clocks considered are those scheduled by {@link #setAlarmClock} - * from any package of the calling user. + * The alarm clocks considered are those scheduled by any application + * using the {@link #setAlarmClock} method. + * + * @return An {@link AlarmClockInfo} object describing the next upcoming alarm + * clock event that will occur. If there are no alarm clock events currently + * scheduled, this method will return {@code null}. * * @see #setAlarmClock * @see AlarmClockInfo + * @see #ACTION_NEXT_ALARM_CLOCK_CHANGED */ public AlarmClockInfo getNextAlarmClock() { return getNextAlarmClock(UserHandle.myUserId()); @@ -998,11 +1003,16 @@ public class AlarmManager { /** * Gets information about the next alarm clock currently scheduled. * - * The alarm clocks considered are those scheduled by {@link #setAlarmClock} - * from any package of the given {@parm userId}. + * The alarm clocks considered are those scheduled by any application + * using the {@link #setAlarmClock} method within the given user. + * + * @return An {@link AlarmClockInfo} object describing the next upcoming alarm + * clock event that will occur within the given user. If there are no alarm clock + * events currently scheduled in that user, this method will return {@code null}. * * @see #setAlarmClock * @see AlarmClockInfo + * @see #ACTION_NEXT_ALARM_CLOCK_CHANGED * * @hide */ @@ -1015,7 +1025,7 @@ public class AlarmManager { } /** - * An immutable description of an alarm clock. + * An immutable description of a scheduled "alarm clock" event. * * @see AlarmManager#setAlarmClock * @see AlarmManager#getNextAlarmClock 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/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java index 0b44925bdd0c..ca050918d83a 100644 --- a/core/java/android/app/ApplicationPackageManager.java +++ b/core/java/android/app/ApplicationPackageManager.java @@ -1182,7 +1182,7 @@ public class ApplicationPackageManager extends PackageManager { sameUid ? app.sourceDir : app.publicSourceDir, sameUid ? app.splitSourceDirs : app.splitPublicSourceDirs, app.resourceDirs, app.sharedLibraryFiles, Display.DEFAULT_DISPLAY, - null, mContext.mPackageInfo); + mContext.mPackageInfo); if (r != null) { return r; } diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index e76f9910e751..32ace144ddd8 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -1994,9 +1994,10 @@ class ContextImpl extends Context { } static ContextImpl createActivityContext(ActivityThread mainThread, - LoadedApk packageInfo, int displayId, Configuration overrideConfiguration) { + LoadedApk packageInfo, IBinder activityToken, int displayId, + Configuration overrideConfiguration) { if (packageInfo == null) throw new IllegalArgumentException("packageInfo"); - return new ContextImpl(null, mainThread, packageInfo, null, null, 0, + return new ContextImpl(null, mainThread, packageInfo, activityToken, null, 0, null, overrideConfiguration, displayId); } @@ -2054,10 +2055,16 @@ class ContextImpl extends Context { || overrideConfiguration != null || (compatInfo != null && compatInfo.applicationScale != resources.getCompatibilityInfo().applicationScale)) { - resources = mResourcesManager.getTopLevelResources(packageInfo.getResDir(), - packageInfo.getSplitResDirs(), packageInfo.getOverlayDirs(), - packageInfo.getApplicationInfo().sharedLibraryFiles, displayId, - overrideConfiguration, compatInfo, packageInfo.getClassLoader()); + resources = mResourcesManager.getResources( + activityToken, + packageInfo.getResDir(), + packageInfo.getSplitResDirs(), + packageInfo.getOverlayDirs(), + packageInfo.getApplicationInfo().sharedLibraryFiles, + displayId, + overrideConfiguration, + compatInfo, + packageInfo.getClassLoader()); } } mResources = resources; diff --git a/core/java/android/app/DatePickerDialog.java b/core/java/android/app/DatePickerDialog.java index bbf1607ad529..83dc506371cf 100644 --- a/core/java/android/app/DatePickerDialog.java +++ b/core/java/android/app/DatePickerDialog.java @@ -125,9 +125,8 @@ public class DatePickerDialog extends AlertDialog implements OnClickListener, @Nullable OnDateSetListener listener, int year, int month, int dayOfMonth) { this(context, themeResId); - mDateSetListener = listener; - mDatePicker.updateDate(year, month, dayOfMonth); + mDateSetListener = listener; } static @StyleRes int resolveDialogTheme(@NonNull Context context, @StyleRes int themeResId) { diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java index eadf4978688c..cdbf598ebb9d 100644 --- a/core/java/android/app/IActivityManager.java +++ b/core/java/android/app/IActivityManager.java @@ -151,6 +151,12 @@ public interface IActivityManager extends IInterface { boolean preserveWindows, boolean animate) throws RemoteException; /** + * Moves all tasks from the docked stack in the fullscreen stack and puts the top task of the + * fullscreen stack into the docked stack. + */ + public void swapDockedAndFullscreenStack() throws RemoteException; + + /** * Resizes the docked stack, and all other stacks as the result of the dock stack bounds change. * * @param dockedBounds The bounds for the docked stack. @@ -998,4 +1004,5 @@ public interface IActivityManager extends IInterface { int GET_MEMORY_TRIM_LEVEL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+369; int RESIZE_PINNED_STACK_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 370; int IS_VR_PACKAGE_ENABLED_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 371; + int SWAP_DOCKED_AND_FULLSCREEN_STACK = IBinder.FIRST_CALL_TRANSACTION + 372; } diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl index 2c270fc8a95c..7a69c6234eb9 100644 --- a/core/java/android/app/INotificationManager.aidl +++ b/core/java/android/app/INotificationManager.aidl @@ -61,7 +61,7 @@ interface INotificationManager StatusBarNotification[] getActiveNotifications(String callingPkg); StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count); - void registerListener(in INotificationListener listener, in ComponentName component, int userid, boolean asRanker); + void registerListener(in INotificationListener listener, in ComponentName component, int userid); void unregisterListener(in INotificationListener listener, int userid); void cancelNotificationFromListener(in INotificationListener token, String pkg, String tag, int id); diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java index cd170780450d..b8fc32308961 100644 --- a/core/java/android/app/LoadedApk.java +++ b/core/java/android/app/LoadedApk.java @@ -283,9 +283,9 @@ public final class LoadedApk { synchronized (this) { mClassLoader = createOrUpdateClassLoaderLocked(addedPaths); if (mResources != null) { - mResources = mActivityThread.getNewTopLevelResources(mResDir, mSplitResDirs, + mResources = mActivityThread.getTopLevelResources(mResDir, mSplitResDirs, mOverlayDirs, mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, - null /*overrideConfiguration*/, this); + this); } } } @@ -668,7 +668,7 @@ public final class LoadedApk { public Resources getResources(ActivityThread mainThread) { if (mResources == null) { mResources = mainThread.getTopLevelResources(mResDir, mSplitResDirs, mOverlayDirs, - mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, null, this); + mApplicationInfo.sharedLibraryFiles, Display.DEFAULT_DISPLAY, this); } return mResources; } 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/Notification.java b/core/java/android/app/Notification.java index a2cc6b17c376..88c89648f52e 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -4222,7 +4222,8 @@ public class Notification implements Parcelable int i=0; final float density = mBuilder.mContext.getResources().getDisplayMetrics().density; int topPadding = (int) (5 * density); - int bottomPadding = (int) (13 * density); + int bottomPadding = mBuilder.mContext.getResources().getDimensionPixelSize( + com.android.internal.R.dimen.notification_content_margin_bottom); boolean first = true; while (i < mTexts.size() && i < rowIds.length) { CharSequence str = mTexts.get(i); diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java index 7cfa0cd36102..10aa7ebc136a 100644 --- a/core/java/android/app/NotificationManager.java +++ b/core/java/android/app/NotificationManager.java @@ -145,7 +145,6 @@ public class NotificationManager public static final String ACTION_INTERRUPTION_FILTER_CHANGED_INTERNAL = "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL"; - /** @hide */ @IntDef({INTERRUPTION_FILTER_NONE, INTERRUPTION_FILTER_PRIORITY, INTERRUPTION_FILTER_ALARMS, INTERRUPTION_FILTER_ALL, INTERRUPTION_FILTER_UNKNOWN}) diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java index bc44553d25ec..54d813dee6d7 100644 --- a/core/java/android/app/ResourcesManager.java +++ b/core/java/android/app/ResourcesManager.java @@ -18,6 +18,8 @@ package android.app; import static android.app.ActivityThread.DEBUG_CONFIGURATION; +import android.annotation.NonNull; +import android.annotation.Nullable; import android.content.pm.ActivityInfo; import android.content.res.AssetManager; import android.content.res.CompatibilityInfo; @@ -26,6 +28,7 @@ import android.content.res.Resources; import android.content.res.ResourcesImpl; import android.content.res.ResourcesKey; import android.hardware.display.DisplayManagerGlobal; +import android.os.IBinder; import android.util.ArrayMap; import android.util.DisplayMetrics; import android.util.LocaleList; @@ -34,11 +37,16 @@ import android.util.Pair; import android.util.Slog; import android.view.Display; import android.view.DisplayAdjustments; +import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.util.ArrayUtils; import java.lang.ref.WeakReference; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; -import java.util.List; +import java.util.Objects; +import java.util.WeakHashMap; +import java.util.function.Predicate; /** @hide */ public class ResourcesManager { @@ -46,18 +54,56 @@ public class ResourcesManager { private static final boolean DEBUG = false; private static ResourcesManager sResourcesManager; - private final ArrayMap<ResourcesKey, WeakReference<Resources>> mActiveResources = - new ArrayMap<>(); - private final ArrayMap<Pair<Integer, DisplayAdjustments>, WeakReference<Display>> mDisplays = - new ArrayMap<>(); + + /** + * Predicate that returns true if a WeakReference is gc'ed. + */ + private static final Predicate<WeakReference<Resources>> sEmptyReferencePredicate = + new Predicate<WeakReference<Resources>>() { + @Override + public boolean test(WeakReference<Resources> weakRef) { + return weakRef == null || weakRef.get() == null; + } + }; private String[] mSystemLocales = {}; - private final HashSet<String> mNonSystemLocales = new HashSet<String>(); + private final HashSet<String> mNonSystemLocales = new HashSet<>(); private boolean mHasNonSystemLocales = false; - CompatibilityInfo mResCompatibilityInfo; + /** + * The global compatibility settings. + */ + private CompatibilityInfo mResCompatibilityInfo; + + /** + * The global configuration upon which all Resources are based. Multi-window Resources + * apply their overrides to this configuration. + */ + private final Configuration mResConfiguration = new Configuration(); - Configuration mResConfiguration; + /** + * A mapping of ResourceImpls and their configurations. These are heavy weight objects + * which should be reused as much as possible. + */ + private final ArrayMap<ResourcesKey, WeakReference<ResourcesImpl>> mResourceImpls = + new ArrayMap<>(); + + /** + * A list of Resource references that can be reused. + */ + private final ArrayList<WeakReference<Resources>> mResourceReferences = new ArrayList<>(); + + /** + * Each Activity may have only one Resources object. + */ + private final WeakHashMap<IBinder, WeakReference<Resources>> mActivityResourceReferences = + new WeakHashMap<>(); + + /** + * A cache of DisplayId to DisplayAdjustments. + */ + private final ArrayMap<Pair<Integer, DisplayAdjustments>, WeakReference<Display>> mDisplays = + new ArrayMap<>(); public static ResourcesManager getInstance() { synchronized (ResourcesManager.class) { @@ -76,7 +122,11 @@ public class ResourcesManager { return getDisplayMetricsLocked(Display.DEFAULT_DISPLAY); } - DisplayMetrics getDisplayMetricsLocked(int displayId) { + /** + * Protected so that tests can override and returns something a fixed value. + */ + @VisibleForTesting + protected DisplayMetrics getDisplayMetricsLocked(int displayId) { DisplayMetrics dm = new DisplayMetrics(); final Display display = getAdjustedDisplay(displayId, DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS); @@ -88,12 +138,12 @@ public class ResourcesManager { return dm; } - final void applyNonDefaultDisplayMetricsToConfigurationLocked( - DisplayMetrics dm, Configuration config) { + private static void applyNonDefaultDisplayMetricsToConfiguration( + @NonNull DisplayMetrics dm, @NonNull Configuration config) { config.touchscreen = Configuration.TOUCHSCREEN_NOTOUCH; config.densityDpi = dm.densityDpi; - config.screenWidthDp = (int)(dm.widthPixels / dm.density); - config.screenHeightDp = (int)(dm.heightPixels / dm.density); + config.screenWidthDp = (int) (dm.widthPixels / dm.density); + config.screenHeightDp = (int) (dm.heightPixels / dm.density); int sl = Configuration.resetScreenLayout(config.screenLayout); if (dm.widthPixels > dm.heightPixels) { config.orientation = Configuration.ORIENTATION_LANDSCAPE; @@ -110,8 +160,8 @@ public class ResourcesManager { config.compatSmallestScreenWidthDp = config.smallestScreenWidthDp; } - public boolean applyCompatConfiguration(int displayDensity, - Configuration compatConfiguration) { + public boolean applyCompatConfigurationLocked(int displayDensity, + @NonNull Configuration compatConfiguration) { if (mResCompatibilityInfo != null && !mResCompatibilityInfo.supportsScreen()) { mResCompatibilityInfo.applyToConfiguration(displayDensity, compatConfiguration); return true; @@ -126,7 +176,8 @@ public class ResourcesManager { * @param displayId display Id. * @param displayAdjustments display adjustments. */ - public Display getAdjustedDisplay(final int displayId, DisplayAdjustments displayAdjustments) { + public Display getAdjustedDisplay(final int displayId, + @Nullable DisplayAdjustments displayAdjustments) { final DisplayAdjustments displayAdjustmentsCopy = (displayAdjustments != null) ? new DisplayAdjustments(displayAdjustments) : new DisplayAdjustments(); final Pair<Integer, DisplayAdjustments> key = @@ -153,76 +204,42 @@ public class ResourcesManager { } /** - * Creates the top level Resources for applications with the given compatibility info. + * Creates an AssetManager from the paths within the ResourcesKey. * - * @param resDir the resource directory. - * @param splitResDirs split resource directories. - * @param overlayDirs the resource overlay directories. - * @param libDirs the shared library resource dirs this app references. - * @param displayId display Id. - * @param overrideConfiguration override configurations. - * @param compatInfo the compatibility info. Must not be null. - * @param classLoader the class loader for the resource package - */ - Resources getTopLevelResources(String resDir, String[] splitResDirs, - String[] overlayDirs, String[] libDirs, int displayId, - Configuration overrideConfiguration, CompatibilityInfo compatInfo, - ClassLoader classLoader) { - final float scale = compatInfo.applicationScale; - Configuration overrideConfigCopy = (overrideConfiguration != null) - ? new Configuration(overrideConfiguration) : null; - ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfigCopy, scale); - Resources r; - final boolean findSystemLocales; - final boolean hasNonSystemLocales; - synchronized (this) { - // Resources is app scale dependent. - if (DEBUG) Slog.w(TAG, "getTopLevelResources: " + resDir + " / " + scale); - - WeakReference<Resources> wr = mActiveResources.get(key); - r = wr != null ? wr.get() : null; - //if (r != null) Log.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate()); - if (r != null && r.getAssets().isUpToDate()) { - if (DEBUG) Slog.w(TAG, "Returning cached resources " + r + " " + resDir - + ": appScale=" + r.getCompatibilityInfo().applicationScale - + " key=" + key + " overrideConfig=" + overrideConfiguration); - return r; - } - findSystemLocales = (mSystemLocales.length == 0); - hasNonSystemLocales = mHasNonSystemLocales; - } - - //if (r != null) { - // Log.w(TAG, "Throwing away out-of-date resources!!!! " - // + r + " " + resDir); - //} - + * This can be overridden in tests so as to avoid creating a real AssetManager with + * real APK paths. + * @param key The key containing the resource paths to add to the AssetManager. + * @return a new AssetManager. + */ + @VisibleForTesting + protected AssetManager createAssetManager(@NonNull final ResourcesKey key) { AssetManager assets = new AssetManager(); + // resDir can be null if the 'android' package is creating a new Resources object. // This is fine, since each AssetManager automatically loads the 'android' package // already. - if (resDir != null) { - if (assets.addAssetPath(resDir) == 0) { + if (key.mResDir != null) { + if (assets.addAssetPath(key.mResDir) == 0) { return null; } } - if (splitResDirs != null) { - for (String splitResDir : splitResDirs) { + if (key.mSplitResDirs != null) { + for (final String splitResDir : key.mSplitResDirs) { if (assets.addAssetPath(splitResDir) == 0) { return null; } } } - if (overlayDirs != null) { - for (String idmapPath : overlayDirs) { + if (key.mOverlayDirs != null) { + for (final String idmapPath : key.mOverlayDirs) { assets.addOverlayPath(idmapPath); } } - if (libDirs != null) { - for (String libDir : libDirs) { + if (key.mLibDirs != null) { + for (final String libDir : key.mLibDirs) { if (libDir.endsWith(".apk")) { // Avoid opening files we know do not have resources, // like code-only .jar files. @@ -233,16 +250,17 @@ public class ResourcesManager { } } } + return assets; + } - //Log.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics); - DisplayMetrics dm = getDisplayMetricsLocked(displayId); + private Configuration generateConfig(@NonNull ResourcesKey key, @NonNull DisplayMetrics dm) { Configuration config; - final boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY); + final boolean isDefaultDisplay = (key.mDisplayId == Display.DEFAULT_DISPLAY); final boolean hasOverrideConfig = key.hasOverrideConfiguration(); if (!isDefaultDisplay || hasOverrideConfig) { config = new Configuration(getConfiguration()); if (!isDefaultDisplay) { - applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config); + applyNonDefaultDisplayMetricsToConfiguration(dm, config); } if (hasOverrideConfig) { config.updateFrom(key.mOverrideConfiguration); @@ -251,16 +269,212 @@ public class ResourcesManager { } else { config = getConfiguration(); } - r = new Resources(classLoader); - r.setImpl(new ResourcesImpl(assets, dm, config, compatInfo)); - if (DEBUG) Slog.i(TAG, "Created app resources " + resDir + " " + r + ": " - + r.getConfiguration() + " appScale=" + r.getCompatibilityInfo().applicationScale); - - final String[] systemLocales = ( - findSystemLocales ? - AssetManager.getSystem().getLocales() : - null); - final String[] nonSystemLocales = assets.getNonSystemLocales(); + return config; + } + + + private ResourcesImpl createResourcesImpl(@NonNull ResourcesKey key) { + AssetManager assets = createAssetManager(key); + DisplayMetrics dm = getDisplayMetricsLocked(key.mDisplayId); + Configuration config = generateConfig(key, dm); + ResourcesImpl impl = new ResourcesImpl(assets, dm, config, key.mCompatInfo); + if (DEBUG) { + Slog.d(TAG, "- creating impl=" + impl + " with key: " + key); + } + return impl; + } + + /** + * Finds a cached ResourcesImpl object that matches the given ResourcesKey. + * + * @param key The key to match. + * @return a ResourcesImpl if the key matches a cache entry, null otherwise. + */ + private ResourcesImpl findResourcesImplForKey(@NonNull ResourcesKey key) { + WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.get(key); + ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null; + if (impl != null && impl.getAssets().isUpToDate()) { + return impl; + } + return null; + } + + /** + * Find the ResourcesKey that this ResourcesImpl object is associated with. + * @return the ResourcesKey or null if none was found. + */ + private ResourcesKey findKeyForResourceImpl(@NonNull ResourcesImpl resourceImpl) { + final int refCount = mResourceImpls.size(); + for (int i = 0; i < refCount; i++) { + WeakReference<ResourcesImpl> weakImplRef = mResourceImpls.valueAt(i); + ResourcesImpl impl = weakImplRef != null ? weakImplRef.get() : null; + if (impl != null && resourceImpl == impl) { + return mResourceImpls.keyAt(i); + } + } + return null; + } + + /** + * Gets an existing Resources object tied to this Activity, or creates one if it doesn't exist + * or the class loader is different. + */ + private Resources getOrCreateResourcesForActivityLocked(@NonNull IBinder activityToken, + @NonNull ClassLoader classLoader, @NonNull ResourcesImpl impl) { + // This is a request tied to an Activity, meaning we will need to update all + // Activity related Resources to match this configuration. + WeakReference<Resources> weakResourceRef = mActivityResourceReferences.get(activityToken); + Resources resources = weakResourceRef != null ? weakResourceRef.get() : null; + if (resources == null || !Objects.equals(resources.getClassLoader(), classLoader)) { + resources = new Resources(classLoader); + mActivityResourceReferences.put(activityToken, new WeakReference<>(resources)); + if (DEBUG) { + Slog.d(TAG, "- creating new ref=" + resources); + } + } else { + if (DEBUG) { + Slog.d(TAG, "- using existing ref=" + resources); + } + } + + if (resources.getImpl() != impl) { + if (DEBUG) { + Slog.d(TAG, "- setting ref=" + resources + " with impl=" + impl); + } + + // Setting an impl is expensive because we update all ThemeImpl references. + // too. + resources.setImpl(impl); + } + return resources; + } + + /** + * Gets an existing Resources object if the class loader and ResourcesImpl are the same, + * otherwise creates a new Resources object. + */ + private Resources getOrCreateResourcesLocked(@NonNull ClassLoader classLoader, + @NonNull ResourcesImpl impl) { + // Find an existing Resources that has this ResourcesImpl set. + final int refCount = mResourceReferences.size(); + for (int i = 0; i < refCount; i++) { + WeakReference<Resources> weakResourceRef = mResourceReferences.get(i); + Resources resources = weakResourceRef != null ? weakResourceRef.get() : null; + if (resources != null && + Objects.equals(resources.getClassLoader(), classLoader) && + resources.getImpl() == impl) { + if (DEBUG) { + Slog.d(TAG, "- using existing ref=" + resources); + } + return resources; + } + } + + // Create a new Resources reference and use the existing ResourcesImpl object. + Resources resources = new Resources(classLoader); + resources.setImpl(impl); + mResourceReferences.add(new WeakReference<>(resources)); + if (DEBUG) { + Slog.d(TAG, "- creating new ref=" + resources); + Slog.d(TAG, "- setting ref=" + resources + " with impl=" + impl); + } + return resources; + } + + /** + * Gets or creates a new Resources object associated with the IBinder token. References returned + * by this method live as long as the Activity, meaning they can be cached and used by the + * Activity even after a configuration change. If any other parameter is changed + * (resDir, splitResDirs, overrideConfig) for a given Activity, the same Resources object + * is updated and handed back to the caller. However, changing the class loader will result in a + * new Resources object. + * <p/> + * If activityToken is null, a cached Resources object will be returned if it matches the + * input parameters. Otherwise a new Resources object that satisfies these parameters is + * returned. + * + * @param activityToken Represents an Activity. If null, global resources are assumed. + * @param resDir The base resource path. Can be null (only framework resources will be loaded). + * @param splitResDirs An array of split resource paths. Can be null. + * @param overlayDirs An array of overlay paths. Can be null. + * @param libDirs An array of resource library paths. Can be null. + * @param displayId The ID of the display for which to create the resources. + * @param overrideConfig The configuration to apply on top of the base configuration. Can be + * null. Mostly used with Activities that are in multi-window which may override width and + * height properties from the base config. + * @param compatInfo The compatibility settings to use. Cannot be null. A default to use is + * {@link CompatibilityInfo#DEFAULT_COMPATIBILITY_INFO}. + * @param classLoader The class loader to use when inflating Resources. If null, the + * {@link ClassLoader#getSystemClassLoader()} is used. + * @return a Resources object from which to access resources. + */ + public Resources getResources(@Nullable IBinder activityToken, + @Nullable String resDir, + @Nullable String[] splitResDirs, + @Nullable String[] overlayDirs, + @Nullable String[] libDirs, + int displayId, + @Nullable Configuration overrideConfig, + @NonNull CompatibilityInfo compatInfo, + @Nullable ClassLoader classLoader) { + final ResourcesKey key = new ResourcesKey( + resDir, + splitResDirs, + overlayDirs, + libDirs, + displayId, + overrideConfig != null ? new Configuration(overrideConfig) : null, // Copy + compatInfo); + + classLoader = classLoader != null ? classLoader : ClassLoader.getSystemClassLoader(); + + final boolean findSystemLocales; + final boolean hasNonSystemLocales; + synchronized (this) { + findSystemLocales = (mSystemLocales.length == 0); + hasNonSystemLocales = mHasNonSystemLocales; + + if (DEBUG) { + Throwable here = new Throwable(); + here.fillInStackTrace(); + Slog.w(TAG, "!! Get resources for activity=" + activityToken + " key=" + key, here); + } + + if (activityToken != null) { + ResourcesImpl resourcesImpl = findResourcesImplForKey(key); + if (resourcesImpl != null) { + if (DEBUG) { + Slog.d(TAG, "- using existing impl=" + resourcesImpl); + } + return getOrCreateResourcesForActivityLocked(activityToken, classLoader, + resourcesImpl); + } + + // We will create the ResourcesImpl object outside of holding this lock. + + } else { + // Clean up any dead references so they don't pile up. + ArrayUtils.unstableRemoveIf(mResourceReferences, sEmptyReferencePredicate); + + // Not tied to an Activity, find a shared Resources that has the right ResourcesImpl + ResourcesImpl resourcesImpl = findResourcesImplForKey(key); + if (resourcesImpl != null) { + if (DEBUG) { + Slog.d(TAG, "- using existing impl=" + resourcesImpl); + } + return getOrCreateResourcesLocked(classLoader, resourcesImpl); + } + + // We will create the ResourcesImpl object outside of holding this lock. + } + } + + // If we're here, we didn't find a suitable ResourcesImpl to use, so create one now. + ResourcesImpl resourcesImpl = createResourcesImpl(key); + + final String[] systemLocales = findSystemLocales + ? AssetManager.getSystem().getLocales() : null; + final String[] nonSystemLocales = resourcesImpl.getAssets().getNonSystemLocales(); // Avoid checking for non-pseudo-locales if we already know there were some from a previous // Resources. The default value (for when hasNonSystemLocales is true) doesn't matter, // since mHasNonSystemLocales will also be true, and thus isPseudoLocalesOnly would not be @@ -269,41 +483,75 @@ public class ResourcesManager { LocaleList.isPseudoLocalesOnly(nonSystemLocales); synchronized (this) { - WeakReference<Resources> wr = mActiveResources.get(key); - Resources existing = wr != null ? wr.get() : null; - if (existing != null && existing.getAssets().isUpToDate()) { - // Someone else already created the resources while we were - // unlocked; go ahead and use theirs. - r.getAssets().close(); - return existing; - } - - // XXX need to remove entries when weak references go away - mActiveResources.put(key, new WeakReference<>(r)); if (mSystemLocales.length == 0) { mSystemLocales = systemLocales; } mNonSystemLocales.addAll(Arrays.asList(nonSystemLocales)); mHasNonSystemLocales = mHasNonSystemLocales || !isPseudoLocalesOnly; - if (DEBUG) Slog.v(TAG, "mActiveResources.size()=" + mActiveResources.size()); - return r; + + ResourcesImpl existingResourcesImpl = findResourcesImplForKey(key); + if (existingResourcesImpl != null) { + if (DEBUG) { + Slog.d(TAG, "- got beat! existing impl=" + existingResourcesImpl + + " new impl=" + resourcesImpl); + } + resourcesImpl.getAssets().close(); + resourcesImpl = existingResourcesImpl; + } else { + // Add this ResourcesImpl to the cache. + mResourceImpls.put(key, new WeakReference<>(resourcesImpl)); + } + + final Resources resources; + if (activityToken != null) { + resources = getOrCreateResourcesForActivityLocked(activityToken, classLoader, + resourcesImpl); + } else { + resources = getOrCreateResourcesLocked(classLoader, resourcesImpl); + } + return resources; } } /** - * Removes the top level Resources for applications with the given compatibility info. - * @see #getTopLevelResources(String, String[], String[], String[], int, Configuration, CompatibilityInfo, ClassLoader) + * Updates an Activity's Resources object with overrideConfig. The Resources object + * that was previously returned by + * {@link #getResources(IBinder, String, String[], String[], String[], int, Configuration, + * CompatibilityInfo, ClassLoader)} is + * still valid and will have the updated configuration. + * @param activityToken The Activity token. + * @param overrideConfig The configuration override to update. */ - void removeTopLevelResources(String resDir, int displayId, Configuration overrideConfiguration, - CompatibilityInfo compatInfo) { - final float scale = compatInfo.applicationScale; - final Configuration overrideConfigCopy = (overrideConfiguration != null) - ? new Configuration(overrideConfiguration) : null; - final ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfigCopy, scale); - mActiveResources.remove(key); + public void updateResourcesForActivity(@NonNull IBinder activityToken, + @Nullable Configuration overrideConfig) { + final ClassLoader classLoader; + final ResourcesKey oldKey; + synchronized (this) { + // Extract the ResourcesKey that was last used to create the Resources for this + // activity. + WeakReference<Resources> weakResRef = mActivityResourceReferences.get(activityToken); + final Resources resources = weakResRef != null ? weakResRef.get() : null; + if (resources == null) { + Slog.e(TAG, "can't update resources for uncached activity " + activityToken); + return; + } + + classLoader = resources.getClassLoader(); + oldKey = findKeyForResourceImpl(resources.getImpl()); + if (oldKey == null) { + Slog.e(TAG, "can't find ResourcesKey for resources impl=" + resources.getImpl()); + return; + } + } + + // Update the Resources object with the new override config and all of the existing + // settings. + getResources(activityToken, oldKey.mResDir, oldKey.mSplitResDirs, oldKey.mOverlayDirs, + oldKey.mLibDirs, oldKey.mDisplayId, overrideConfig, oldKey.mCompatInfo, + classLoader); } - /* package */ void setDefaultLocalesLocked(LocaleList locales) { + /* package */ void setDefaultLocalesLocked(@NonNull LocaleList locales) { final int bestLocale; if (mHasNonSystemLocales) { bestLocale = locales.getFirstMatchIndexWithEnglishSupported(mNonSystemLocales); @@ -317,11 +565,8 @@ public class ResourcesManager { LocaleList.setDefault(locales, bestLocale); } - final boolean applyConfigurationToResourcesLocked(Configuration config, - CompatibilityInfo compat) { - if (mResConfiguration == null) { - mResConfiguration = new Configuration(); - } + public final boolean applyConfigurationToResourcesLocked(@NonNull Configuration config, + @Nullable CompatibilityInfo compat) { if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) { if (DEBUG || DEBUG_CONFIGURATION) Slog.v(TAG, "Skipping new config: curSeq=" + mResConfiguration.seq + ", newSeq=" + config.seq); @@ -368,9 +613,9 @@ public class ResourcesManager { Configuration tmpConfig = null; - for (int i = mActiveResources.size() - 1; i >= 0; i--) { - ResourcesKey key = mActiveResources.keyAt(i); - Resources r = mActiveResources.valueAt(i).get(); + for (int i = mResourceImpls.size() - 1; i >= 0; i--) { + ResourcesKey key = mResourceImpls.keyAt(i); + ResourcesImpl r = mResourceImpls.valueAt(i).get(); if (r != null) { if (DEBUG || DEBUG_CONFIGURATION) Slog.v(TAG, "Changing resources " + r + " config to: " + localeAdjustedConfig); @@ -385,7 +630,7 @@ public class ResourcesManager { tmpConfig.setTo(localeAdjustedConfig); if (!isDefaultDisplay) { dm = getDisplayMetricsLocked(displayId); - applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig); + applyNonDefaultDisplayMetricsToConfiguration(dm, tmpConfig); } if (hasOverrideConfiguration) { tmpConfig.updateFrom(key.mOverrideConfiguration); @@ -398,11 +643,10 @@ public class ResourcesManager { // + " " + r + ": " + r.getConfiguration()); } else { //Slog.i(TAG, "Removing old resources " + v.getKey()); - mActiveResources.removeAt(i); + mResourceImpls.removeAt(i); } } return changes != 0; } - -} +}
\ No newline at end of file diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java index 3a5dd30bfda7..6c0b69c8afdb 100644 --- a/core/java/android/app/SystemServiceRegistry.java +++ b/core/java/android/app/SystemServiceRegistry.java @@ -103,6 +103,7 @@ import android.os.SystemVibrator; import android.os.UserHandle; import android.os.UserManager; import android.os.Vibrator; +import android.os.health.SystemHealthManager; import android.os.storage.StorageManager; import android.print.IPrintManager; import android.print.PrintManager; @@ -273,9 +274,9 @@ final class SystemServiceRegistry { }}); registerService(Context.DROPBOX_SERVICE, DropBoxManager.class, - new StaticServiceFetcher<DropBoxManager>() { + new CachedServiceFetcher<DropBoxManager>() { @Override - public DropBoxManager createService() { + public DropBoxManager createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(Context.DROPBOX_SERVICE); IDropBoxManagerService service = IDropBoxManagerService.Stub.asInterface(b); if (service == null) { @@ -285,7 +286,7 @@ final class SystemServiceRegistry { // DROPBOX_SERVICE is registered. return null; } - return new DropBoxManager(service); + return new DropBoxManager(ctx, service); }}); registerService(Context.INPUT_SERVICE, InputManager.class, @@ -747,18 +748,23 @@ final class SystemServiceRegistry { @Override public SoundTriggerManager createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(Context.SOUND_TRIGGER_SERVICE); - Log.i(TAG, "Creating new instance of SoundTriggerManager object."); return new SoundTriggerManager(ctx, ISoundTriggerService.Stub.asInterface(b)); }}); registerService(Context.SHORTCUT_SERVICE, ShortcutManager.class, new CachedServiceFetcher<ShortcutManager>() { - @Override - public ShortcutManager createService(ContextImpl ctx) { - IBinder b = ServiceManager.getService(Context.SHORTCUT_SERVICE); - return new ShortcutManager(ctx, - IShortcutService.Stub.asInterface(b)); - }}); + @Override + public ShortcutManager createService(ContextImpl ctx) { + IBinder b = ServiceManager.getService(Context.SHORTCUT_SERVICE); + return new ShortcutManager(ctx, IShortcutService.Stub.asInterface(b)); + }}); + + registerService(Context.SYSTEM_HEALTH_SERVICE, SystemHealthManager.class, + new CachedServiceFetcher<SystemHealthManager>() { + @Override + public SystemHealthManager createService(ContextImpl ctx) { + return new SystemHealthManager(); + }}); } /** diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java index 6bc03f7da77b..2d06dcca35f6 100644 --- a/core/java/android/app/WallpaperManager.java +++ b/core/java/android/app/WallpaperManager.java @@ -49,7 +49,6 @@ import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; -import android.os.UserHandle; import android.text.TextUtils; import android.util.Log; import android.view.WindowManagerGlobal; @@ -263,7 +262,8 @@ public class WallpaperManager { static class Globals extends IWallpaperManagerCallback.Stub { private IWallpaperManager mService; - private Bitmap mWallpaper; + private Bitmap mCachedWallpaper; + private int mCachedWallpaperUserId; private Bitmap mDefaultWallpaper; Globals(Looper looper) { @@ -296,33 +296,34 @@ public class WallpaperManager { throw e.rethrowFromSystemServer(); } } - if (mWallpaper != null) { - return mWallpaper; + if (mCachedWallpaper != null && mCachedWallpaperUserId == userId) { + return mCachedWallpaper; } - if (mDefaultWallpaper != null) { - return mDefaultWallpaper; - } - mWallpaper = null; + mCachedWallpaper = null; + mCachedWallpaperUserId = 0; try { - mWallpaper = getCurrentWallpaperLocked(userId); + mCachedWallpaper = getCurrentWallpaperLocked(userId); + mCachedWallpaperUserId = userId; } catch (OutOfMemoryError e) { Log.w(TAG, "No memory load current wallpaper", e); } + if (mCachedWallpaper != null) { + return mCachedWallpaper; + } if (returnDefault) { - if (mWallpaper == null) { + if (mDefaultWallpaper == null) { mDefaultWallpaper = getDefaultWallpaperLocked(context); - return mDefaultWallpaper; - } else { - mDefaultWallpaper = null; } + return mDefaultWallpaper; } - return mWallpaper; + return null; } } public void forgetLoadedWallpaper() { synchronized (this) { - mWallpaper = null; + mCachedWallpaper = null; + mCachedWallpaperUserId = 0; mDefaultWallpaper = null; } } diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index 8bd40dc66491..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(); } @@ -2774,18 +2780,19 @@ public class DevicePolicyManager { * certificate and corresponding private key. All apps within the profile will be able to access * the certificate and use the private key, given direct user approval. * - * <p>The caller of this API may grant itself access to the credential immediately, without user - * approval. It is a best practice not to request this unless strictly necessary since it opens - * up additional security vulnerabilities. + * <p>The caller of this API may grant itself access to the certificate and private key + * immediately, without user approval. It is a best practice not to request this unless strictly + * necessary since it opens up additional security vulnerabilities. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or - * {@code null} if calling from a delegated certificate installer. + * {@code null} if calling from a delegated certificate installer. * @param privKey The private key to install. * @param cert The certificate to install. * @param alias The private key alias under which to install the certificate. If a certificate - * with that alias already exists, it will be overwritten. + * with that alias already exists, it will be overwritten. * @param requestAccess {@code true} to request that the calling app be granted access to the - * credentials immediately. Otherwise, access to the credentials will be gated by user approval. + * credentials immediately. Otherwise, access to the credentials will be gated by user + * approval. * @return {@code true} if the keys were installed, {@code false} otherwise. */ public boolean installKeyPair(@Nullable ComponentName admin, @NonNull PrivateKey privKey, @@ -2806,13 +2813,13 @@ public class DevicePolicyManager { } /** - * Called by a device or profile owner, or delegated certificate installer, to remove all user - * credentials installed under a given alias. + * Called by a device or profile owner, or delegated certificate installer, to remove a + * certificate and private key pair installed under a given alias. * * @param admin Which {@link DeviceAdminReceiver} this request is associated with, or - * {@code null} if calling from a delegated certificate installer. + * {@code null} if calling from a delegated certificate installer. * @param alias The private key alias under which the certificate is installed. - * @return {@code true} if the certificate alias no longer exists, {@code false} otherwise. + * @return {@code true} if the private key alias no longer exists, {@code false} otherwise. */ public boolean removeKeyPair(@Nullable ComponentName admin, @NonNull String alias) { try { @@ -3722,7 +3729,9 @@ public class DevicePolicyManager { * be hidden, it will not show up in recents, will not be able to show toasts or dialogs * or ring the device. * - * <p>The package must already be installed. + * <p>The package must already be installed. If the package is uninstalled while suspended + * the package will no longer be suspended. The admin can block this by using + * {@link #setUninstallBlocked}. * * @param admin The name of the admin component to check. * @param packageNames The package names to suspend or unsuspend. diff --git a/core/java/android/app/admin/DevicePolicyManagerInternal.java b/core/java/android/app/admin/DevicePolicyManagerInternal.java index 8cdfee5572a8..61b40d437514 100644 --- a/core/java/android/app/admin/DevicePolicyManagerInternal.java +++ b/core/java/android/app/admin/DevicePolicyManagerInternal.java @@ -16,6 +16,8 @@ package android.app.admin; +import android.os.UserHandle; + import java.util.List; /** @@ -71,8 +73,8 @@ public abstract class DevicePolicyManagerInternal { public abstract boolean isActiveAdminWithPolicy(int uid, int reqPolicy); /** - * Checks if a given package has a device or a profile owner for the given user - * + * Checks if a given package has a device or a profile owner for the given user. + * </br><em>Does <b>not</b> support negative userIds like {@link UserHandle#USER_ALL}</em> * @param packageName The package to check * @param userId the userId to check for. * @return true if package has a device or profile owner, false otherwise. 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/Context.java b/core/java/android/content/Context.java index f96ddf0d183a..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 @@ -3585,6 +3585,15 @@ public abstract class Context { public static final String SHORTCUT_SERVICE = "shortcut"; /** + * Use with {@link #getSystemService} to retrieve a + * {@link android.os.health.SystemHealthManager} for accessing system health (battery, power, + * memory, etc) metrics. + * + * @see #getSystemService + */ + public static final String SYSTEM_HEALTH_SERVICE = "systemhealth"; + + /** * Determine whether the given permission is allowed for a particular * process and user ID running in the system. * 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/ILauncherApps.aidl b/core/java/android/content/pm/ILauncherApps.aidl index cf3e298fd6d7..b1d3f207f82f 100644 --- a/core/java/android/content/pm/ILauncherApps.aidl +++ b/core/java/android/content/pm/ILauncherApps.aidl @@ -26,6 +26,8 @@ import android.content.pm.ShortcutInfo; import android.graphics.Rect; import android.os.Bundle; import android.os.UserHandle; +import android.os.ParcelFileDescriptor; + import java.util.List; /** @@ -52,4 +54,8 @@ interface ILauncherApps { in UserHandle user); boolean startShortcut(String callingPackage, String packageName, String id, in Rect sourceBounds, in Bundle startActivityOptions, in UserHandle user); + + int getShortcutIconResId(String callingPackage, in ShortcutInfo shortcut, in UserHandle user); + ParcelFileDescriptor getShortcutIconFd(String callingPackage, in ShortcutInfo shortcut, + in UserHandle user); } diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl index aee3ba77f1f0..2a3fac341e24 100644 --- a/core/java/android/content/pm/IPackageInstallerSession.aidl +++ b/core/java/android/content/pm/IPackageInstallerSession.aidl @@ -29,6 +29,8 @@ interface IPackageInstallerSession { ParcelFileDescriptor openWrite(String name, long offsetBytes, long lengthBytes); ParcelFileDescriptor openRead(String name); + void removeSplit(String splitName); + void close(); void commit(in IntentSender statusReceiver); void abandon(); diff --git a/core/java/android/content/pm/IShortcutService.aidl b/core/java/android/content/pm/IShortcutService.aidl index 23e671d82f12..8f9dcfc15d63 100644 --- a/core/java/android/content/pm/IShortcutService.aidl +++ b/core/java/android/content/pm/IShortcutService.aidl @@ -44,5 +44,7 @@ interface IShortcutService { long getRateLimitResetTime(String packageName, int userId); + int getIconMaxDimensions(String packageName, int userId); + void resetThrottling(); // system only API for developer opsions }
\ No newline at end of file diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java index 8e4a0e20097e..a6a732ea9513 100644 --- a/core/java/android/content/pm/LauncherApps.java +++ b/core/java/android/content/pm/LauncherApps.java @@ -183,7 +183,8 @@ public class LauncherApps { public static final int FLAG_GET_PINNED = 1 << 1; /** - * Requests "key" fields only. + * Requests "key" fields only. See {@link ShortcutInfo#hasKeyFieldsOnly()} for which + * fields are available. */ public static final int FLAG_GET_KEY_FIELDS_ONLY = 1 << 2; @@ -473,7 +474,11 @@ public class LauncherApps { */ @RequiresPermission(permission.BIND_APPWIDGET) public int getShortcutIconResId(@NonNull ShortcutInfo shortcut, @NonNull UserHandle user) { - throw new RuntimeException("not implemented yet"); + try { + return mService.getShortcutIconResId(mContext.getPackageName(), shortcut, user); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** @@ -488,7 +493,11 @@ public class LauncherApps { @RequiresPermission(permission.BIND_APPWIDGET) public ParcelFileDescriptor getShortcutIconFd( @NonNull ShortcutInfo shortcut, @NonNull UserHandle user) { - throw new RuntimeException("not implemented yet"); + try { + return mService.getShortcutIconFd(mContext.getPackageName(), shortcut, user); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java index 700a40db1f5f..0f5ec919710e 100644 --- a/core/java/android/content/pm/PackageInstaller.java +++ b/core/java/android/content/pm/PackageInstaller.java @@ -795,6 +795,27 @@ public class PackageInstaller { } /** + * Removes a split. + * <p> + * Split removals occur prior to adding new APKs. If upgrading a feature + * split, it is not expected nor desirable to remove the split prior to + * upgrading. + * <p> + * When split removal is bundled with new APKs, the packageName must be + * identical. + */ + public void removeSplit(@NonNull String splitName) throws IOException { + try { + mSession.removeSplit(splitName); + } catch (RuntimeException e) { + ExceptionUtils.maybeUnwrapIOException(e); + throw e; + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + + /** * Attempt to commit everything staged in this session. This may require * user intervention, and so it may not happen immediately. The final * result of the commit will be reported through the given callback. @@ -979,8 +1000,8 @@ public class PackageInstaller { } /** - * Optionally set the URI where this package was downloaded from. Used for - * verification purposes. + * Optionally set the URI where this package was downloaded from. This is + * informational and may be used as a signal for anti-malware purposes. * * @see Intent#EXTRA_ORIGINATING_URI */ @@ -989,7 +1010,8 @@ public class PackageInstaller { } /** - * Sets the UID that initiated package installation. Used for verification purposes. + * Sets the UID that initiated package installation. This is informational + * and may be used as a signal for anti-malware purposes. * * @see PackageManager#EXTRA_VERIFICATION_INSTALLER_UID */ @@ -998,8 +1020,8 @@ public class PackageInstaller { } /** - * Optionally set the URI that referred you to install this package. Used - * for verification purposes. + * Optionally set the URI that referred you to install this package. This is + * informational and may be used as a signal for anti-malware purposes. * * @see Intent#EXTRA_REFERRER */ @@ -1031,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/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 0dc856c5da4f..e1e8a07310ac 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -1596,9 +1596,9 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and - * {@link #hasSystemFeature}: If this feature is supported, the Vulkan native API will enumerate - * at least one {@code VkPhysicalDevice}, and the feature version will indicate what - * level of optional hardware features limits it supports. + * {@link #hasSystemFeature(String, int)}: If this feature is supported, the Vulkan native API + * will enumerate at least one {@code VkPhysicalDevice}, and the feature version will indicate + * what level of optional hardware features limits it supports. * <p> * Level 0 includes the base Vulkan requirements as well as: * <ul><li>{@code VkPhysicalDeviceFeatures::textureCompressionETC2}</li></ul> @@ -1623,7 +1623,7 @@ public abstract class PackageManager { /** * Feature for {@link #getSystemAvailableFeatures} and - * {@link #hasSystemFeature}: The version of this feature indicates the highest + * {@link #hasSystemFeature(String, int)}: The version of this feature indicates the highest * {@code VkPhysicalDeviceProperties::apiVersion} supported by the physical devices that support * the hardware level indicated by {@link #FEATURE_VULKAN_HARDWARE_LEVEL}. The feature version * uses the same encoding as Vulkan version numbers: @@ -5367,6 +5367,9 @@ public abstract class PackageManager { * will be hidden, the application will not show up in recents, will not be able to show * toasts or dialogs or ring the device. * + * <p>The package must already be installed. If the package is uninstalled while suspended + * the package will no longer be suspended. + * * @param packageNames The names of the packages to set the suspended status. * @param suspended If set to {@code true} than the packages will be suspended, if set to * {@code false} the packages will be unsuspended. 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 65205636c98e..e41136c0038a 100644 --- a/core/java/android/content/pm/ShortcutInfo.java +++ b/core/java/android/content/pm/ShortcutInfo.java @@ -19,9 +19,11 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.ComponentName; +import android.content.ContentResolver; import android.content.Context; import android.content.Intent; import android.graphics.drawable.Icon; +import android.os.Bundle; import android.os.Parcel; import android.os.Parcelable; import android.os.PersistableBundle; @@ -60,6 +62,9 @@ public class ShortcutInfo implements Parcelable { /* @hide */ public static final int FLAG_HAS_ICON_FILE = 1 << 3; + /* @hide */ + public static final int FLAG_KEY_FIELDS_ONLY = 1 << 4; + /** @hide */ @IntDef(flag = true, value = { @@ -67,6 +72,7 @@ public class ShortcutInfo implements Parcelable { FLAG_PINNED, FLAG_HAS_ICON_RES, FLAG_HAS_ICON_FILE, + FLAG_KEY_FIELDS_ONLY, }) @Retention(RetentionPolicy.SOURCE) public @interface ShortcutFlags {} @@ -114,10 +120,15 @@ public class ShortcutInfo implements Parcelable { @NonNull private String mTitle; + /** + * Intent *with extras removed*. + */ @NonNull private Intent mIntent; - // Internal use only. + /** + * Extras for the intent. + */ @NonNull private PersistableBundle mIntentPersistableExtras; @@ -149,6 +160,13 @@ public class ShortcutInfo implements Parcelable { mIcon = b.mIcon; mTitle = b.mTitle; mIntent = b.mIntent; + 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; updateTimestamp(); @@ -170,13 +188,15 @@ public class ShortcutInfo implements Parcelable { private ShortcutInfo(ShortcutInfo source, @CloneFlags int cloneFlags) { mId = source.mId; mPackageName = source.mPackageName; - mActivityComponent = source.mActivityComponent; mFlags = source.mFlags; mLastChangedTimestamp = source.mLastChangedTimestamp; if ((cloneFlags & CLONE_REMOVE_NON_KEY_INFO) == 0) { + mActivityComponent = source.mActivityComponent; + if ((cloneFlags & CLONE_REMOVE_ICON) == 0) { mIcon = source.mIcon; + mBitmapPath = source.mBitmapPath; } mTitle = source.mTitle; @@ -187,7 +207,9 @@ 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; } } @@ -210,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; @@ -239,6 +261,39 @@ public class ShortcutInfo implements Parcelable { } /** + * @hide + */ + public static Icon validateIcon(Icon icon) { + switch (icon.getType()) { + case Icon.TYPE_RESOURCE: + case Icon.TYPE_BITMAP: + break; // OK + case Icon.TYPE_URI: + if (ContentResolver.SCHEME_CONTENT.equals(icon.getUri().getScheme())) { + break; + } + // Note "file:" is not supported, because depending on the path, system server + // cannot access it. // TODO Revisit "file:" icon support + + // fall through + default: + throw getInvalidIconException(); + } + if (icon.hasTint()) { + // TODO support it + throw new IllegalArgumentException("Icons with tints are not supported"); + } + + return icon; + } + + /** @hide */ + public static IllegalArgumentException getInvalidIconException() { + return new IllegalArgumentException("Unsupported icon type:" + +" only bitmap, resource and content URI are supported"); + } + + /** * Builder class for {@link ShortcutInfo} objects. */ public static class Builder { @@ -273,7 +328,9 @@ public class ShortcutInfo implements Parcelable { } /** - * Optionally sets the target activity. + * Optionally sets the target activity. If it's not set, and if the caller application + * has multiple launcher icons, this shortcut will be shown on all those icons. + * If it's set, this shortcut will be only shown on this activity. */ @NonNull public Builder setActivityComponent(@NonNull ComponentName activityComponent) { @@ -284,15 +341,22 @@ public class ShortcutInfo implements Parcelable { /** * Optionally sets an icon. * - * - Tint is not supported TODO Either check and throw, or support it. - * - URI icons will be converted into Bitmap icons at the registration time. + * <ul> + * <li>Tints are not supported. + * <li>Bitmaps, resources and "content:" URIs are supported. + * <li>"content:" URI will be fetched when a shortcut is registered to + * {@link ShortcutManager}. Changing the content from the same URI later will + * not be reflected to launcher icons. + * </ul> * - * TODO Only allow Bitmap, Resource and URI types. byte[] type can easily go over - * binder size limit. + * <p>For performance reasons, icons will <b>NOT</b> be available on instances + * returned by {@link ShortcutManager} or {@link LauncherApps}. Launcher applications + * need to use {@link LauncherApps#getShortcutIconFd(ShortcutInfo, UserHandle)} + * and {@link LauncherApps#getShortcutIconResId(ShortcutInfo, UserHandle)}. */ @NonNull public Builder setIcon(Icon icon) { - mIcon = icon; + mIcon = validateIcon(icon); return this; } @@ -316,7 +380,7 @@ public class ShortcutInfo implements Parcelable { } /** - * Optionally sets the weight of a shortcut, which will be used by Launcher for sorting. + * Optionally sets the weight of a shortcut, which will be used by the launcher for sorting. * The larger the weight, the more "important" a shortcut is. */ @NonNull @@ -326,8 +390,8 @@ public class ShortcutInfo implements Parcelable { } /** - * Optional values that application can set. - * TODO: reserve keys starting with "android." + * Optional values that applications can set. Applications can store any meta-data of + * shortcuts in this, and retrieve later from {@link ShortcutInfo#getExtras()}. */ @NonNull public Builder setExtras(@NonNull PersistableBundle extras) { @@ -353,7 +417,7 @@ public class ShortcutInfo implements Parcelable { } /** - * Return the ID of the shortcut. + * Return the package name of the creator application. */ @NonNull public String getPackageName() { @@ -374,7 +438,7 @@ public class ShortcutInfo implements Parcelable { * * For performance reasons, this will <b>NOT</b> be available when an instance is returned * by {@link ShortcutManager} or {@link LauncherApps}. A launcher application needs to use - * other APIs in LauncherApps to fetch the bitmap. TODO Add a precondition for it. + * other APIs in LauncherApps to fetch the bitmap. * * @hide */ @@ -385,22 +449,46 @@ public class ShortcutInfo implements Parcelable { /** * Return the shortcut title. + * + * <p>All shortcuts must have a non-empty title, but this method will return null when + * {@link #hasKeyFieldsOnly()} is true. */ - @NonNull + @Nullable public String getTitle() { return mTitle; } /** * Return the intent. - * TODO Set mIntentPersistableExtras and before returning. + * + * <p>All shortcuts must have an intent, but this method will return null when + * {@link #hasKeyFieldsOnly()} is true. */ - @NonNull + @Nullable public Intent getIntent() { + if (mIntent == null) { + return null; + } + final Intent intent = new Intent(mIntent); + intent.replaceExtras( + mIntentPersistableExtras != null ? new Bundle(mIntentPersistableExtras) : null); + return intent; + } + + /** + * Return "raw" intent, which is the original intent without the extras. + * @hide + */ + @Nullable + public Intent getIntentNoExtras() { return mIntent; } - /** @hide */ + /** + * The extras in the intent. We convert extras into {@link PersistableBundle} so we can + * persist them. + * @hide + */ @Nullable public PersistableBundle getIntentPersistableExtras() { return mIntentPersistableExtras; @@ -483,6 +571,23 @@ public class ShortcutInfo implements Parcelable { return hasFlags(FLAG_HAS_ICON_FILE); } + /** + * Return whether a shortcut only contains "key" information only or not. If true, only the + * following fields are available. + * <ul> + * <li>{@link #getId()} + * <li>{@link #getPackageName()} + * <li>{@link #getLastChangedTimestamp()} + * <li>{@link #isDynamic()} + * <li>{@link #isPinned()} + * <li>{@link #hasIconResource()} + * <li>{@link #hasIconFile()} + * </ul> + */ + public boolean hasKeyFieldsOnly() { + return hasFlags(FLAG_KEY_FIELDS_ONLY); + } + /** @hide */ public void updateTimestamp() { mLastChangedTimestamp = System.currentTimeMillis(); @@ -495,33 +600,13 @@ public class ShortcutInfo implements Parcelable { } /** @hide */ - public void setIcon(Icon icon) { - mIcon = icon; - } - - /** @hide */ - public void setTitle(String title) { - mTitle = title; - } - - /** @hide */ - public void setIntent(Intent intent) { - mIntent = intent; - } - - /** @hide */ - public void setIntentPersistableExtras(PersistableBundle intentPersistableExtras) { - mIntentPersistableExtras = intentPersistableExtras; - } - - /** @hide */ - public void setWeight(int weight) { - mWeight = weight; + public void clearIcon() { + mIcon = null; } /** @hide */ - public void setExtras(PersistableBundle extras) { - mExtras = extras; + public void setIconResourceId(int iconResourceId) { + mIconResourceId = iconResourceId; } /** @hide */ @@ -643,9 +728,10 @@ public class ShortcutInfo implements Parcelable { sb.append(", extras="); sb.append(mExtras); + sb.append(", flags="); + sb.append(mFlags); + if (includeInternalData) { - sb.append(", flags="); - sb.append(mFlags); sb.append(", iconRes="); sb.append(mIconResourceId); diff --git a/core/java/android/content/pm/ShortcutManager.java b/core/java/android/content/pm/ShortcutManager.java index 4c51d499ab4a..b247f65c94c3 100644 --- a/core/java/android/content/pm/ShortcutManager.java +++ b/core/java/android/content/pm/ShortcutManager.java @@ -239,6 +239,17 @@ public class ShortcutManager { } } + /** + * Return the max width and height for icons, in pixels. + */ + public int getIconMaxDimensions() { + try { + return mService.getIconMaxDimensions(mContext.getPackageName(), injectMyUserId()); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } + } + /** @hide injection point */ @VisibleForTesting protected int injectMyUserId() { diff --git a/core/java/android/content/pm/ShortcutServiceInternal.java b/core/java/android/content/pm/ShortcutServiceInternal.java index 3d6028a6ffe5..918c763545fa 100644 --- a/core/java/android/content/pm/ShortcutServiceInternal.java +++ b/core/java/android/content/pm/ShortcutServiceInternal.java @@ -22,6 +22,8 @@ import android.annotation.UserIdInt; import android.content.ComponentName; import android.content.Intent; import android.content.pm.LauncherApps.ShortcutQuery; +import android.os.ParcelFileDescriptor; +import android.os.UserHandle; import java.util.List; @@ -55,4 +57,10 @@ public abstract class ShortcutServiceInternal { @NonNull String packageName, @NonNull String shortcutId, int userId); public abstract void addListener(@NonNull ShortcutChangeListener listener); + + public abstract int getShortcutIconResId(@NonNull String callingPackage, + @NonNull ShortcutInfo shortcut, int userId); + + public abstract ParcelFileDescriptor getShortcutIconFd(@NonNull String callingPackage, + @NonNull ShortcutInfo shortcut, int userId); } 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/Resources.java b/core/java/android/content/res/Resources.java index f337fe6fe4b1..fb706fcb3c94 100644 --- a/core/java/android/content/res/Resources.java +++ b/core/java/android/content/res/Resources.java @@ -54,6 +54,7 @@ import android.util.TypedValue; import android.view.ViewDebug; import android.view.ViewHierarchyEncoder; +import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.GrowingArrayUtils; import com.android.internal.util.XmlUtils; @@ -62,6 +63,8 @@ import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; import java.io.InputStream; +import java.lang.ref.WeakReference; +import java.util.ArrayList; /** * Class for accessing an application's resources. This sits on top of the @@ -113,6 +116,13 @@ public class Resources { final ClassLoader mClassLoader; /** + * WeakReferences to Themes that were constructed from this Resources object. + * We keep track of these in case our underlying implementation is changed, in which case + * the Themes must also get updated ThemeImpls. + */ + private final ArrayList<WeakReference<Theme>> mThemeRefs = new ArrayList<>(); + + /** * Returns the most appropriate default theme for the specified target SDK version. * <ul> * <li>Below API 11: Gingerbread @@ -231,10 +241,42 @@ public class Resources { } /** + * Set the underlying implementation (containing all the resources and caches) + * and updates all Theme references to new implementations as well. * @hide */ public void setImpl(ResourcesImpl impl) { + if (impl == mResourcesImpl) { + return; + } + mResourcesImpl = impl; + + // Create new ThemeImpls that are identical to the ones we have. + synchronized (mThemeRefs) { + final int count = mThemeRefs.size(); + for (int i = 0; i < count; i++) { + WeakReference<Theme> weakThemeRef = mThemeRefs.get(i); + Theme theme = weakThemeRef != null ? weakThemeRef.get() : null; + if (theme != null) { + theme.setImpl(mResourcesImpl.newThemeImpl(theme.getKey())); + } + } + } + } + + /** + * @hide + */ + public ResourcesImpl getImpl() { + return mResourcesImpl; + } + + /** + * @hide + */ + public ClassLoader getClassLoader() { + return mClassLoader; } /** @@ -1683,6 +1725,7 @@ public class Resources { public final Theme newTheme() { Theme theme = new Theme(); theme.setImpl(mResourcesImpl.newThemeImpl()); + mThemeRefs.add(new WeakReference<>(theme)); return theme; } @@ -1785,6 +1828,7 @@ public class Resources { * This is just for testing. * @hide */ + @VisibleForTesting public void setCompatibilityInfo(CompatibilityInfo ci) { if (ci != null) { mResourcesImpl.updateConfiguration(null, null, ci); @@ -2069,6 +2113,15 @@ public class Resources { } /** + * Called by ConfigurationBoundResourceCacheTest. + * @hide + */ + @VisibleForTesting + public int calcConfigChanges(Configuration config) { + return mResourcesImpl.calcConfigChanges(config); + } + + /** * Obtains styled attributes from the theme, if available, or unstyled * resources if the theme is null. * diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index 2ffd3722b5a3..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,14 +44,19 @@ 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; import java.util.Locale; /** + * The implementation of Resource access. This class contains the AssetManager and all caches + * associated with it. + * + * {@link Resources} is just a thing wrapper around this class. When a configuration change + * occurs, clients can retain the same {@link Resources} reference because the underlying + * {@link ResourcesImpl} object will be updated or re-created. + * * @hide */ public class ResourcesImpl { @@ -58,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; @@ -126,14 +135,14 @@ public class ResourcesImpl { * @param compatInfo this resource's compatibility info. Must not be null. */ public ResourcesImpl(AssetManager assets, DisplayMetrics metrics, Configuration config, - CompatibilityInfo compatInfo) { + CompatibilityInfo compatInfo) { mAssets = assets; mMetrics.setToDefaults(); updateConfiguration(config, metrics, compatInfo); mAssets.ensureStringBlocks(); } - AssetManager getAssets() { + public AssetManager getAssets() { return mAssets; } @@ -174,7 +183,7 @@ public class ResourcesImpl { } void getValueForDensity(@AnyRes int id, int density, TypedValue outValue, - boolean resolveRefs) throws NotFoundException { + boolean resolveRefs) throws NotFoundException { boolean found = mAssets.getResourceValue(id, density, outValue, resolveRefs); if (found) { return; @@ -298,8 +307,8 @@ public class ResourcesImpl { return mStateListAnimatorCache; } - void updateConfiguration(Configuration config, DisplayMetrics metrics, - CompatibilityInfo compat) { + public void updateConfiguration(Configuration config, DisplayMetrics metrics, + CompatibilityInfo compat) { synchronized (mAccessLock) { if (false) { Slog.i(TAG, "**** Updating config of " + this + ": old config is " @@ -324,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()) { @@ -388,26 +397,30 @@ public class ResourcesImpl { } /** - * Called by ConfigurationBoundResourceCacheTest via reflection. + * 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 */ - private int calcConfigChanges(Configuration config) { - int configChanges = 0xfffffff; - if (config != null) { - mTmpConfig.setTo(config); - int density = config.densityDpi; - if (density == Configuration.DENSITY_DPI_UNDEFINED) { - density = mMetrics.noncompatDensityDpi; - } + public @Config int calcConfigChanges(@Nullable Configuration config) { + if (config == null) { + // If there is no configuration, assume all flags have changed. + return 0xFFFFFFFF; + } + + mTmpConfig.setTo(config); + int density = config.densityDpi; + if (density == Configuration.DENSITY_DPI_UNDEFINED) { + density = mMetrics.noncompatDensityDpi; + } - mCompatibilityInfo.applyToConfiguration(density, mTmpConfig); + mCompatibilityInfo.applyToConfiguration(density, mTmpConfig); - if (mTmpConfig.getLocales().isEmpty()) { - mTmpConfig.setLocales(LocaleList.getDefault()); - } - configChanges = mConfiguration.updateFrom(mTmpConfig); - configChanges = ActivityInfo.activityInfoConfigToNative(configChanges); + if (mTmpConfig.getLocales().isEmpty()) { + mTmpConfig.setLocales(LocaleList.getDefault()); } - return configChanges; + return mConfiguration.updateFrom(mTmpConfig); } /** @@ -460,7 +473,7 @@ public class ResourcesImpl { @Nullable Drawable loadDrawable(Resources wrapper, TypedValue value, int id, Resources.Theme theme, - boolean useCache) throws NotFoundException { + boolean useCache) throws NotFoundException { try { if (TRACE_FOR_PRELOAD) { // Log only framework resources @@ -553,7 +566,7 @@ public class ResourcesImpl { } private void cacheDrawable(TypedValue value, boolean isColorDrawable, DrawableCache caches, - Resources.Theme theme, boolean usesTheme, long key, Drawable dr) { + Resources.Theme theme, boolean usesTheme, long key, Drawable dr) { final Drawable.ConstantState cs = dr.getConstantState(); if (cs == null) { return; @@ -586,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 @@ -625,7 +638,7 @@ public class ResourcesImpl { * Loads a drawable from XML or resources stream. */ private Drawable loadDrawableForCookie(Resources wrapper, TypedValue value, int id, - Resources.Theme theme) { + Resources.Theme theme) { if (value.string == null) { throw new NotFoundException("Resource \"" + getResourceName(id) + "\" (" + Integer.toHexString(id) + ") is not a Drawable (color or path): " + value); @@ -681,7 +694,7 @@ public class ResourcesImpl { * Last, parse the XML and generate the CSL. */ private ComplexColor loadComplexColorFromName(Resources wrapper, Resources.Theme theme, - TypedValue value, int id) { + TypedValue value, int id) { final long key = (((long) value.assetCookie) << 32) | value.data; final ConfigurationBoundResourceCache<ComplexColor> cache = mComplexColorCache; ComplexColor complexColor = cache.getInstance(key, wrapper, theme); @@ -714,7 +727,7 @@ public class ResourcesImpl { @Nullable ComplexColor loadComplexColor(Resources wrapper, @NonNull TypedValue value, int id, - Resources.Theme theme) { + Resources.Theme theme) { if (TRACE_FOR_PRELOAD) { // Log only framework resources if ((id >>> 24) == 0x1) { @@ -755,7 +768,7 @@ public class ResourcesImpl { @Nullable ColorStateList loadColorStateList(Resources wrapper, TypedValue value, int id, - Resources.Theme theme) + Resources.Theme theme) throws NotFoundException { if (TRACE_FOR_PRELOAD) { // Log only framework resources @@ -815,7 +828,7 @@ public class ResourcesImpl { */ @Nullable private ComplexColor loadComplexColorForCookie(Resources wrapper, TypedValue value, int id, - Resources.Theme theme) { + Resources.Theme theme) { if (value.string == null) { throw new UnsupportedOperationException( "Can't convert to ComplexColor: type=0x" + value.type); @@ -893,8 +906,8 @@ public class ResourcesImpl { * @throws NotFoundException if the file could not be loaded */ @NonNull - XmlResourceParser loadXmlResourceParser(@NonNull String file, @AnyRes int id, - int assetCookie, @NonNull String type) + XmlResourceParser loadXmlResourceParser(@NonNull String file, @AnyRes int id, int assetCookie, + @NonNull String type) throws NotFoundException { if (id != 0) { try { @@ -975,6 +988,16 @@ public class ResourcesImpl { return new ThemeImpl(); } + /** + * Creates a new ThemeImpl which is already set to the given Resources.ThemeKey. + */ + ThemeImpl newThemeImpl(Resources.ThemeKey key) { + ThemeImpl impl = new ThemeImpl(); + impl.mKey.setTo(key); + impl.rebase(); + return impl; + } + public class ThemeImpl { /** * Unique key for the series of styles applied to this theme. @@ -1035,10 +1058,10 @@ public class ResourcesImpl { @NonNull TypedArray obtainStyledAttributes(@NonNull Resources.Theme wrapper, - AttributeSet set, - @StyleableRes int[] attrs, - @AttrRes int defStyleAttr, - @StyleRes int defStyleRes) { + AttributeSet set, + @StyleableRes int[] attrs, + @AttrRes int defStyleAttr, + @StyleRes int defStyleRes) { synchronized (mKey) { final int len = attrs.length; final TypedArray array = TypedArray.obtain(wrapper.getResources(), len); @@ -1060,8 +1083,8 @@ public class ResourcesImpl { @NonNull TypedArray resolveAttributes(@NonNull Resources.Theme wrapper, - @NonNull int[] values, - @NonNull int[] attrs) { + @NonNull int[] values, + @NonNull int[] attrs) { synchronized (mKey) { final int len = attrs.length; if (values == null || len != values.length) { @@ -1087,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/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java index 26205718c44d..e89449283c5e 100644 --- a/core/java/android/content/res/ResourcesKey.java +++ b/core/java/android/content/res/ResourcesKey.java @@ -17,32 +17,59 @@ package android.content.res; import android.annotation.NonNull; +import android.annotation.Nullable; +import android.text.TextUtils; +import java.util.Arrays; import java.util.Objects; /** @hide */ public final class ResourcesKey { - private final String mResDir; - private final float mScale; - private final int mHash; + @Nullable + public final String mResDir; + + @Nullable + public final String[] mSplitResDirs; + + @Nullable + public final String[] mOverlayDirs; + + @Nullable + public final String[] mLibDirs; public final int mDisplayId; + @NonNull public final Configuration mOverrideConfiguration; - public ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, - float scale) { + @NonNull + public final CompatibilityInfo mCompatInfo; + + private final int mHash; + + public ResourcesKey(@Nullable String resDir, + @Nullable String[] splitResDirs, + @Nullable String[] overlayDirs, + @Nullable String[] libDirs, + int displayId, + @Nullable Configuration overrideConfig, + @Nullable CompatibilityInfo compatInfo) { mResDir = resDir; + mSplitResDirs = splitResDirs; + mOverlayDirs = overlayDirs; + mLibDirs = libDirs; mDisplayId = displayId; - mOverrideConfiguration = overrideConfiguration != null - ? overrideConfiguration : Configuration.EMPTY; - mScale = scale; + mOverrideConfiguration = overrideConfig != null ? overrideConfig : Configuration.EMPTY; + mCompatInfo = compatInfo != null ? compatInfo : CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO; int hash = 17; - hash = 31 * hash + (mResDir == null ? 0 : mResDir.hashCode()); + hash = 31 * hash + Objects.hashCode(mResDir); + hash = 31 * hash + Arrays.hashCode(mSplitResDirs); + hash = 31 * hash + Arrays.hashCode(mOverlayDirs); + hash = 31 * hash + Arrays.hashCode(mLibDirs); hash = 31 * hash + mDisplayId; - hash = 31 * hash + mOverrideConfiguration.hashCode(); - hash = 31 * hash + Float.floatToIntBits(mScale); + hash = 31 * hash + Objects.hashCode(mOverrideConfiguration); + hash = 31 * hash + Objects.hashCode(mCompatInfo); mHash = hash; } @@ -60,18 +87,32 @@ public final class ResourcesKey { if (!(obj instanceof ResourcesKey)) { return false; } + ResourcesKey peer = (ResourcesKey) obj; + if (mHash != peer.mHash) { + // If the hashes don't match, the objects can't match. + return false; + } if (!Objects.equals(mResDir, peer.mResDir)) { return false; } + if (!Arrays.equals(mSplitResDirs, peer.mSplitResDirs)) { + return false; + } + if (!Arrays.equals(mOverlayDirs, peer.mOverlayDirs)) { + return false; + } + if (!Arrays.equals(mLibDirs, peer.mLibDirs)) { + return false; + } if (mDisplayId != peer.mDisplayId) { return false; } - if (!mOverrideConfiguration.equals(peer.mOverrideConfiguration)) { + if (!Objects.equals(mOverrideConfiguration, peer.mOverrideConfiguration)) { return false; } - if (mScale != peer.mScale) { + if (!Objects.equals(mCompatInfo, peer.mCompatInfo)) { return false; } return true; @@ -79,6 +120,29 @@ public final class ResourcesKey { @Override public String toString() { - return Integer.toHexString(mHash); + StringBuilder builder = new StringBuilder().append("ResourcesKey{"); + builder.append(" mHash=").append(Integer.toHexString(mHash)); + builder.append(" mResDir=").append(mResDir); + builder.append(" mSplitDirs=["); + if (mSplitResDirs != null) { + builder.append(TextUtils.join(",", mSplitResDirs)); + } + builder.append("]"); + builder.append(" mOverlayDirs=["); + if (mOverlayDirs != null) { + builder.append(TextUtils.join(",", mOverlayDirs)); + } + builder.append("]"); + builder.append(" mLibDirs=["); + if (mLibDirs != null) { + builder.append(TextUtils.join(",", mLibDirs)); + } + builder.append("]"); + builder.append(" mDisplayId=").append(mDisplayId); + builder.append(" mOverrideConfig=").append(Configuration.resourceQualifierString( + mOverrideConfiguration)); + builder.append(" mCompatInfo=").append(mCompatInfo); + builder.append("}"); + return builder.toString(); } } 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/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java index d58ad22396c6..4add9626b24e 100644 --- a/core/java/android/hardware/camera2/CameraMetadata.java +++ b/core/java/android/hardware/camera2/CameraMetadata.java @@ -2070,6 +2070,24 @@ public abstract class CameraMetadata<TKey> { */ public static final int CONTROL_SCENE_MODE_FACE_PRIORITY_LOW_LIGHT = 19; + /** + * <p>Scene mode values within the range of + * <code>[DEVICE_CUSTOM_START, DEVICE_CUSTOM_END]</code> are reserved for device specific + * customized scene modes.</p> + * @see CaptureRequest#CONTROL_SCENE_MODE + * @hide + */ + public static final int CONTROL_SCENE_MODE_DEVICE_CUSTOM_START = 100; + + /** + * <p>Scene mode values within the range of + * <code>[DEVICE_CUSTOM_START, DEVICE_CUSTOM_END]</code> are reserved for device specific + * customized scene modes.</p> + * @see CaptureRequest#CONTROL_SCENE_MODE + * @hide + */ + public static final int CONTROL_SCENE_MODE_DEVICE_CUSTOM_END = 127; + // // Enumeration values for CaptureRequest#CONTROL_VIDEO_STABILIZATION_MODE // 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/net/TrafficStats.java b/core/java/android/net/TrafficStats.java index ba8bd34bfc6d..95ffb44d22e5 100644 --- a/core/java/android/net/TrafficStats.java +++ b/core/java/android/net/TrafficStats.java @@ -19,6 +19,7 @@ package android.net; import android.annotation.SystemApi; import android.app.DownloadManager; import android.app.backup.BackupManager; +import android.app.usage.NetworkStatsManager; import android.content.Context; import android.media.MediaPlayer; import android.os.RemoteException; @@ -33,12 +34,16 @@ import java.net.Socket; import java.net.SocketException; /** - * Class that provides network traffic statistics. These statistics include + * Class that provides network traffic statistics. These statistics include * bytes transmitted and received and network packets transmitted and received, * over all interfaces, over the mobile interface, and on a per-UID basis. * <p> - * These statistics may not be available on all platforms. If the statistics - * are not supported by this device, {@link #UNSUPPORTED} will be returned. + * These statistics may not be available on all platforms. If the statistics are + * not supported by this device, {@link #UNSUPPORTED} will be returned. + * <p> + * Note that the statistics returned by this class reset and start from zero + * after every reboot. To access more robust historical network statistics data, + * use {@link NetworkStatsManager} instead. */ public class TrafficStats { /** @@ -497,14 +502,27 @@ public class TrafficStats { * monotonically since device boot. Statistics are measured at the network * layer, so they include both TCP and UDP usage. * <p> - * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return - * {@link #UNSUPPORTED} on devices where statistics aren't available. + * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may + * return {@link #UNSUPPORTED} on devices where statistics aren't available. + * <p> + * Starting in {@link android.os.Build.VERSION_CODES#N} this will only + * report traffic statistics for the calling UID. It will return + * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access + * historical network statistics belonging to other UIDs, use + * {@link NetworkStatsManager}. * * @see android.os.Process#myUid() * @see android.content.pm.ApplicationInfo#uid */ public static long getUidTxBytes(int uid) { - return nativeGetUidStat(uid, TYPE_TX_BYTES); + // This isn't actually enforcing any security; it just returns the + // unsupported value. The real filtering is done at the kernel level. + final int callingUid = android.os.Process.myUid(); + if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) { + return nativeGetUidStat(uid, TYPE_TX_BYTES); + } else { + return UNSUPPORTED; + } } /** @@ -515,12 +533,25 @@ public class TrafficStats { * <p> * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return * {@link #UNSUPPORTED} on devices where statistics aren't available. + * <p> + * Starting in {@link android.os.Build.VERSION_CODES#N} this will only + * report traffic statistics for the calling UID. It will return + * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access + * historical network statistics belonging to other UIDs, use + * {@link NetworkStatsManager}. * * @see android.os.Process#myUid() * @see android.content.pm.ApplicationInfo#uid */ public static long getUidRxBytes(int uid) { - return nativeGetUidStat(uid, TYPE_RX_BYTES); + // This isn't actually enforcing any security; it just returns the + // unsupported value. The real filtering is done at the kernel level. + final int callingUid = android.os.Process.myUid(); + if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) { + return nativeGetUidStat(uid, TYPE_RX_BYTES); + } else { + return UNSUPPORTED; + } } /** @@ -531,12 +562,25 @@ public class TrafficStats { * <p> * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return * {@link #UNSUPPORTED} on devices where statistics aren't available. + * <p> + * Starting in {@link android.os.Build.VERSION_CODES#N} this will only + * report traffic statistics for the calling UID. It will return + * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access + * historical network statistics belonging to other UIDs, use + * {@link NetworkStatsManager}. * * @see android.os.Process#myUid() * @see android.content.pm.ApplicationInfo#uid */ public static long getUidTxPackets(int uid) { - return nativeGetUidStat(uid, TYPE_TX_PACKETS); + // This isn't actually enforcing any security; it just returns the + // unsupported value. The real filtering is done at the kernel level. + final int callingUid = android.os.Process.myUid(); + if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) { + return nativeGetUidStat(uid, TYPE_TX_PACKETS); + } else { + return UNSUPPORTED; + } } /** @@ -547,12 +591,25 @@ public class TrafficStats { * <p> * Before {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}, this may return * {@link #UNSUPPORTED} on devices where statistics aren't available. + * <p> + * Starting in {@link android.os.Build.VERSION_CODES#N} this will only + * report traffic statistics for the calling UID. It will return + * {@link #UNSUPPORTED} for all other UIDs for privacy reasons. To access + * historical network statistics belonging to other UIDs, use + * {@link NetworkStatsManager}. * * @see android.os.Process#myUid() * @see android.content.pm.ApplicationInfo#uid */ public static long getUidRxPackets(int uid) { - return nativeGetUidStat(uid, TYPE_RX_PACKETS); + // This isn't actually enforcing any security; it just returns the + // unsupported value. The real filtering is done at the kernel level. + final int callingUid = android.os.Process.myUid(); + if (callingUid == android.os.Process.SYSTEM_UID || callingUid == uid) { + return nativeGetUidStat(uid, TYPE_RX_PACKETS); + } else { + return UNSUPPORTED; + } } /** diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index 8281279bec68..e1c7ad77bd25 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -465,6 +465,7 @@ public abstract class BatteryStats implements Parcelable { }; public abstract long getProcessStateTime(int state, long elapsedRealtimeUs, int which); + public abstract Timer getProcessStateTimer(int state); public abstract Timer getVibratorOnTimer(); 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/os/DropBoxManager.java b/core/java/android/os/DropBoxManager.java index 0d940723b7d2..cb85eef5724f 100644 --- a/core/java/android/os/DropBoxManager.java +++ b/core/java/android/os/DropBoxManager.java @@ -16,6 +16,9 @@ package android.os; +import android.content.Context; +import android.util.Log; + import com.android.internal.os.IDropBoxManagerService; import java.io.ByteArrayInputStream; @@ -40,6 +43,8 @@ import java.util.zip.GZIPInputStream; */ public class DropBoxManager { private static final String TAG = "DropBoxManager"; + + private final Context mContext; private final IDropBoxManagerService mService; /** Flag value: Entry's content was deleted to save space. */ @@ -249,14 +254,20 @@ public class DropBoxManager { } /** {@hide} */ - public DropBoxManager(IDropBoxManagerService service) { mService = service; } + public DropBoxManager(Context context, IDropBoxManagerService service) { + mContext = context; + mService = service; + } /** * Create a dummy instance for testing. All methods will fail unless * overridden with an appropriate mock implementation. To obtain a * functional instance, use {@link android.content.Context#getSystemService}. */ - protected DropBoxManager() { mService = null; } + protected DropBoxManager() { + mContext = null; + mService = null; + } /** * Stores human-readable text. The data may be discarded eventually (or even @@ -270,6 +281,11 @@ public class DropBoxManager { try { mService.add(new Entry(tag, 0, data)); } catch (RemoteException e) { + if (e instanceof TransactionTooLargeException + && mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N) { + Log.e(TAG, "App sent too much data, so it was ignored", e); + return; + } throw e.rethrowFromSystemServer(); } } @@ -286,6 +302,11 @@ public class DropBoxManager { try { mService.add(new Entry(tag, 0, data, flags)); } catch (RemoteException e) { + if (e instanceof TransactionTooLargeException + && mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N) { + Log.e(TAG, "App sent too much data, so it was ignored", e); + return; + } throw e.rethrowFromSystemServer(); } } diff --git a/core/java/android/os/IDeviceIdleController.aidl b/core/java/android/os/IDeviceIdleController.aidl index 838279bf38f9..082194ba6162 100644 --- a/core/java/android/os/IDeviceIdleController.aidl +++ b/core/java/android/os/IDeviceIdleController.aidl @@ -25,10 +25,12 @@ interface IDeviceIdleController { void removePowerSaveWhitelistApp(String name); String[] getSystemPowerWhitelistExceptIdle(); String[] getSystemPowerWhitelist(); + String[] getUserPowerWhitelist(); String[] getFullPowerWhitelistExceptIdle(); String[] getFullPowerWhitelist(); int[] getAppIdWhitelistExceptIdle(); int[] getAppIdWhitelist(); + int[] getAppIdUserWhitelist(); int[] getAppIdTempWhitelist(); boolean isPowerSaveWhitelistExceptIdleApp(String name); boolean isPowerSaveWhitelistApp(String name); diff --git a/core/java/android/os/PersistableBundle.java b/core/java/android/os/PersistableBundle.java index f36bb2989c72..5872f7438904 100644 --- a/core/java/android/os/PersistableBundle.java +++ b/core/java/android/os/PersistableBundle.java @@ -86,6 +86,8 @@ public final class PersistableBundle extends BaseBundle implements Cloneable, Pa * @param b a Bundle to be copied. * * @throws IllegalArgumentException if any element of {@code b} cannot be persisted. + * + * @hide */ public PersistableBundle(Bundle b) { this(b.getMap()); diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 8fd3b0c0035f..4506f51fe38a 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -998,6 +998,31 @@ public class Process { throws IllegalArgumentException, SecurityException; /** + * On some devices, the foreground process may have one or more CPU + * cores exclusively reserved for it. This method can be used to + * retrieve which cores that are (if any), so the calling process + * can then use sched_setaffinity() to lock a thread to these cores. + * Note that the calling process must currently be running in the + * foreground for this method to return any cores. + * + * The CPU core(s) exclusively reserved for the foreground process will + * stay reserved for as long as the process stays in the foreground. + * + * As soon as a process leaves the foreground, those CPU cores will + * no longer be reserved for it, and will most likely be reserved for + * the new foreground process. It's not necessary to change the affinity + * of your process when it leaves the foreground (if you had previously + * set it to use a reserved core); the OS will automatically take care + * of resetting the affinity at that point. + * + * @return an array of integers, indicating the CPU cores exclusively + * reserved for this process. The array will have length zero if no + * CPU cores are exclusively reserved for this process at this point + * in time. + */ + public static final native int[] getExclusiveCores(); + + /** * Set the priority of the calling thread, based on Linux priorities. See * {@link #setThreadPriority(int, int)} for more information. * diff --git a/core/java/android/os/health/HealthKeys.java b/core/java/android/os/health/HealthKeys.java new file mode 100644 index 000000000000..842def3d256b --- /dev/null +++ b/core/java/android/os/health/HealthKeys.java @@ -0,0 +1,219 @@ +/* + * 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.os.health; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Field; +import java.util.Arrays; + +/** + * Constants and stuff for the android.os.health package. + * + * @hide + */ +public class HealthKeys { + + /** + * No valid key will ever be 0. + */ + public static final int UNKNOWN_KEY = 0; + + /* + * Base key for each of the different classes. There is + * nothing intrinsic to the operation of the value of the + * keys. It's just segmented for better debugging. The + * classes don't mix them anway. + */ + public static final int BASE_UID = 10000; + public static final int BASE_PID = 20000; + public static final int BASE_PROCESS = 30000; + public static final int BASE_PACKAGE = 40000; + public static final int BASE_SERVICE = 50000; + + /* + * The types of values supported by HealthStats. + */ + public static final int TYPE_TIMER = 0; + public static final int TYPE_MEASUREMENT = 1; + public static final int TYPE_STATS = 2; + public static final int TYPE_TIMERS = 3; + public static final int TYPE_MEASUREMENTS = 4; + + public static final int TYPE_COUNT = 5; + + /** + * Annotation to mark public static final int fields that are to be used + * as field keys in HealthStats. + */ + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.FIELD}) + public @interface Constant { + /** + * One of the TYPE_* constants above. + */ + int type(); + } + + /** + * Class to gather the constants defined in a class full of constants and + * build the key indices used by HealthStatsWriter and HealthStats. + * + * @hide + */ + public static class Constants { + private final String mDataType; + private final int[][] mKeys = new int[TYPE_COUNT][]; + + /** + * Pass in a class to gather the public static final int fields that are + * tagged with the @Constant annotation. + */ + public Constants(Class clazz) { + // Save the class name for debugging + mDataType = clazz.getSimpleName(); + + // Iterate through the list of fields on this class, and build the + // constant arrays for these fields. + final Field[] fields = clazz.getDeclaredFields(); + final Class<Constant> annotationClass = Constant.class; + + final int N = fields.length; + + final SortedIntArray[] keys = new SortedIntArray[mKeys.length]; + for (int i=0; i<keys.length; i++) { + keys[i] = new SortedIntArray(N); + } + + for (int i=0; i<N; i++) { + final Field field = fields[i]; + final Constant constant = field.getAnnotation(annotationClass); + if (constant != null) { + final int type = constant.type(); + if (type >= keys.length) { + throw new RuntimeException("Unknown Constant type " + type + + " on " + field); + } + try { + keys[type].addValue(field.getInt(null)); + } catch (IllegalAccessException ex) { + throw new RuntimeException("Can't read constant value type=" + type + + " field=" + field, ex); + } + } + } + + for (int i=0; i<keys.length; i++) { + mKeys[i] = keys[i].getArray(); + } + } + + /** + * Get a string representation of this class. Useful for debugging. It will be the + * simple name of the class passed in the constructor. + */ + public String getDataType() { + return mDataType; + } + + /** + * Return how many keys there are for the given field type. + * + * @see TYPE_TIMER + * @see TYPE_MEASUREMENT + * @see TYPE_TIMERS + * @see TYPE_MEASUREMENTS + * @see TYPE_STATS + */ + public int getSize(int type) { + return mKeys[type].length; + } + + /** + * Return the index for the given type and key combination in the array of field + * keys or values. + * + * @see TYPE_TIMER + * @see TYPE_MEASUREMENT + * @see TYPE_TIMERS + * @see TYPE_MEASUREMENTS + * @see TYPE_STATS + */ + public int getIndex(int type, int key) { + final int index = Arrays.binarySearch(mKeys[type], key); + if (index >= 0) { + return index; + } else { + throw new RuntimeException("Unknown Constant " + key + " (of type " + + type + " )"); + } + } + + /** + * Get the array of keys for the given field type. + */ + public int[] getKeys(int type) { + return mKeys[type]; + } + } + + /** + * An array of fixed size that will be sorted. + */ + private static class SortedIntArray { + int mCount; + int[] mArray; + + /** + * Construct with the maximum number of values. + */ + SortedIntArray(int maxCount) { + mArray = new int[maxCount]; + } + + /** + * Add a value. + */ + void addValue(int value) { + mArray[mCount++] = value; + } + + /** + * Get the array of values that have been added, with the values in + * numerically increasing order. + */ + int[] getArray() { + if (mCount == mArray.length) { + Arrays.sort(mArray); + return mArray; + } else { + final int[] result = new int[mCount]; + System.arraycopy(mArray, 0, result, 0, mCount); + Arrays.sort(result); + return result; + } + } + } +} + + diff --git a/core/java/android/os/health/HealthStats.java b/core/java/android/os/health/HealthStats.java new file mode 100644 index 000000000000..f0489e244750 --- /dev/null +++ b/core/java/android/os/health/HealthStats.java @@ -0,0 +1,481 @@ +/* + * 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.os.health; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.ArrayMap; + +import java.util.Arrays; +import java.util.Map; + +/** + * A HealthStats object contains system health data about an application. + * + * <p> + * <b>Data Types</b><br> + * Each of the keys references data in one of five data types: + * + * <p> + * A <b>measurement</b> metric contains a sinlge {@code long} value. That value may + * be a count, a time, or some other type of value. The unit for a measurement + * (COUNT, MS, etc) will always be in the name of the constant for the key to + * retrieve it. For example, the + * {@link android.os.health.UidHealthStats#MEASUREMENT_WIFI_TX_MS UidHealthStats.MEASUREMENT_WIFI_TX_MS} + * value is the number of milliseconds (ms) that were spent transmitting on wifi by an + * application. The + * {@link android.os.health.UidHealthStats#MEASUREMENT_MOBILE_RX_PACKETS UidHealthStats.MEASUREMENT_MOBILE_RX_PACKETS} + * measurement is the number of packets received on behalf of an application. + * The {@link android.os.health.UidHealthStats#MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT + * UidHealthStats.MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT} + * measurement is the number of times the user touched the screen, causing the + * screen to stay awake. + * + * + * <p> + * A <b>timer</b> metric contains an {@code int} count and a {@code long} time, + * measured in milliseconds. Timers track how many times a resource was used, and + * the total duration for that usage. For example, the + * {@link android.os.health.UidHealthStats#TIMER_FLASHLIGHT} + * timer tracks how many times the application turned on the flashlight, and for + * how many milliseconds total it kept it on. + * + * <p> + * A <b>measurement map</b> metric is a mapping of {@link java.lang.String} names to + * {@link java.lang.Long} values. The names typically are application provided names. For + * example, the + * {@link android.os.health.PackageHealthStats#MEASUREMENTS_WAKEUP_ALARMS_COUNT + * PackageHealthStats.MEASUREMENTS_WAKEUP_ALARMS_COUNT} + * measurement map is a mapping of the tag provided to the + * {@link android.app.AlarmManager} when the alarm is scheduled. + * + * <p> + * A <b>timer map</b> metric is a mapping of {@link java.lang.String} names to + * {@link android.os.health.TimerStat} objects. The names are typically application + * provided names. For example, the + * {@link android.os.health.UidHealthStats#TIMERS_WAKELOCKS_PARTIAL UidHealthStats.TIMERS_WAKELOCKS_PARTIAL} + * is a mapping of tag provided to the {@link android.os.PowerManager} when the + * wakelock is created to the number of times and for how long each wakelock was + * active. + * + * <p> + * Lastly, a <b>health stats</b> metric is a mapping of {@link java.lang.String} + * names to a recursive {@link android.os.health.HealthStats} object containing + * more detailed information. For example, the + * {@link android.os.health.UidHealthStats#STATS_PACKAGES UidHealthStats.STATS_PACKAGES} + * metric is a mapping of the package names for each of the APKs sharing a uid to + * the information recorded for that apk. The returned HealthStats objects will + * each be associated with a different set of constants. For the HealthStats + * returned for UidHealthStats.STATS_PACKAGES, the keys come from the + * {@link android.os.health.PackageHealthStats} class. + * + */ +public class HealthStats { + // Header fields + private String mDataType; + + // TimerStat fields + private int[] mTimerKeys; + private int[] mTimerCounts; + private long[] mTimerTimes; + + // Measurement fields + private int[] mMeasurementKeys; + private long[] mMeasurementValues; + + // Stats fields + private int[] mStatsKeys; + private ArrayMap<String,HealthStats>[] mStatsValues; + + // Timers fields + private int[] mTimersKeys; + private ArrayMap<String,TimerStat>[] mTimersValues; + + // Measurements fields + private int[] mMeasurementsKeys; + private ArrayMap<String,Long>[] mMeasurementsValues; + + /** + * HealthStats empty constructor not implemented because this + * class is read-only. + */ + private HealthStats() { + throw new RuntimeException("unsupported"); + } + + /** + * Construct a health stats object from a parcel. + * + * @hide + */ + public HealthStats(Parcel in) { + int count; + + // Header fields + mDataType = in.readString(); + + // TimerStat fields + count = in.readInt(); + mTimerKeys = new int[count]; + mTimerCounts = new int[count]; + mTimerTimes = new long[count]; + for (int i=0; i<count; i++) { + mTimerKeys[i] = in.readInt(); + mTimerCounts[i] = in.readInt(); + mTimerTimes[i] = in.readLong(); + } + + // Measurement fields + count = in.readInt(); + mMeasurementKeys = new int[count]; + mMeasurementValues = new long[count]; + for (int i=0; i<count; i++) { + mMeasurementKeys[i] = in.readInt(); + mMeasurementValues[i] = in.readLong(); + } + + // Stats fields + count = in.readInt(); + mStatsKeys = new int[count]; + mStatsValues = new ArrayMap[count]; + for (int i=0; i<count; i++) { + mStatsKeys[i] = in.readInt(); + mStatsValues[i] = createHealthStatsMap(in); + } + + // Timers fields + count = in.readInt(); + mTimersKeys = new int[count]; + mTimersValues = new ArrayMap[count]; + for (int i=0; i<count; i++) { + mTimersKeys[i] = in.readInt(); + mTimersValues[i] = createParcelableMap(in, TimerStat.CREATOR); + } + + // Measurements fields + count = in.readInt(); + mMeasurementsKeys = new int[count]; + mMeasurementsValues = new ArrayMap[count]; + for (int i=0; i<count; i++) { + mMeasurementsKeys[i] = in.readInt(); + mMeasurementsValues[i] = createLongsMap(in); + } + } + + /** + * Get a name representing the contents of this object. + * + * @see UidHealthStats + * @see PackageHealthStats + * @see PidHealthStats + * @see ProcessHealthStats + * @see ServiceHealthStats + */ + public String getDataType() { + return mDataType; + } + + /** + * Return whether this object contains a TimerStat for the supplied key. + */ + public boolean hasTimer(int key) { + return getIndex(mTimerKeys, key) >= 0; + } + + /** + * Return a TimerStat object for the given key. + * + * This will allocate a new {@link TimerStat} object, which may be wasteful. Instead, use + * {@link #getTimerCount} and {@link #getTimerTime}. + * + * @throws IndexOutOfBoundsException When the key is not present in this object. + * @see #hasTimer hasTimer(int) To check if a value for the given key is present. + */ + public TimerStat getTimer(int key) { + final int index = getIndex(mTimerKeys, key); + if (index < 0) { + throw new IndexOutOfBoundsException("Bad timer key dataType=" + mDataType + + " key=" + key); + } + return new TimerStat(mTimerCounts[index], mTimerTimes[index]); + } + + /** + * Get the count for the timer for the given key. + * + * @throws IndexOutOfBoundsException When the key is not present in this object. + * @see #hasTimer hasTimer(int) To check if a value for the given key is present. + */ + public int getTimerCount(int key) { + final int index = getIndex(mTimerKeys, key); + if (index < 0) { + throw new IndexOutOfBoundsException("Bad timer key dataType=" + mDataType + + " key=" + key); + } + return mTimerCounts[index]; + } + + /** + * Get the time for the timer for the given key, in milliseconds. + * + * @throws IndexOutOfBoundsException When the key is not present in this object. + * @see #hasTimer hasTimer(int) To check if a value for the given key is present. + */ + public long getTimerTime(int key) { + final int index = getIndex(mTimerKeys, key); + if (index < 0) { + throw new IndexOutOfBoundsException("Bad timer key dataType=" + mDataType + + " key=" + key); + } + return mTimerTimes[index]; + } + + /** + * Get the number of timer values in this object. Can be used to iterate through + * the available timers. + * + * @see #getTimerKeyAt + */ + public int getTimerKeyCount() { + return mTimerKeys.length; + } + + /** + * Get the key for the timer at the given index. Index must be between 0 and the result + * of {@link #getTimerKeyCount getTimerKeyCount()}. + * + * @see #getTimerKeyCount + */ + public int getTimerKeyAt(int index) { + return mTimerKeys[index]; + } + + /** + * Return whether this object contains a measurement for the supplied key. + */ + public boolean hasMeasurement(int key) { + return getIndex(mMeasurementKeys, key) >= 0; + } + + /** + * Get the measurement for the given key. + * + * @throws IndexOutOfBoundsException When the key is not present in this object. + * @see #hasMeasurement hasMeasurement(int) To check if a value for the given key is present. + */ + public long getMeasurement(int key) { + final int index = getIndex(mMeasurementKeys, key); + if (index < 0) { + throw new IndexOutOfBoundsException("Bad measurement key dataType=" + mDataType + + " key=" + key); + } + return mMeasurementValues[index]; + } + + /** + * Get the number of measurement values in this object. Can be used to iterate through + * the available measurements. + * + * @see #getMeasurementKeyAt + */ + public int getMeasurementKeyCount() { + return mMeasurementKeys.length; + } + + /** + * Get the key for the measurement at the given index. Index must be between 0 and the result + * of {@link #getMeasurementKeyCount getMeasurementKeyCount()}. + * + * @see #getMeasurementKeyCount + */ + public int getMeasurementKeyAt(int index) { + return mMeasurementKeys[index]; + } + + /** + * Return whether this object contains a HealthStats map for the supplied key. + */ + public boolean hasStats(int key) { + return getIndex(mStatsKeys, key) >= 0; + } + + /** + * Get the HealthStats map for the given key. + * + * @throws IndexOutOfBoundsException When the key is not present in this object. + * @see #hasStats hasStats(int) To check if a value for the given key is present. + */ + public Map<String,HealthStats> getStats(int key) { + final int index = getIndex(mStatsKeys, key); + if (index < 0) { + throw new IndexOutOfBoundsException("Bad stats key dataType=" + mDataType + + " key=" + key); + } + return mStatsValues[index]; + } + + /** + * Get the number of HealthStat map values in this object. Can be used to iterate through + * the available measurements. + * + * @see #getMeasurementKeyAt + */ + public int getStatsKeyCount() { + return mStatsKeys.length; + } + + /** + * Get the key for the timer at the given index. Index must be between 0 and the result + * of {@link #getStatsKeyCount getStatsKeyCount()}. + * + * @see #getStatsKeyCount + */ + public int getStatsKeyAt(int index) { + return mStatsKeys[index]; + } + + /** + * Return whether this object contains a timers map for the supplied key. + */ + public boolean hasTimers(int key) { + return getIndex(mTimersKeys, key) >= 0; + } + + /** + * Get the TimerStat map for the given key. + * + * @throws IndexOutOfBoundsException When the key is not present in this object. + * @see #hasTimers hasTimers(int) To check if a value for the given key is present. + */ + public Map<String,TimerStat> getTimers(int key) { + final int index = getIndex(mTimersKeys, key); + if (index < 0) { + throw new IndexOutOfBoundsException("Bad timers key dataType=" + mDataType + + " key=" + key); + } + return mTimersValues[index]; + } + + /** + * Get the number of timer map values in this object. Can be used to iterate through + * the available timer maps. + * + * @see #getTimersKeyAt + */ + public int getTimersKeyCount() { + return mTimersKeys.length; + } + + /** + * Get the key for the timer map at the given index. Index must be between 0 and the result + * of {@link #getTimersKeyCount getTimersKeyCount()}. + * + * @see #getTimersKeyCount + */ + public int getTimersKeyAt(int index) { + return mTimersKeys[index]; + } + + /** + * Return whether this object contains a measurements map for the supplied key. + */ + public boolean hasMeasurements(int key) { + return getIndex(mMeasurementsKeys, key) >= 0; + } + + /** + * Get the measurements map for the given key. + * + * @throws IndexOutOfBoundsException When the key is not present in this object. + * @see #hasMeasurements To check if a value for the given key is present. + */ + public Map<String,Long> getMeasurements(int key) { + final int index = getIndex(mMeasurementsKeys, key); + if (index < 0) { + throw new IndexOutOfBoundsException("Bad measurements key dataType=" + mDataType + + " key=" + key); + } + return mMeasurementsValues[index]; + } + + /** + * Get the number of measurement map values in this object. Can be used to iterate through + * the available measurement maps. + * + * @see #getMeasurementsKeyAt + */ + public int getMeasurementsKeyCount() { + return mMeasurementsKeys.length; + } + + /** + * Get the key for the measurement map at the given index. + * Index must be between 0 and the result + * of {@link #getMeasurementsKeyCount getMeasurementsKeyCount()}. + * + * @see #getMeasurementsKeyCount + */ + public int getMeasurementsKeyAt(int index) { + return mMeasurementsKeys[index]; + } + + /** + * Get the index in keys of key. + */ + private static int getIndex(int[] keys, int key) { + return Arrays.binarySearch(keys, key); + } + + /** + * Create an ArrayMap<String,HealthStats> from the given Parcel. + */ + private static ArrayMap<String,HealthStats> createHealthStatsMap(Parcel in) { + final int count = in.readInt(); + final ArrayMap<String,HealthStats> result = new ArrayMap<String,HealthStats>(count); + for (int i=0; i<count; i++) { + result.put(in.readString(), new HealthStats(in)); + } + return result; + } + + /** + * Create an ArrayMap<String,T extends Parcelable> from the given Parcel using + * the given Parcelable.Creator. + */ + private static <T extends Parcelable> ArrayMap<String,T> createParcelableMap(Parcel in, + Parcelable.Creator<T> creator) { + final int count = in.readInt(); + final ArrayMap<String,T> result = new ArrayMap<String,T>(count); + for (int i=0; i<count; i++) { + result.put(in.readString(), creator.createFromParcel(in)); + } + return result; + } + + /** + * Create an ArrayMap<String,Long> from the given Parcel. + */ + private static ArrayMap<String,Long> createLongsMap(Parcel in) { + final int count = in.readInt(); + final ArrayMap<String,Long> result = new ArrayMap<String,Long>(count); + for (int i=0; i<count; i++) { + result.put(in.readString(), in.readLong()); + } + return result; + } +} + diff --git a/libs/hwui/tests/microbench/MicroBench.h b/core/java/android/os/health/HealthStatsParceler.aidl index f05e92cd86d1..68c348b1d21b 100644 --- a/libs/hwui/tests/microbench/MicroBench.h +++ b/core/java/android/os/health/HealthStatsParceler.aidl @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 The Android Open Source Project + * Copyright (C) 2016 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,23 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef MICROBENCH_MICROBENCH_H -#define MICROBENCH_MICROBENCH_H -namespace android { -namespace uirenderer { +package android.os.health; -#define NO_INLINE __attribute__ ((noinline)) - -class MicroBench { -public: - template <class Tp> - static inline void DoNotOptimize(Tp const& value) { - asm volatile("" : "+rm" (const_cast<Tp&>(value))); - } -}; - -} /* namespace uirenderer */ -} /* namespace android */ - -#endif /* MICROBENCH_MICROBENCH_H */ +parcelable HealthStatsParceler; diff --git a/core/java/android/os/health/HealthStatsParceler.java b/core/java/android/os/health/HealthStatsParceler.java new file mode 100644 index 000000000000..28b36940fb2e --- /dev/null +++ b/core/java/android/os/health/HealthStatsParceler.java @@ -0,0 +1,87 @@ +/* + * 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.os.health; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.ArrayMap; + +import java.util.Arrays; +import java.util.Map; + +/** + * Class to allow sending the HealthStats through aidl generated glue. + * + * The alternative would be to send a HealthStats object, which would + * require constructing one, and then immediately flattening it. This + * saves that step at the cost of doing the extra flattening when + * accessed in the same process as the writer. + * + * The HealthStatsWriter passed in the constructor is retained, so don't + * reuse them. + * @hide + */ +public class HealthStatsParceler implements Parcelable { + private HealthStatsWriter mWriter; + private HealthStats mHealthStats; + + public static final Parcelable.Creator<HealthStatsParceler> CREATOR + = new Parcelable.Creator<HealthStatsParceler>() { + public HealthStatsParceler createFromParcel(Parcel in) { + return new HealthStatsParceler(in); + } + + public HealthStatsParceler[] newArray(int size) { + return new HealthStatsParceler[size]; + } + }; + + public HealthStatsParceler(HealthStatsWriter writer) { + mWriter = writer; + } + + public HealthStatsParceler(Parcel in) { + mHealthStats = new HealthStats(in); + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel out, int flags) { + // See comment on mWriter declaration above. + if (mWriter != null) { + mWriter.flattenToParcel(out); + } else { + throw new RuntimeException("Can not re-parcel HealthStatsParceler that was" + + " constructed from a Parcel"); + } + } + + public HealthStats getHealthStats() { + if (mWriter != null) { + final Parcel parcel = Parcel.obtain(); + mWriter.flattenToParcel(parcel); + parcel.setDataPosition(0); + mHealthStats = new HealthStats(parcel); + parcel.recycle(); + } + + return mHealthStats; + } +} + diff --git a/core/java/android/os/health/HealthStatsWriter.java b/core/java/android/os/health/HealthStatsWriter.java new file mode 100644 index 000000000000..351836bad7c9 --- /dev/null +++ b/core/java/android/os/health/HealthStatsWriter.java @@ -0,0 +1,288 @@ +/* + * 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.os.health; + +import android.os.Parcel; +import android.os.Parcelable; +import android.util.ArrayMap; + +import java.util.Map; + +/** + * Class to write the health stats data into a parcel, so it can then be + * retrieved via a {@link HealthStats} object. + * + * There is an attempt to keep this class as low overhead as possible, for + * example storing an int[] and a long[] instead of a TimerStat[]. + * + * @hide + */ +public class HealthStatsWriter { + private final HealthKeys.Constants mConstants; + + // TimerStat fields + private final boolean[] mTimerFields; + private final int[] mTimerCounts; + private final long[] mTimerTimes; + + // Measurement fields + private final boolean[] mMeasurementFields; + private final long[] mMeasurementValues; + + // Stats fields + private final ArrayMap<String,HealthStatsWriter>[] mStatsValues; + + // Timers fields + private final ArrayMap<String,TimerStat>[] mTimersValues; + + // Measurements fields + private final ArrayMap<String,Long>[] mMeasurementsValues; + + /** + * Construct a HealthStatsWriter object with the given constants. + * + * The "getDataType()" of the resulting HealthStats object will be the + * short name of the java class that the Constants object was initalized + * with. + */ + public HealthStatsWriter(HealthKeys.Constants constants) { + mConstants = constants; + + // TimerStat + final int timerCount = constants.getSize(HealthKeys.TYPE_TIMER); + mTimerFields = new boolean[timerCount]; + mTimerCounts = new int[timerCount]; + mTimerTimes = new long[timerCount]; + + // Measurement + final int measurementCount = constants.getSize(HealthKeys.TYPE_MEASUREMENT); + mMeasurementFields = new boolean[measurementCount]; + mMeasurementValues = new long[measurementCount]; + + // Stats + final int statsCount = constants.getSize(HealthKeys.TYPE_STATS); + mStatsValues = new ArrayMap[statsCount]; + + // Timers + final int timersCount = constants.getSize(HealthKeys.TYPE_TIMERS); + mTimersValues = new ArrayMap[timersCount]; + + // Measurements + final int measurementsCount = constants.getSize(HealthKeys.TYPE_MEASUREMENTS); + mMeasurementsValues = new ArrayMap[measurementsCount]; + } + + /** + * Add a timer for the given key. + */ + public void addTimer(int timerId, int count, long time) { + final int index = mConstants.getIndex(HealthKeys.TYPE_TIMER, timerId); + + mTimerFields[index] = true; + mTimerCounts[index] = count; + mTimerTimes[index] = time; + } + + /** + * Add a measurement for the given key. + */ + public void addMeasurement(int measurementId, long value) { + final int index = mConstants.getIndex(HealthKeys.TYPE_MEASUREMENT, measurementId); + + mMeasurementFields[index] = true; + mMeasurementValues[index] = value; + } + + /** + * Add a recursive HealthStats object for the given key and string name. The value + * is stored as a HealthStatsWriter until this object is written to a parcel, so + * don't attempt to reuse the HealthStatsWriter. + * + * The value field should not be null. + */ + public void addStats(int key, String name, HealthStatsWriter value) { + final int index = mConstants.getIndex(HealthKeys.TYPE_STATS, key); + + ArrayMap<String,HealthStatsWriter> map = mStatsValues[index]; + if (map == null) { + map = mStatsValues[index] = new ArrayMap<String,HealthStatsWriter>(1); + } + map.put(name, value); + } + + /** + * Add a TimerStat for the given key and string name. + * + * The value field should not be null. + */ + public void addTimers(int key, String name, TimerStat value) { + final int index = mConstants.getIndex(HealthKeys.TYPE_TIMERS, key); + + ArrayMap<String,TimerStat> map = mTimersValues[index]; + if (map == null) { + map = mTimersValues[index] = new ArrayMap<String,TimerStat>(1); + } + map.put(name, value); + } + + /** + * Add a measurement for the given key and string name. + */ + public void addMeasurements(int key, String name, long value) { + final int index = mConstants.getIndex(HealthKeys.TYPE_MEASUREMENTS, key); + + ArrayMap<String,Long> map = mMeasurementsValues[index]; + if (map == null) { + map = mMeasurementsValues[index] = new ArrayMap<String,Long>(1); + } + map.put(name, value); + } + + /** + * Flattens the data in this HealthStatsWriter to the Parcel format + * that can be unparceled into a HealthStat. + * @more + * (Called flattenToParcel because this HealthStatsWriter itself is + * not parcelable and we don't flatten all the business about the + * HealthKeys.Constants, only the values that were actually supplied) + */ + public void flattenToParcel(Parcel out) { + int[] keys; + + // Header fields + out.writeString(mConstants.getDataType()); + + // TimerStat fields + out.writeInt(countBooleanArray(mTimerFields)); + keys = mConstants.getKeys(HealthKeys.TYPE_TIMER); + for (int i=0; i<keys.length; i++) { + if (mTimerFields[i]) { + out.writeInt(keys[i]); + out.writeInt(mTimerCounts[i]); + out.writeLong(mTimerTimes[i]); + } + } + + // Measurement fields + out.writeInt(countBooleanArray(mMeasurementFields)); + keys = mConstants.getKeys(HealthKeys.TYPE_MEASUREMENT); + for (int i=0; i<keys.length; i++) { + if (mMeasurementFields[i]) { + out.writeInt(keys[i]); + out.writeLong(mMeasurementValues[i]); + } + } + + // Stats + out.writeInt(countObjectArray(mStatsValues)); + keys = mConstants.getKeys(HealthKeys.TYPE_STATS); + for (int i=0; i<keys.length; i++) { + if (mStatsValues[i] != null) { + out.writeInt(keys[i]); + writeHealthStatsWriterMap(out, mStatsValues[i]); + } + } + + // Timers + out.writeInt(countObjectArray(mTimersValues)); + keys = mConstants.getKeys(HealthKeys.TYPE_TIMERS); + for (int i=0; i<keys.length; i++) { + if (mTimersValues[i] != null) { + out.writeInt(keys[i]); + writeParcelableMap(out, mTimersValues[i]); + } + } + + // Measurements + out.writeInt(countObjectArray(mMeasurementsValues)); + keys = mConstants.getKeys(HealthKeys.TYPE_MEASUREMENTS); + for (int i=0; i<keys.length; i++) { + if (mMeasurementsValues[i] != null) { + out.writeInt(keys[i]); + writeLongsMap(out, mMeasurementsValues[i]); + } + } + } + + /** + * Count how many of the fields have been set. + */ + private static int countBooleanArray(boolean[] fields) { + int count = 0; + final int N = fields.length; + for (int i=0; i<N; i++) { + if (fields[i]) { + count++; + } + } + return count; + } + + /** + * Count how many of the fields have been set. + */ + private static <T extends Object> int countObjectArray(T[] fields) { + int count = 0; + final int N = fields.length; + for (int i=0; i<N; i++) { + if (fields[i] != null) { + count++; + } + } + return count; + } + + /** + * Write a map of String to HealthStatsWriter to the Parcel. + */ + private static void writeHealthStatsWriterMap(Parcel out, + ArrayMap<String,HealthStatsWriter> map) { + final int N = map.size(); + out.writeInt(N); + for (int i=0; i<N; i++) { + out.writeString(map.keyAt(i)); + map.valueAt(i).flattenToParcel(out); + } + } + + /** + * Write a map of String to Parcelables to the Parcel. + */ + private static <T extends Parcelable> void writeParcelableMap(Parcel out, + ArrayMap<String,T> map) { + final int N = map.size(); + out.writeInt(N); + for (int i=0; i<N; i++) { + out.writeString(map.keyAt(i)); + map.valueAt(i).writeToParcel(out, 0); + } + } + + /** + * Write a map of String to Longs to the Parcel. + */ + private static void writeLongsMap(Parcel out, ArrayMap<String,Long> map) { + final int N = map.size(); + out.writeInt(N); + for (int i=0; i<N; i++) { + out.writeString(map.keyAt(i)); + out.writeLong(map.valueAt(i)); + } + } +} + + diff --git a/core/java/android/os/health/PackageHealthStats.java b/core/java/android/os/health/PackageHealthStats.java new file mode 100644 index 000000000000..2c30d5f4018c --- /dev/null +++ b/core/java/android/os/health/PackageHealthStats.java @@ -0,0 +1,50 @@ +/* + * 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.os.health; + +/** + * Keys for {@link HealthStats} returned from + * {@link HealthStats#getStats(int) HealthStats.getStats(int)} with the + * {@link UidHealthStats#STATS_PACKAGES UidHealthStats.STATS_PACKAGES} key. + */ +public final class PackageHealthStats { + + private PackageHealthStats() { + } + + /** + * Key for a HealthStats with {@link ServiceHealthStats} keys for each of the + * services defined in this apk. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_STATS) + public static final int STATS_SERVICES = HealthKeys.BASE_PACKAGE + 1; + + /** + * Key for a map of the number of times that a package's wakeup alarms have fired + * while the device was on battery. + * + * @see android.app.AlarmManager. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENTS) + public static final int MEASUREMENTS_WAKEUP_ALARMS_COUNT = HealthKeys.BASE_PACKAGE + 2; + + /** + * @hide + */ + public static final HealthKeys.Constants CONSTANTS + = new HealthKeys.Constants(PackageHealthStats.class); +} diff --git a/core/java/android/os/health/PidHealthStats.java b/core/java/android/os/health/PidHealthStats.java new file mode 100644 index 000000000000..fe3c02cadcc7 --- /dev/null +++ b/core/java/android/os/health/PidHealthStats.java @@ -0,0 +1,42 @@ +/* + * 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.os.health; + +/** + * Keys for {@link HealthStats} returned from + * {@link HealthStats#getStats(int) HealthStats.getStats(int)} with the + * {@link UidHealthStats#STATS_PIDS UidHealthStats.STATS_PIDS} key. + */ +public final class PidHealthStats { + + private PidHealthStats() { + } + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WAKE_NESTING_COUNT = HealthKeys.BASE_PID + 1; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WAKE_SUM_MS = HealthKeys.BASE_PID + 2; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WAKE_START_MS = HealthKeys.BASE_PID + 3; + + /** + * @hide + */ + public static final HealthKeys.Constants CONSTANTS = new HealthKeys.Constants(PidHealthStats.class); +} diff --git a/core/java/android/os/health/ProcessHealthStats.java b/core/java/android/os/health/ProcessHealthStats.java new file mode 100644 index 000000000000..e004ecb27ad5 --- /dev/null +++ b/core/java/android/os/health/ProcessHealthStats.java @@ -0,0 +1,51 @@ +/* + * 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.os.health; + +/** + * Keys for {@link HealthStats} returned from + * {@link HealthStats#getStats(int) HealthStats.getStats(int)} with the + * {@link UidHealthStats#STATS_PROCESSES UidHealthStats.STATS_PROCESSES} key. + */ +public final class ProcessHealthStats { + + private ProcessHealthStats() { + } + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_USER_TIME_MS = HealthKeys.BASE_PROCESS + 1; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_SYSTEM_TIME_MS = HealthKeys.BASE_PROCESS + 2; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_STARTS_COUNT = HealthKeys.BASE_PROCESS + 3; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_CRASHES_COUNT = HealthKeys.BASE_PROCESS + 4; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_ANR_COUNT = HealthKeys.BASE_PROCESS + 5; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_FOREGROUND_MS = HealthKeys.BASE_PROCESS + 6; + + /** + * @hide + */ + public static final HealthKeys.Constants CONSTANTS = new HealthKeys.Constants(ProcessHealthStats.class); +} diff --git a/core/java/android/os/health/ServiceHealthStats.java b/core/java/android/os/health/ServiceHealthStats.java new file mode 100644 index 000000000000..802ad31894b3 --- /dev/null +++ b/core/java/android/os/health/ServiceHealthStats.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 android.os.health; + +/** + * Keys for {@link HealthStats} returned from + * {@link HealthStats#getStats(int) HealthStats.getStats(int)} with the + * {@link PackageHealthStats#STATS_SERVICES PackageHealthStats.STATS_SERVICES} key. + */ +public final class ServiceHealthStats { + + private ServiceHealthStats() { + } + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_START_SERVICE_COUNT = HealthKeys.BASE_SERVICE + 1; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_LAUNCH_COUNT = HealthKeys.BASE_SERVICE + 2; + + /** + * @hide + */ + public static final HealthKeys.Constants CONSTANTS + = new HealthKeys.Constants(ServiceHealthStats.class); +} diff --git a/core/java/android/os/health/SystemHealthManager.java b/core/java/android/os/health/SystemHealthManager.java new file mode 100644 index 000000000000..520e84e0266a --- /dev/null +++ b/core/java/android/os/health/SystemHealthManager.java @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.os.health; + +import android.content.Context; +import android.os.BatteryStats; +import android.os.Process; +import android.os.RemoteException; +import android.os.ServiceManager; + +import com.android.internal.app.IBatteryStats; + +/** + * Provides access to data about how various system resources are used by applications. + * @more + * <b>Battery Usage</b><br> + * The statistics related to power (battery) usage are recorded since the device + * was last unplugged. It is expected that applications schedule more work to do + * while the device is plugged in (e.g. using {@link android.app.job.JobScheduler + * JobScheduler}), and while that can affect charging rates, it is still preferable + * to actually draining the battery. + */ +public class SystemHealthManager { + private final IBatteryStats mBatteryStats; + + /** + * Construct a new SystemHealthManager object. + * @hide + */ + public SystemHealthManager() { + mBatteryStats = IBatteryStats.Stub.asInterface( + ServiceManager.getService(BatteryStats.SERVICE_NAME)); + } + + /** + * Obtain a SystemHealthManager object for the supplied context. + */ + public static SystemHealthManager from(Context context) { + return (SystemHealthManager)context.getSystemService(Context.SYSTEM_HEALTH_SERVICE); + } + + /** + * Return a {@link HealthStats} object containing a snapshot of system health + * metrics for the given uid (user-id, which in usually corresponds to application). + * @more + * + * An application must hold the {@link android.Manifest.permission#BATTERY_STATS + * android.permission.BATTERY_STATS} permission in order to retrieve any HealthStats + * other than its own. + * + * @param uid User ID for a given application. + * @return A {@link HealthStats} object containing the metrics for the requested + * application. The keys for this HealthStats object will be from the {@link UidHealthStats} + * class. + * @see Process#myUid() + */ + public HealthStats takeUidSnapshot(int uid) { + try { + final HealthStatsParceler parceler = mBatteryStats.takeUidSnapshot(uid); + return parceler.getHealthStats(); + } catch (RemoteException ex) { + throw new RuntimeException(ex); + } + } + + /** + * Return a {@link HealthStats} object containing a snapshot of system health + * metrics for the application calling this API. This method is the same as calling + * {@code takeUidSnapshot(Process.myUid())}. + * + * @return A {@link HealthStats} object containing the metrics for this application. The keys + * for this HealthStats object will be from the {@link UidHealthStats} class. + */ + public HealthStats takeMyUidSnapshot() { + return takeUidSnapshot(Process.myUid()); + } + + /** + * Return a {@link HealthStats} object containing a snapshot of system health + * metrics for the given uids (user-id, which in usually corresponds to application). + * @more + * + * An application must hold the {@link android.Manifest.permission#BATTERY_STATS + * android.permission.BATTERY_STATS} permission in order to retrieve any HealthStats + * other than its own. + * + * @param uids An array of User IDs to retrieve. + * @return An array of {@link HealthStats} objects containing the metrics for each of + * the requested uids. The keys for this HealthStats object will be from the + * {@link UidHealthStats} class. + */ + public HealthStats[] takeUidSnapshots(int[] uids) { + try { + final HealthStatsParceler[] parcelers = mBatteryStats.takeUidSnapshots(uids); + final HealthStats[] results = new HealthStats[uids.length]; + final int N = uids.length; + for (int i=0; i<N; i++) { + results[i] = parcelers[i].getHealthStats(); + } + return results; + } catch (RemoteException ex) { + throw new RuntimeException(ex); + } + } + +} + diff --git a/core/java/android/os/health/TimerStat.java b/core/java/android/os/health/TimerStat.java new file mode 100644 index 000000000000..fc51b60ff531 --- /dev/null +++ b/core/java/android/os/health/TimerStat.java @@ -0,0 +1,116 @@ +/* + * 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.os.health; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A TimerStat object stores a count and a time. + * + * @more + * When possible, the other APIs in this package avoid requiring a TimerStat + * object to be constructed, even internally, but the getTimers method on + * {@link android.os.health.HealthStats} does require TimerStat objects. + */ +public class TimerStat implements Parcelable { + private int mCount; + private long mTime; + + /** + * The CREATOR instance for use by aidl Binder interfaces. + */ + public static final Parcelable.Creator<TimerStat> CREATOR + = new Parcelable.Creator<TimerStat>() { + public TimerStat createFromParcel(Parcel in) { + return new TimerStat(in); + } + + public TimerStat[] newArray(int size) { + return new TimerStat[size]; + } + }; + + /** + * Construct an empty TimerStat object with the count and time set to 0. + */ + public TimerStat() { + } + + /** + * Construct a TimerStat object with the supplied count and time fields. + * + * @param count The count + * @param time The time + */ + public TimerStat(int count, long time) { + mCount = count; + mTime = time; + } + + /** + * Construct a TimerStat object reading the values from a {@link android.os.Parcel Parcel} + * object. + */ + public TimerStat(Parcel in) { + mCount = in.readInt(); + mTime = in.readLong(); + } + + /** + * @inheritDoc + */ + public int describeContents() { + return 0; + } + + /** + * Write this TimerStat object to a parcel. + */ + public void writeToParcel(Parcel out, int flags) { + out.writeInt(mCount); + out.writeLong(mTime); + } + + /** + * Set the count for this timer. + */ + public void setCount(int count) { + mCount = count; + } + + /** + * Get the count for this timer. + */ + public int getCount() { + return mCount; + } + + /** + * Set the time for this timer. + */ + public void setTime(long time) { + mTime = time; + } + + /** + * Get the time for this timer. + */ + public long getTime() { + return mTime; + } +} diff --git a/core/java/android/os/health/UidHealthStats.java b/core/java/android/os/health/UidHealthStats.java new file mode 100644 index 000000000000..c7d257fcaa42 --- /dev/null +++ b/core/java/android/os/health/UidHealthStats.java @@ -0,0 +1,280 @@ +/* + * 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.os.health; + +/** + * Keys for {@link HealthStats} returned from + * {@link SystemHealthManager#takeUidSnapshot(int) SystemHealthManager.takeUidSnapshot(int)}, + * {@link SystemHealthManager#takeMyUidSnapshot() SystemHealthManager.takeMyUidSnapshot()}, and + * {@link SystemHealthManager#takeUidSnapshots(int[]) SystemHealthManager.takeUidSnapshots(int[])}. + */ +public final class UidHealthStats { + + private UidHealthStats() { + } + + /** + * How many milliseconds this statistics report covers in wall-clock time while the + * device was on battery including both screen-on and screen-off time. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_REALTIME_BATTERY_MS = HealthKeys.BASE_UID + 1; + + /** + * How many milliseconds this statistics report covers that the CPU was running while the + * device was on battery including both screen-on and screen-off time. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_UPTIME_BATTERY_MS = HealthKeys.BASE_UID + 2; + + /** + * How many milliseconds this statistics report covers in wall-clock time while the + * device was on battery including both screen-on and screen-off time. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS = HealthKeys.BASE_UID + 3; + + /** + * How many milliseconds this statistics report covers that the CPU was running while the + * device was on battery including both screen-on and screen-off time. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS = HealthKeys.BASE_UID + 4; + + /** + * Key for a TimerStat for the times a + * {@link android.os.PowerManager#FULL_WAKE_LOCK full wake lock} + * was acquired for this uid. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMERS) + public static final int TIMERS_WAKELOCKS_FULL = HealthKeys.BASE_UID + 5; + + /** + * Key for a TimerStat for the times a + * {@link android.os.PowerManager#PARTIAL_WAKE_LOCK full wake lock} + * was acquired for this uid. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMERS) + public static final int TIMERS_WAKELOCKS_PARTIAL = HealthKeys.BASE_UID + 6; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMERS) + public static final int TIMERS_WAKELOCKS_WINDOW = HealthKeys.BASE_UID + 7; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMERS) + public static final int TIMERS_WAKELOCKS_DRAW = HealthKeys.BASE_UID + 8; + + /** + * Key for a map of Timers for the sync adapter syncs that were done for + * this uid. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMERS) + public static final int TIMERS_SYNCS = HealthKeys.BASE_UID + 9; + + /** + * Key for a map of Timers for the {@link android.app.job.JobScheduler} jobs for + * this uid. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMERS) + public static final int TIMERS_JOBS = HealthKeys.BASE_UID + 10; + + /** + * Key for a timer for the applications use of the GPS sensor. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_GPS_SENSOR = HealthKeys.BASE_UID + 11; + + /** + * Key for a map of the sensor usage for this uid. The keys are a + * string representation of the handle for the sensor. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMERS) + public static final int TIMERS_SENSORS = HealthKeys.BASE_UID + 12; + + /** + * Key for a HealthStats with {@link PidHealthStats} keys for each of the + * currently running processes for this uid. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_STATS) + public static final int STATS_PIDS = HealthKeys.BASE_UID + 13; + + /** + * Key for a HealthStats with {@link ProcessHealthStats} keys for each of the + * named processes for this uid. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_STATS) + public static final int STATS_PROCESSES = HealthKeys.BASE_UID + 14; + + /** + * Key for a HealthStats with {@link PackageHealthStats} keys for each of the + * APKs that share this uid. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_STATS) + public static final int STATS_PACKAGES = HealthKeys.BASE_UID + 15; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WIFI_IDLE_MS = HealthKeys.BASE_UID + 16; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WIFI_RX_MS = HealthKeys.BASE_UID + 17; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WIFI_TX_MS = HealthKeys.BASE_UID + 18; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WIFI_POWER_MAMS = HealthKeys.BASE_UID + 19; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_BLUETOOTH_IDLE_MS = HealthKeys.BASE_UID + 20; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_BLUETOOTH_RX_MS = HealthKeys.BASE_UID + 21; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_BLUETOOTH_TX_MS = HealthKeys.BASE_UID + 22; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_BLUETOOTH_POWER_MAMS = HealthKeys.BASE_UID + 23; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_MOBILE_IDLE_MS = HealthKeys.BASE_UID + 24; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_MOBILE_RX_MS = HealthKeys.BASE_UID + 25; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_MOBILE_TX_MS = HealthKeys.BASE_UID + 26; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_MOBILE_POWER_MAMS = HealthKeys.BASE_UID + 27; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WIFI_RUNNING_MS = HealthKeys.BASE_UID + 28; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WIFI_FULL_LOCK_MS = HealthKeys.BASE_UID + 29; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_WIFI_SCAN = HealthKeys.BASE_UID + 30; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WIFI_MULTICAST_MS = HealthKeys.BASE_UID + 31; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_AUDIO = HealthKeys.BASE_UID + 32; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_VIDEO = HealthKeys.BASE_UID + 33; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_FLASHLIGHT = HealthKeys.BASE_UID + 34; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_CAMERA = HealthKeys.BASE_UID + 35; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_FOREGROUND_ACTIVITY = HealthKeys.BASE_UID + 36; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_BLUETOOTH_SCAN = HealthKeys.BASE_UID + 37; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_PROCESS_STATE_TOP_MS = HealthKeys.BASE_UID + 38; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_PROCESS_STATE_FOREGROUND_SERVICE_MS = HealthKeys.BASE_UID + 39; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_PROCESS_STATE_TOP_SLEEPING_MS = HealthKeys.BASE_UID + 40; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_PROCESS_STATE_FOREGROUND_MS = HealthKeys.BASE_UID + 41; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_PROCESS_STATE_BACKGROUND_MS = HealthKeys.BASE_UID + 42; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_PROCESS_STATE_CACHED_MS = HealthKeys.BASE_UID + 43; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_VIBRATOR = HealthKeys.BASE_UID + 44; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_OTHER_USER_ACTIVITY_COUNT = HealthKeys.BASE_UID + 45; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT = HealthKeys.BASE_UID + 46; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT = HealthKeys.BASE_UID + 47; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_MOBILE_RX_BYTES = HealthKeys.BASE_UID + 48; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_MOBILE_TX_BYTES = HealthKeys.BASE_UID + 49; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WIFI_RX_BYTES = HealthKeys.BASE_UID + 50; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WIFI_TX_BYTES = HealthKeys.BASE_UID + 51; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_BLUETOOTH_RX_BYTES = HealthKeys.BASE_UID + 52; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_BLUETOOTH_TX_BYTES = HealthKeys.BASE_UID + 53; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_MOBILE_RX_PACKETS = HealthKeys.BASE_UID + 54; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_MOBILE_TX_PACKETS = HealthKeys.BASE_UID + 55; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WIFI_RX_PACKETS = HealthKeys.BASE_UID + 56; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_WIFI_TX_PACKETS = HealthKeys.BASE_UID + 57; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_BLUETOOTH_RX_PACKETS = HealthKeys.BASE_UID + 58; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_BLUETOOTH_TX_PACKETS = HealthKeys.BASE_UID + 59; + + @HealthKeys.Constant(type=HealthKeys.TYPE_TIMER) + public static final int TIMER_MOBILE_RADIO_ACTIVE = HealthKeys.BASE_UID + 61; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_USER_CPU_TIME_US = HealthKeys.BASE_UID + 62; + + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_SYSTEM_CPU_TIME_US = HealthKeys.BASE_UID + 63; + + /** + * An estimate of the number of milliamp-microsends used by this uid. + */ + @HealthKeys.Constant(type=HealthKeys.TYPE_MEASUREMENT) + public static final int MEASUREMENT_CPU_POWER_MAUS = HealthKeys.BASE_UID + 64; + + /** + * @hide + */ + public static final HealthKeys.Constants CONSTANTS = new HealthKeys.Constants(UidHealthStats.class); +} + diff --git a/core/java/android/os/health/package.html b/core/java/android/os/health/package.html new file mode 100644 index 000000000000..3a46a5ba9cc4 --- /dev/null +++ b/core/java/android/os/health/package.html @@ -0,0 +1,39 @@ +<html> +<body> + +The android.os.health package contains a set of classes to provide data +to track the system resources of applications. +<p> +Applications running in the background are responsible for a significant amount +of battery usage on a typical android device. There are several things that +applications can do in order to reduce their impact. For example, by using +{@link android.app.job.JobScheduler JobScheduler}, an application does not need +to independently monitor whether the network is available, whether the device is +plugged in, etc. In addition to being simpler to use, the application's +services are only started when the required conditions have been met. But even +when using the appropriate helper APIs, applications still can reduce their +footprint. This package provides more insight into what is going on behind the +scenes when an application is running. +<p> +Application data is tracked by which user id (uid) is using particular +resources. A snapshot of an application's measurements can be taken with the +{@link android.os.health.SystemHealthManager#takeMyUidSnapshot() SystemHealth.takeMyUidSnapshot()} +method. The {@link android.os.health.HealthStats} object returned contains the +statistics. +<p> +<b>HealthStats</b><br> +In order to be returned efficiently, the {@link android.os.health.HealthStats} +class uses a set of int keys to identify the data returned. The +{@link android.os.health.UidHealthStats}, {@link android.os.health.PidHealthStats}, +{@link android.os.health.PackageHealthStats} , {@link android.os.health.ProcessHealthStats}, +and {@link android.os.health.ServiceHealthStats} classes provide those constants. +Each {@link android.os.health.HealthStats} object will be associated with +exactly one of those classes. The object returned from +{@link android.os.health.SystemHealthManager#takeMyUidSnapshot() SystemHealth.takeMyUidSnapshot()} +will be using the {@link android.os.health.UidHealthStats} keys, as it contains all +of the data available for that uid. + + +</body> +</html> + diff --git a/core/java/android/os/storage/IMountService.java b/core/java/android/os/storage/IMountService.java index fc440d2b446b..c21c65a706a3 100644 --- a/core/java/android/os/storage/IMountService.java +++ b/core/java/android/os/storage/IMountService.java @@ -2286,7 +2286,12 @@ public interface IMountService extends IInterface { /** * Determines the encryption state of the volume. - * @return a numerical value. See {@code ENCRYPTION_STATE_*} for possible values. + * @return a numerical value. See {@code ENCRYPTION_STATE_*} for possible + * values. + * Note that this has been replaced in most cases by the APIs in + * StorageManager (see isEncryptable and below) + * This is still useful to get the error state when encryption has failed + * and CryptKeeper needs to throw up a screen advising the user what to do */ public int getEncryptionState() throws RemoteException; diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java index 17df7080acf1..61e6b95cf89f 100644 --- a/core/java/android/os/storage/StorageManager.java +++ b/core/java/android/os/storage/StorageManager.java @@ -1025,21 +1025,119 @@ public class StorageManager { } } - /** {@hide} */ - public static boolean isFileBasedEncryptionEnabled() { - return isNativeFileBasedEncryptionEnabled() || isEmulatedFileBasedEncryptionEnabled(); + /** {@hide} + * Is this device encryptable or already encrypted? + * @return true for encryptable or encrypted + * false not encrypted and not encryptable + */ + public static boolean isEncryptable() { + final String state = SystemProperties.get("ro.crypto.state", "unsupported"); + return !"unsupported".equalsIgnoreCase(state); } - /** {@hide} */ - public static boolean isNativeFileBasedEncryptionEnabled() { - return "file".equals(SystemProperties.get("ro.crypto.type", "none")); + /** {@hide} + * Is this device already encrypted? + * @return true for encrypted. (Implies isEncryptable() == true) + * false not encrypted + */ + public static boolean isEncrypted() { + final String state = SystemProperties.get("ro.crypto.state", ""); + return "encrypted".equalsIgnoreCase(state); + } + + /** {@hide} + * Is this device file encrypted? + * @return true for file encrypted. (Implies isEncrypted() == true) + * false not encrypted or block encrypted + */ + public static boolean isFileEncryptedNativeOnly() { + if (!isEncrypted()) { + return false; + } + + final String status = SystemProperties.get("ro.crypto.type", ""); + return "file".equalsIgnoreCase(status); + } + + /** {@hide} + * Is this device block encrypted? + * @return true for block encrypted. (Implies isEncrypted() == true) + * false not encrypted or file encrypted + */ + public static boolean isBlockEncrypted() { + if (!isEncrypted()) { + return false; + } + final String status = SystemProperties.get("ro.crypto.type", ""); + return "block".equalsIgnoreCase(status); + } + + /** {@hide} + * Is this device block encrypted with credentials? + * @return true for crediential block encrypted. + * (Implies isBlockEncrypted() == true) + * false not encrypted, file encrypted or default block encrypted + */ + public static boolean isNonDefaultBlockEncrypted() { + if (!isBlockEncrypted()) { + return false; + } + + try { + IMountService mountService = IMountService.Stub.asInterface( + ServiceManager.getService("mount")); + return mountService.getPasswordType() != CRYPT_TYPE_DEFAULT; + } catch (RemoteException e) { + Log.e(TAG, "Error getting encryption type"); + return false; + } + } + + /** {@hide} + * Is this device in the process of being block encrypted? + * @return true for encrypting. + * false otherwise + * Whether device isEncrypted at this point is undefined + * Note that only system services and CryptKeeper will ever see this return + * true - no app will ever be launched in this state. + * Also note that this state will not change without a teardown of the + * framework, so no service needs to check for changes during their lifespan + */ + public static boolean isBlockEncrypting() { + final String state = SystemProperties.get("vold.encrypt_progress", ""); + return !"".equalsIgnoreCase(state); + } + + /** {@hide} + * Is this device non default block encrypted and in the process of + * prompting for credentials? + * @return true for prompting for credentials. + * (Implies isNonDefaultBlockEncrypted() == true) + * false otherwise + * Note that only system services and CryptKeeper will ever see this return + * true - no app will ever be launched in this state. + * Also note that this state will not change without a teardown of the + * framework, so no service needs to check for changes during their lifespan + */ + public static boolean inCryptKeeperBounce() { + final String status = SystemProperties.get("vold.decrypt"); + return "trigger_restart_min_framework".equals(status); } /** {@hide} */ - public static boolean isEmulatedFileBasedEncryptionEnabled() { + public static boolean isFileEncryptedEmulatedOnly() { return SystemProperties.getBoolean(StorageManager.PROP_EMULATE_FBE, false); } + /** {@hide} + * Is this device running in a file encrypted mode, either native or emulated? + * @return true for file encrypted, false otherwise + */ + public static boolean isFileEncryptedNativeOrEmulated() { + return isFileEncryptedNativeOnly() + || isFileEncryptedEmulatedOnly(); + } + /** {@hide} */ public static File maybeTranslateEmulatedPathToInternal(File path) { final IMountService mountService = IMountService.Stub.asInterface( diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 4b43f53ebefe..3658df9a8443 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -5185,6 +5185,10 @@ public final class ContactsContract { * <li> * Corp contacts will get artificial {@link #LOOKUP_KEY}s too. * </li> + * <li> + * Returned work contact IDs and lookup keys are not accepted in places that not + * explicitly say to accept them. + * </li> * </ul> * <p> * A contact lookup URL built by @@ -6194,6 +6198,10 @@ public final class ContactsContract { * <li> * Corp contacts will get artificial {@link #LOOKUP_KEY}s too. * </li> + * <li> + * Returned work contact IDs and lookup keys are not accepted in places that not + * explicitly say to accept them. + * </li> * </ul> * <p> * A contact lookup URL built by @@ -8466,7 +8474,9 @@ public final class ContactsContract { * around this {@link View}. * @param lookupUri A {@link ContactsContract.Contacts#CONTENT_LOOKUP_URI} style * {@link Uri} that describes a specific contact to feature - * in this dialog. + * in this dialog. A work lookup uri is supported here, + * see {@link CommonDataKinds.Email#ENTERPRISE_CONTENT_LOOKUP_URI} and + * {@link PhoneLookup#ENTERPRISE_CONTENT_FILTER_URI}. * @param mode Any of {@link #MODE_SMALL}, {@link #MODE_MEDIUM}, or * {@link #MODE_LARGE}, indicating the desired dialog size, * when supported. @@ -8500,7 +8510,9 @@ public final class ContactsContract { * @param lookupUri A * {@link ContactsContract.Contacts#CONTENT_LOOKUP_URI} style * {@link Uri} that describes a specific contact to feature - * in this dialog. + * in this dialog. A work lookup uri is supported here, + * see {@link CommonDataKinds.Email#ENTERPRISE_CONTENT_LOOKUP_URI} and + * {@link PhoneLookup#ENTERPRISE_CONTENT_FILTER_URI}. * @param mode Any of {@link #MODE_SMALL}, {@link #MODE_MEDIUM}, or * {@link #MODE_LARGE}, indicating the desired dialog size, * when supported. @@ -8531,7 +8543,9 @@ public final class ContactsContract { * @param lookupUri A * {@link ContactsContract.Contacts#CONTENT_LOOKUP_URI} style * {@link Uri} that describes a specific contact to feature - * in this dialog. + * in this dialog. A work lookup uri is supported here, + * see {@link CommonDataKinds.Email#ENTERPRISE_CONTENT_LOOKUP_URI} and + * {@link PhoneLookup#ENTERPRISE_CONTENT_FILTER_URI}. * @param excludeMimes Optional list of {@link Data#MIMETYPE} MIME-types * to exclude when showing this dialog. For example, when * already viewing the contact details card, this can be used @@ -8569,7 +8583,9 @@ public final class ContactsContract { * @param lookupUri A * {@link ContactsContract.Contacts#CONTENT_LOOKUP_URI} style * {@link Uri} that describes a specific contact to feature - * in this dialog. + * in this dialog. A work lookup uri is supported here, + * see {@link CommonDataKinds.Email#ENTERPRISE_CONTENT_LOOKUP_URI} and + * {@link PhoneLookup#ENTERPRISE_CONTENT_FILTER_URI}. * @param excludeMimes Optional list of {@link Data#MIMETYPE} MIME-types * to exclude when showing this dialog. For example, when * already viewing the contact details card, this can be used diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java index 0065cd961eb2..e7a9b7d87fdd 100644 --- a/core/java/android/provider/DocumentsContract.java +++ b/core/java/android/provider/DocumentsContract.java @@ -119,8 +119,6 @@ public final class DocumentsContract { public static final String EXTRA_PROMPT = "android.provider.extra.PROMPT"; /** {@hide} */ - public static final String ACTION_MANAGE_ROOT = "android.provider.action.MANAGE_ROOT"; - /** {@hide} */ public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT"; /** {@hide} */ @@ -383,18 +381,6 @@ public final class DocumentsContract { */ public static final int FLAG_ARCHIVE = 1 << 15; - /** - * Flag indicating that document titles should be hidden when viewing - * this directory in a larger format grid. For example, a directory - * containing only images may want the image thumbnails to speak for - * themselves. Only valid when {@link #COLUMN_MIME_TYPE} is - * {@link #MIME_TYPE_DIR}. - * - * @see #COLUMN_FLAGS - * @see #FLAG_DIR_PREFERS_GRID - * @hide - */ - public static final int FLAG_DIR_HIDE_GRID_TITLES = 1 << 16; } /** diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java index d43ff4e04bcb..d4ff766c6063 100755 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -7786,6 +7786,31 @@ public final class Settings { public static final String ALARM_MANAGER_CONSTANTS = "alarm_manager_constants"; /** + * ShortcutManager specific settings. + * This is encoded as a key=value list, separated by commas. Ex: + * + * "reset_interval_sec=86400,max_daily_updates=5" + * + * The following keys are supported: + * + * <pre> + * reset_interval_sec (long) + * max_daily_updates (int) + * max_icon_dimension_dp (int, DP) + * max_icon_dimension_dp_lowram (int, DP) + * max_shortcuts (int) + * icon_quality (int, 0-100) + * icon_format (String) + * </pre> + * + * <p> + * Type: string + * @hide + * @see com.android.server.pm.ShortcutService.ConfigConstants + */ + public static final String SHORTCUT_MANAGER_CONSTANTS = "shortcut_manager_constants"; + + /** * Get the key that retrieves a bluetooth headset's priority. * @hide */ diff --git a/core/java/android/security/net/config/XmlConfigSource.java b/core/java/android/security/net/config/XmlConfigSource.java index 2a8773cd3d86..d57d0f561181 100644 --- a/core/java/android/security/net/config/XmlConfigSource.java +++ b/core/java/android/security/net/config/XmlConfigSource.java @@ -339,7 +339,7 @@ public class XmlConfigSource implements ConfigSource { } if (mDebugBuild) { debugConfigBuilder = - parseConfigEntry(parser, seenDomains, null, CONFIG_DEBUG).get(0).first; + parseConfigEntry(parser, null, null, CONFIG_DEBUG).get(0).first; } else { XmlUtils.skipCurrentTag(parser); } @@ -348,6 +348,11 @@ public class XmlConfigSource implements ConfigSource { XmlUtils.skipCurrentTag(parser); } } + // If debug is true and there was no debug-overrides in the file check for an extra + // _debug resource. + if (mDebugBuild && debugConfigBuilder == null) { + debugConfigBuilder = parseDebugOverridesResource(); + } // Use the platform default as the parent of the base config for any values not provided // there. If there is no base config use the platform default. @@ -385,6 +390,43 @@ public class XmlConfigSource implements ConfigSource { mDomainMap = configs; } + private NetworkSecurityConfig.Builder parseDebugOverridesResource() + throws IOException, XmlPullParserException, ParserException { + Resources resources = mContext.getResources(); + String packageName = resources.getResourcePackageName(mResourceId); + String entryName = resources.getResourceEntryName(mResourceId); + int resId = resources.getIdentifier(entryName + "_debug", "xml", packageName); + // No debug-overrides resource was found, nothing to parse. + if (resId == 0) { + return null; + } + NetworkSecurityConfig.Builder debugConfigBuilder = null; + // Parse debug-overrides out of the _debug resource. + try (XmlResourceParser parser = resources.getXml(resId)) { + XmlUtils.beginDocument(parser, "network-security-config"); + int outerDepth = parser.getDepth(); + boolean seenDebugOverrides = false; + while (XmlUtils.nextElementWithin(parser, outerDepth)) { + if ("debug-overrides".equals(parser.getName())) { + if (seenDebugOverrides) { + throw new ParserException(parser, "Only one debug-overrides allowed"); + } + if (mDebugBuild) { + debugConfigBuilder = + parseConfigEntry(parser, null, null, CONFIG_DEBUG).get(0).first; + } else { + XmlUtils.skipCurrentTag(parser); + } + seenDebugOverrides = true; + } else { + XmlUtils.skipCurrentTag(parser); + } + } + } + + return debugConfigBuilder; + } + public static class ParserException extends Exception { public ParserException(XmlPullParser parser, String message, Throwable cause) { diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java index a8b8da102e36..afdd1d43c35f 100644 --- a/core/java/android/service/notification/NotificationListenerService.java +++ b/core/java/android/service/notification/NotificationListenerService.java @@ -680,18 +680,12 @@ public abstract class NotificationListenerService extends Service { @SystemApi public void registerAsSystemService(Context context, ComponentName componentName, int currentUser) throws RemoteException { - registerAsSystemServiceImpl(context, componentName, currentUser, false /* asRanker */); - } - - /** @hide */ - protected void registerAsSystemServiceImpl(Context context, ComponentName componentName, - int currentUser, boolean asRanker) throws RemoteException { - mSystemContext = context; if (mWrapper == null) { mWrapper = new NotificationListenerWrapper(); } + mSystemContext = context; INotificationManager noMan = getNotificationInterface(); - noMan.registerListener(mWrapper, componentName, currentUser, asRanker); + noMan.registerListener(mWrapper, componentName, currentUser); mCurrentUser = currentUser; mHandler = new MyHandler(context.getMainLooper()); } diff --git a/core/java/android/service/notification/NotificationRankerService.java b/core/java/android/service/notification/NotificationRankerService.java index 520b4c225dfd..47fdac6bf4c2 100644 --- a/core/java/android/service/notification/NotificationRankerService.java +++ b/core/java/android/service/notification/NotificationRankerService.java @@ -37,7 +37,7 @@ import com.android.internal.os.SomeArgs; */ @SystemApi public abstract class NotificationRankerService extends NotificationListenerService { - private static final String TAG = "NotificationRanker"; + private static final String TAG = "NotificationRankers"; /** * The {@link Intent} that must be declared as handled by the service. @@ -118,9 +118,14 @@ public abstract class NotificationRankerService extends NotificationListenerServ /** @hide */ @Override public void registerAsSystemService(Context context, ComponentName componentName, - int currentUser) throws RemoteException { - registerAsSystemServiceImpl(context, componentName, currentUser, true /* as Ranker */); - mHandler = new MyHandler(getContext().getMainLooper()); + int currentUser) { + throw new UnsupportedOperationException("the ranker lifecycle is managed by the system."); + } + + /** @hide */ + @Override + public void unregisterAsSystemService() { + throw new UnsupportedOperationException("the ranker lifecycle is managed by the system."); } @Override 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/transition/ArcMotion.java b/core/java/android/transition/ArcMotion.java index fa4c8d29897d..70443ba90f45 100644 --- a/core/java/android/transition/ArcMotion.java +++ b/core/java/android/transition/ArcMotion.java @@ -15,13 +15,13 @@ */ package android.transition; -import com.android.internal.R; - import android.content.Context; import android.content.res.TypedArray; import android.graphics.Path; import android.util.AttributeSet; +import com.android.internal.R; + /** * A PathMotion that generates a curved path along an arc on an imaginary circle containing * the two points. If the horizontal distance between the points is less than the vertical @@ -207,7 +207,7 @@ public class ArcMotion extends PathMotion { ey = (startY + endY) / 2; } else { float deltaX = endX - startX; - float deltaY = startY - endY; // Y is inverted compared to diagram above. + float deltaY = endY - startY; // hypotenuse squared. float h2 = deltaX * deltaX + deltaY * deltaY; @@ -219,24 +219,35 @@ public class ArcMotion extends PathMotion { float midDist2 = h2 * 0.25f; float minimumArcDist2 = 0; + boolean isQuadrant1Or3 = (deltaX * deltaY) > 0; - if (Math.abs(deltaX) < Math.abs(deltaY)) { + if ((Math.abs(deltaX) < Math.abs(deltaY))) { // Similar triangles bfa and bde mean that (ab/fb = eb/bd) // Therefore, eb = ab * bd / fb // ab = hypotenuse // bd = hypotenuse/2 // fb = deltaY float eDistY = h2 / (2 * deltaY); - ey = endY + eDistY; - ex = endX; + if (isQuadrant1Or3) { + ey = startY + eDistY; + ex = startX; + } else { + ey = endY - eDistY; + ex = endX; + } minimumArcDist2 = midDist2 * mMinimumVerticalTangent * mMinimumVerticalTangent; } else { // Same as above, but flip X & Y float eDistX = h2 / (2 * deltaX); - ex = endX + eDistX; - ey = endY; + if (isQuadrant1Or3) { + ex = endX - eDistX; + ey = endY; + } else { + ex = startX + eDistX; + ey = startY; + } minimumArcDist2 = midDist2 * mMinimumHorizontalTangent * mMinimumHorizontalTangent; 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/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl index 804830101ffb..f912e51b5bfb 100644 --- a/core/java/android/view/IWindowManager.aidl +++ b/core/java/android/view/IWindowManager.aidl @@ -363,6 +363,12 @@ interface IWindowManager void setDockedStackResizing(boolean resizing); /** + * Sets the region the user can touch the divider. This region will be excluded from the region + * which is used to cause a focus switch when dispatching touch. + */ + void setDockedStackDividerTouchRegion(in Rect touchableRegion); + + /** * Registers a listener that will be called when the dock divider changes its visibility or when * the docked stack gets added/removed. */ 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 c54ce80631bd..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: { @@ -5357,9 +5364,6 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager void offsetRectBetweenParentAndChild(View descendant, Rect rect, boolean offsetFromChildToParent, boolean clipToBounds) { - final RectF rectF = mAttachInfo != null ? mAttachInfo.mTmpTransformRect1 : new RectF(); - final Matrix inverse = mAttachInfo != null ? mAttachInfo.mTmpMatrix : new Matrix(); - // already in the same coord system :) if (descendant == this) { return; @@ -5373,16 +5377,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager && (theParent != this)) { if (offsetFromChildToParent) { - rect.offset(-descendant.mScrollX, -descendant.mScrollY); - - if (!descendant.hasIdentityMatrix()) { - rectF.set(rect); - descendant.getMatrix().mapRect(rectF); - rectF.roundOut(rect); - } - - rect.offset(descendant.mLeft, descendant.mTop); - + rect.offset(descendant.mLeft - descendant.mScrollX, + descendant.mTop - descendant.mScrollY); if (clipToBounds) { View p = (View) theParent; boolean intersected = rect.intersect(0, 0, p.mRight - p.mLeft, @@ -5400,16 +5396,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager rect.setEmpty(); } } - rect.offset(-descendant.mLeft, -descendant.mTop); - - if (!descendant.hasIdentityMatrix()) { - descendant.getMatrix().invert(inverse); - rectF.set(rect); - inverse.mapRect(rectF); - rectF.roundOut(rect); - } - - rect.offset(descendant.mScrollX, descendant.mScrollY); + rect.offset(descendant.mScrollX - descendant.mLeft, + descendant.mScrollY - descendant.mTop); } descendant = (View) theParent; @@ -5420,26 +5408,11 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager // to get into our coordinate space if (theParent == this) { if (offsetFromChildToParent) { - rect.offset(-descendant.mScrollX, -descendant.mScrollY); - - if (!descendant.hasIdentityMatrix()) { - rectF.set(rect); - descendant.getMatrix().mapRect(rectF); - rectF.roundOut(rect); - } - - rect.offset(descendant.mLeft, descendant.mTop); + rect.offset(descendant.mLeft - descendant.mScrollX, + descendant.mTop - descendant.mScrollY); } else { - rect.offset(-descendant.mLeft, -descendant.mTop); - - if (!descendant.hasIdentityMatrix()) { - descendant.getMatrix().invert(inverse); - rectF.set(rect); - inverse.mapRect(rectF); - rectF.roundOut(rect); - } - - rect.offset(descendant.mScrollX, descendant.mScrollY); + rect.offset(descendant.mScrollX - descendant.mLeft, + descendant.mScrollY - descendant.mTop); } } else { throw new IllegalArgumentException("parameter must be a descendant of this view"); diff --git a/core/java/android/view/ViewGroupOverlay.java b/core/java/android/view/ViewGroupOverlay.java index 16afc5df31ae..c2807babdff2 100644 --- a/core/java/android/view/ViewGroupOverlay.java +++ b/core/java/android/view/ViewGroupOverlay.java @@ -15,6 +15,7 @@ */ package android.view; +import android.annotation.NonNull; import android.content.Context; import android.graphics.drawable.Drawable; @@ -37,7 +38,7 @@ public class ViewGroupOverlay extends ViewOverlay { } /** - * Adds a View to the overlay. The bounds of the added view should be + * Adds a {@code View} to the overlay. The bounds of the added view should be * relative to the host view. Any view added to the overlay should be * removed when it is no longer needed or no longer visible. * @@ -54,23 +55,32 @@ public class ViewGroupOverlay extends ViewOverlay { * and 200 pixels down from the origin of the overlay's * host view, then the view will be offset by (100, 200).</p> * - * @param view The View to be added to the overlay. The added view will be + * <p>{@code View}s added with this API will be drawn in the order they were + * added. Drawing of the overlay views will happen before drawing of any of the + * {@code Drawable}s added with {@link #add(Drawable)} API even if a call to + * this API happened after the call to {@link #add(Drawable)}.</p> + * + * <p>Passing <code>null</code> parameter will result in an + * {@link IllegalArgumentException} being thrown.</p> + * + * @param view The {@code View} to be added to the overlay. The added view will be * drawn when the overlay is drawn. * @see #remove(View) * @see ViewOverlay#add(Drawable) */ - public void add(View view) { + public void add(@NonNull View view) { mOverlayViewGroup.add(view); } /** - * Removes the specified View from the overlay. + * Removes the specified {@code View} from the overlay. Passing <code>null</code> parameter + * will result in an {@link IllegalArgumentException} being thrown. * - * @param view The View to be removed from the overlay. + * @param view The {@code View} to be removed from the overlay. * @see #add(View) * @see ViewOverlay#remove(Drawable) */ - public void remove(View view) { + public void remove(@NonNull View view) { mOverlayViewGroup.remove(view); } } diff --git a/core/java/android/view/ViewOverlay.java b/core/java/android/view/ViewOverlay.java index 5e5ef299a799..69c30bac723a 100644 --- a/core/java/android/view/ViewOverlay.java +++ b/core/java/android/view/ViewOverlay.java @@ -16,6 +16,7 @@ package android.view; import android.animation.LayoutTransition; +import android.annotation.NonNull; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; @@ -59,25 +60,30 @@ public class ViewOverlay { } /** - * Adds a Drawable to the overlay. The bounds of the drawable should be relative to + * Adds a {@link Drawable} to the overlay. The bounds of the drawable should be relative to * the host view. Any drawable added to the overlay should be removed when it is no longer - * needed or no longer visible. + * needed or no longer visible. Adding an already existing {@link Drawable} + * is a no-op. Passing <code>null</code> parameter will result in an + * {@link IllegalArgumentException} being thrown. * - * @param drawable The Drawable to be added to the overlay. This drawable will be - * drawn when the view redraws its overlay. + * @param drawable The {@link Drawable} to be added to the overlay. This drawable will be + * drawn when the view redraws its overlay. {@link Drawable}s will be drawn in the order that + * they were added. * @see #remove(Drawable) */ - public void add(Drawable drawable) { + public void add(@NonNull Drawable drawable) { mOverlayViewGroup.add(drawable); } /** - * Removes the specified Drawable from the overlay. + * Removes the specified {@link Drawable} from the overlay. Removing a {@link Drawable} that was + * not added with {@link #add(Drawable)} is a no-op. Passing <code>null</code> parameter will + * result in an {@link IllegalArgumentException} being thrown. * - * @param drawable The Drawable to be removed from the overlay. + * @param drawable The {@link Drawable} to be removed from the overlay. * @see #add(Drawable) */ - public void remove(Drawable drawable) { + public void remove(@NonNull Drawable drawable) { mOverlayViewGroup.remove(drawable); } @@ -119,7 +125,7 @@ public class ViewOverlay { * The View for which this is an overlay. Invalidations of the overlay are redirected to * this host view. */ - View mHostView; + final View mHostView; /** * The set of drawables to draw when the overlay is rendered. @@ -137,10 +143,12 @@ public class ViewOverlay { mRenderNode.setLeftTopRightBottom(0, 0, mRight, mBottom); } - public void add(Drawable drawable) { + public void add(@NonNull Drawable drawable) { + if (drawable == null) { + throw new IllegalArgumentException("drawable must be non-null"); + } if (mDrawables == null) { - - mDrawables = new ArrayList<Drawable>(); + mDrawables = new ArrayList<>(); } if (!mDrawables.contains(drawable)) { // Make each drawable unique in the overlay; can't add it more than once @@ -150,7 +158,10 @@ public class ViewOverlay { } } - public void remove(Drawable drawable) { + public void remove(@NonNull Drawable drawable) { + if (drawable == null) { + throw new IllegalArgumentException("drawable must be non-null"); + } if (mDrawables != null) { mDrawables.remove(drawable); invalidate(drawable.getBounds()); @@ -159,11 +170,15 @@ public class ViewOverlay { } @Override - protected boolean verifyDrawable(Drawable who) { + protected boolean verifyDrawable(@NonNull Drawable who) { return super.verifyDrawable(who) || (mDrawables != null && mDrawables.contains(who)); } - public void add(View child) { + public void add(@NonNull View child) { + if (child == null) { + throw new IllegalArgumentException("view must be non-null"); + } + if (child.getParent() instanceof ViewGroup) { ViewGroup parent = (ViewGroup) child.getParent(); if (parent != mHostView && parent.getParent() != null && @@ -190,7 +205,11 @@ public class ViewOverlay { super.addView(child); } - public void remove(View view) { + public void remove(@NonNull View view) { + if (view == null) { + throw new IllegalArgumentException("view must be non-null"); + } + super.removeView(view); } @@ -210,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/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/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index ad50ff60780e..3d722600abd9 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -262,11 +262,11 @@ public final class WebViewFactory { "For security reasons, WebView is not allowed in privileged processes"); } + StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getProvider()"); try { Class<WebViewFactoryProvider> providerClass = getProviderClass(); - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "providerClass.newInstance()"); try { sProviderInstance = providerClass.getConstructor(WebViewDelegate.class) @@ -278,10 +278,10 @@ public final class WebViewFactory { throw new AndroidRuntimeException(e); } finally { Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); - StrictMode.setThreadPolicy(oldPolicy); } } finally { Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); + StrictMode.setThreadPolicy(oldPolicy); } } } 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/DayPickerPagerAdapter.java b/core/java/android/widget/DayPickerPagerAdapter.java index f5840dc4023a..8ce2f9cb470c 100644 --- a/core/java/android/widget/DayPickerPagerAdapter.java +++ b/core/java/android/widget/DayPickerPagerAdapter.java @@ -282,7 +282,7 @@ class DayPickerPagerAdapter extends PagerAdapter { public CharSequence getPageTitle(int position) { final SimpleMonthView v = mItems.get(position).calendar; if (v != null) { - return v.getTitle(); + return v.getMonthYearLabel(); } return null; } diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java index 406dc2b2baa9..3b6ba3a758a1 100644 --- a/core/java/android/widget/Editor.java +++ b/core/java/android/widget/Editor.java @@ -290,7 +290,6 @@ public class Editor { boolean mIsInsertionActionModeStartPending = false; private final SuggestionHelper mSuggestionHelper = new SuggestionHelper(); - private SuggestionInfo[] mSuggestionInfosInContextMenu; Editor(TextView textView) { mTextView = textView; @@ -926,7 +925,8 @@ public class Editor { } void onLocaleChanged() { - // Will be re-created on demand in getWordIterator with the proper new locale + // Will be re-created on demand in getWordIterator and getWordIteratorWithText with the + // proper new locale mWordIterator = null; mWordIteratorWithText = null; } @@ -2395,17 +2395,22 @@ public class Editor { dragSourceEnd += shift; } - // Delete original selection - mTextView.deleteText_internal(dragSourceStart, dragSourceEnd); - - // Make sure we do not leave two adjacent spaces. - final int prevCharIdx = Math.max(0, dragSourceStart - 1); - final int nextCharIdx = Math.min(mTextView.getText().length(), dragSourceStart + 1); - if (nextCharIdx > prevCharIdx + 1) { - CharSequence t = mTextView.getTransformedText(prevCharIdx, nextCharIdx); - if (Character.isSpaceChar(t.charAt(0)) && Character.isSpaceChar(t.charAt(1))) { - mTextView.deleteText_internal(prevCharIdx, prevCharIdx + 1); + mUndoInputFilter.setForceMerge(true); + try { + // Delete original selection + mTextView.deleteText_internal(dragSourceStart, dragSourceEnd); + + // Make sure we do not leave two adjacent spaces. + final int prevCharIdx = Math.max(0, dragSourceStart - 1); + final int nextCharIdx = Math.min(mTextView.getText().length(), dragSourceStart + 1); + if (nextCharIdx > prevCharIdx + 1) { + CharSequence t = mTextView.getTransformedText(prevCharIdx, nextCharIdx); + if (Character.isSpaceChar(t.charAt(0)) && Character.isSpaceChar(t.charAt(1))) { + mTextView.deleteText_internal(prevCharIdx, prevCharIdx + 1); + } } + } finally { + mUndoInputFilter.setForceMerge(false); } } } @@ -2448,21 +2453,24 @@ public class Editor { } if (shouldOfferToShowSuggestions()) { - if (mSuggestionInfosInContextMenu == null) { - mSuggestionInfosInContextMenu = - new SuggestionInfo[SuggestionSpan.SUGGESTIONS_MAX_SIZE]; - for (int i = 0; i < mSuggestionInfosInContextMenu.length; i++) { - mSuggestionInfosInContextMenu[i] = new SuggestionInfo(); - } + final SuggestionInfo[] suggestionInfoArray = + new SuggestionInfo[SuggestionSpan.SUGGESTIONS_MAX_SIZE]; + for (int i = 0; i < suggestionInfoArray.length; i++) { + suggestionInfoArray[i] = new SuggestionInfo(); } final SubMenu subMenu = menu.addSubMenu(Menu.NONE, Menu.NONE, MENU_ITEM_ORDER_REPLACE, com.android.internal.R.string.replace); - mSuggestionHelper.getSuggestionInfo(mSuggestionInfosInContextMenu); - int i = 0; - for (final SuggestionInfo info : mSuggestionInfosInContextMenu) { - info.mSuggestionEnd = info.mText.length(); - subMenu.add(Menu.NONE, Menu.NONE, i++, info.mText) - .setOnMenuItemClickListener(mOnContextMenuReplaceItemClickListener); + final int numItems = mSuggestionHelper.getSuggestionInfo(suggestionInfoArray); + for (int i = 0; i < numItems; i++) { + final SuggestionInfo info = suggestionInfoArray[i]; + subMenu.add(Menu.NONE, Menu.NONE, i, info.mText) + .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { + @Override + public boolean onMenuItemClick(MenuItem item) { + replaceWithSuggestion(info); + return true; + } + }); } } @@ -2603,27 +2611,6 @@ public class Editor { } }; - private final MenuItem.OnMenuItemClickListener mOnContextMenuReplaceItemClickListener = - new MenuItem.OnMenuItemClickListener() { - @Override - public boolean onMenuItemClick(MenuItem item) { - int index = item.getOrder(); - if (index < 0 || index >= mSuggestionInfosInContextMenu.length) { - clear(); - return false; - } - replaceWithSuggestion(mSuggestionInfosInContextMenu[index]); - clear(); - return true; - } - - private void clear() { - for (final SuggestionInfo info : mSuggestionInfosInContextMenu) { - info.clear(); - } - } - }; - /** * Controls the {@link EasyEditSpan} monitoring when it is added, and when the related * pop-up should be displayed. @@ -5497,6 +5484,9 @@ public class Editor { // rotates the screen during composition. private boolean mHasComposition; + // Whether to merge events into one operation. + private boolean mForceMerge; + public UndoInputFilter(Editor editor) { mEditor = editor; } @@ -5511,6 +5501,10 @@ public class Editor { mHasComposition = parcel.readInt() != 0; } + public void setForceMerge(boolean forceMerge) { + mForceMerge = forceMerge; + } + /** * Signals that a user-triggered edit is starting. */ @@ -5570,7 +5564,7 @@ public class Editor { // Otherwise the user inserted the composition. String newText = TextUtils.substring(source, start, end); EditOperation edit = new EditOperation(mEditor, "", dstart, newText); - recordEdit(edit, false /* forceMerge */); + recordEdit(edit, mForceMerge); return true; } @@ -5584,7 +5578,7 @@ public class Editor { // the initial input filters run (e.g. a credit card formatter that adds spaces to a // string). This results in multiple filter() calls for what the user considers to be // a single operation. Always undo the whole set of changes in one step. - final boolean forceMerge = isInTextWatcher(); + final boolean forceMerge = mForceMerge || isInTextWatcher(); // Build a new operation with all the information from this edit. String newText = TextUtils.substring(source, start, end); 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/SimpleMonthView.java b/core/java/android/widget/SimpleMonthView.java index 6edce91db504..43cf5a1cdc0b 100644 --- a/core/java/android/widget/SimpleMonthView.java +++ b/core/java/android/widget/SimpleMonthView.java @@ -33,6 +33,7 @@ import android.text.TextPaint; import android.text.format.DateFormat; import android.util.AttributeSet; import android.util.IntArray; +import android.util.Log; import android.util.MathUtils; import android.util.StateSet; import android.view.KeyEvent; @@ -47,6 +48,7 @@ import com.android.internal.R; import com.android.internal.widget.ExploreByTouchHelper; import java.text.NumberFormat; +import java.util.Arrays; import java.util.Calendar; import java.util.Locale; @@ -55,17 +57,22 @@ import java.util.Locale; * within the specified month. */ class SimpleMonthView extends View { + private static final String LOG_TAG = "SimpleMonthView"; + private static final int DAYS_IN_WEEK = 7; private static final int MAX_WEEKS_IN_MONTH = 6; private static final int DEFAULT_SELECTED_DAY = -1; private static final int DEFAULT_WEEK_START = Calendar.SUNDAY; - private static final String DEFAULT_TITLE_FORMAT = "MMMMy"; + private static final String MONTH_YEAR_FORMAT = "MMMMy"; private static final String DAY_OF_WEEK_FORMAT = "EEEEE"; private static final int SELECTED_HIGHLIGHT_ALPHA = 0xB0; + /** Temporary until we figure out why the date gets messed up. */ + private static final boolean DEBUG_WRONG_DATE = true; + private final TextPaint mMonthPaint = new TextPaint(); private final TextPaint mDayOfWeekPaint = new TextPaint(); private final TextPaint mDayPaint = new TextPaint(); @@ -73,13 +80,13 @@ class SimpleMonthView extends View { private final Paint mDayHighlightPaint = new Paint(); private final Paint mDayHighlightSelectorPaint = new Paint(); - private final Calendar mCalendar = Calendar.getInstance(); - private final Calendar mDayOfWeekLabelCalendar = Calendar.getInstance(); + private final String[] mDayOfWeekLabels = new String[7]; + + private final Calendar mCalendar; + private final Locale mLocale; private final MonthViewTouchHelper mTouchHelper; - private final SimpleDateFormat mTitleFormatter; - private final SimpleDateFormat mDayOfWeekFormatter; private final NumberFormat mDayFormatter; // Desired dimensions. @@ -89,7 +96,7 @@ class SimpleMonthView extends View { private final int mDesiredCellWidth; private final int mDesiredDaySelectorRadius; - private CharSequence mTitle; + private String mMonthYearLabel; private int mMonth; private int mYear; @@ -168,15 +175,44 @@ class SimpleMonthView extends View { setAccessibilityDelegate(mTouchHelper); setImportantForAccessibility(IMPORTANT_FOR_ACCESSIBILITY_YES); - final Locale locale = res.getConfiguration().locale; - final String titleFormat = DateFormat.getBestDateTimePattern(locale, DEFAULT_TITLE_FORMAT); - mTitleFormatter = new SimpleDateFormat(titleFormat, locale); - mDayOfWeekFormatter = new SimpleDateFormat(DAY_OF_WEEK_FORMAT, locale); - mDayFormatter = NumberFormat.getIntegerInstance(locale); + mLocale = res.getConfiguration().locale; + mCalendar = Calendar.getInstance(mLocale); + + mDayFormatter = NumberFormat.getIntegerInstance(mLocale); + + updateMonthYearLabel(); + updateDayOfWeekLabels(); initPaints(res); } + private void updateMonthYearLabel() { + final String format = DateFormat.getBestDateTimePattern(mLocale, MONTH_YEAR_FORMAT); + final SimpleDateFormat formatter = new SimpleDateFormat(format, mLocale); + mMonthYearLabel = formatter.format(mCalendar.getTime()); + } + + private void updateDayOfWeekLabels() { + if (DEBUG_WRONG_DATE) { + Log.d(LOG_TAG, "enter updateDayOfWeekLabels()", new Exception()); + Log.d(LOG_TAG, "mLocale => " + mLocale); + Log.d(LOG_TAG, "mWeekStart => " + mWeekStart); + } + + final Calendar calendar = Calendar.getInstance(mLocale); + calendar.setFirstDayOfWeek(mWeekStart); + + final SimpleDateFormat formatter = new SimpleDateFormat(DAY_OF_WEEK_FORMAT, mLocale); + for (int i = 0; i < 7; i++) { + calendar.set(Calendar.DAY_OF_WEEK, i); + mDayOfWeekLabels[i] = formatter.format(calendar.getTime()); + } + + if (DEBUG_WRONG_DATE) { + Log.d(LOG_TAG, "mDayOfWeekLabels <= " + Arrays.toString(mDayOfWeekLabels)); + } + } + /** * Applies the specified text appearance resource to a paint, returning the * text color if one is set in the text appearance. @@ -236,13 +272,6 @@ class SimpleMonthView extends View { invalidate(); } - public CharSequence getTitle() { - if (mTitle == null) { - mTitle = mTitleFormatter.format(mCalendar.getTime()); - } - return mTitle; - } - /** * Sets up the text and style properties for painting. */ @@ -607,7 +636,11 @@ class SimpleMonthView extends View { final float lineHeight = mMonthPaint.ascent() + mMonthPaint.descent(); final float y = (mMonthHeight - lineHeight) / 2f; - canvas.drawText(getTitle().toString(), x, y, mMonthPaint); + canvas.drawText(mMonthYearLabel, x, y, mMonthPaint); + } + + public String getMonthYearLabel() { + return mMonthYearLabel; } private void drawDaysOfWeek(Canvas canvas) { @@ -630,16 +663,11 @@ class SimpleMonthView extends View { } final int dayOfWeek = (col + mWeekStart) % DAYS_IN_WEEK; - final String label = getDayOfWeekLabel(dayOfWeek); + final String label = mDayOfWeekLabels[dayOfWeek]; canvas.drawText(label, colCenterRtl, rowCenter - halfLineHeight, p); } } - private String getDayOfWeekLabel(int dayOfWeek) { - mDayOfWeekLabelCalendar.set(Calendar.DAY_OF_WEEK, dayOfWeek); - return mDayOfWeekFormatter.format(mDayOfWeekLabelCalendar.getTime()); - } - /** * Draws the month days. */ @@ -746,12 +774,22 @@ class SimpleMonthView extends View { * {@link Calendar#SUNDAY} through {@link Calendar#SATURDAY} */ public void setFirstDayOfWeek(int weekStart) { + if (DEBUG_WRONG_DATE) { + Log.d(LOG_TAG, "enter setFirstDayOfWeek(" + weekStart + ")", new Exception()); + } + if (isValidDayOfWeek(weekStart)) { mWeekStart = weekStart; } else { mWeekStart = mCalendar.getFirstDayOfWeek(); } + if (DEBUG_WRONG_DATE) { + Log.d(LOG_TAG, "mWeekStart <=" + mWeekStart); + } + + updateDayOfWeekLabels(); + // Invalidate cached accessibility information. mTouchHelper.invalidateRoot(); invalidate(); @@ -807,11 +845,10 @@ class SimpleMonthView extends View { mEnabledDayStart = MathUtils.constrain(enabledDayStart, 1, mDaysInMonth); mEnabledDayEnd = MathUtils.constrain(enabledDayEnd, mEnabledDayStart, mDaysInMonth); - // Invalidate the old title. - mTitle = null; - // Invalidate cached accessibility information. mTouchHelper.invalidateRoot(); + + updateMonthYearLabel(); } private static int getDaysInMonth(int month, int year) { 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 ac3eaf7df334..e971f865bf45 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -3071,7 +3071,14 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * @attr ref android.R.styleable#TextView_elegantTextHeight */ public void setElegantTextHeight(boolean elegant) { - mTextPaint.setElegantTextHeight(elegant); + if (elegant != mTextPaint.isElegantTextHeight()) { + mTextPaint.setElegantTextHeight(elegant); + if (mLayout != null) { + nullLayouts(); + requestLayout(); + invalidate(); + } + } } /** @@ -5463,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) { @@ -5488,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)) { @@ -8916,8 +8923,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } void onLocaleChanged() { - // Will be re-created on demand in getWordIterator with the proper new locale - mEditor.mWordIterator = null; + mEditor.onLocaleChanged(); } /** 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/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl index 74fe94f96ddb..8e38c5a41567 100644 --- a/core/java/com/android/internal/app/IBatteryStats.aidl +++ b/core/java/com/android/internal/app/IBatteryStats.aidl @@ -20,6 +20,7 @@ import com.android.internal.os.BatteryStatsImpl; import android.os.ParcelFileDescriptor; import android.os.WorkSource; +import android.os.health.HealthStatsParceler; import android.telephony.DataConnectionRealTimeInfo; import android.telephony.SignalStrength; @@ -125,4 +126,7 @@ interface IBatteryStats { void noteBleScanStarted(in WorkSource ws); void noteBleScanStopped(in WorkSource ws); void noteResetBleScan(); + + HealthStatsParceler takeUidSnapshot(int uid); + HealthStatsParceler[] takeUidSnapshots(in int[] uid); } diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java index f04bcf2d0264..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: Take secondary system locales into consideration. - if (locale != null && locale.equals(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/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 60c9e14c1d0c..c484121236ac 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -5300,6 +5300,12 @@ public class BatteryStatsImpl extends BatteryStats { } @Override + public Timer getProcessStateTimer(int state) { + if (state < 0 || state >= NUM_PROCESS_STATE) return null; + return mProcessStateTimer[state]; + } + + @Override public Timer getVibratorOnTimer() { return mVibratorOnTimer; } diff --git a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java index 84d0fc70b1ca..9907ea92670b 100644 --- a/core/java/com/android/internal/policy/DividerSnapAlgorithm.java +++ b/core/java/com/android/internal/policy/DividerSnapAlgorithm.java @@ -279,6 +279,26 @@ public class DividerSnapAlgorithm { } /** + * Cycles through all non-dismiss targets with a stepping of {@param increment}. It moves left + * if {@param increment} is negative and moves right otherwise. + */ + public SnapTarget cycleNonDismissTarget(SnapTarget snapTarget, int increment) { + int index = mTargets.indexOf(snapTarget); + if (index != -1) { + SnapTarget newTarget = mTargets.get((index + mTargets.size() + increment) + % mTargets.size()); + if (newTarget == mDismissStartTarget) { + return mLastSplitTarget; + } else if (newTarget == mDismissEndTarget) { + return mFirstSplitTarget; + } else { + return newTarget; + } + } + return snapTarget; + } + + /** * Represents a snap target for the divider. */ public static class SnapTarget { diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java index a84a061077bf..ee73b90097af 100644 --- a/core/java/com/android/internal/util/ArrayUtils.java +++ b/core/java/com/android/internal/util/ArrayUtils.java @@ -27,6 +27,7 @@ import libcore.util.EmptyArray; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.Objects; @@ -477,4 +478,48 @@ public class ArrayUtils { } return !diff; } + + /** + * Removes elements that match the predicate in an efficient way that alters the order of + * elements in the collection. This should only be used if order is not important. + * @param collection The ArrayList from which to remove elements. + * @param predicate The predicate that each element is tested against. + * @return the number of elements removed. + */ + public static <T> int unstableRemoveIf(@Nullable ArrayList<T> collection, + @NonNull java.util.function.Predicate<T> predicate) { + if (collection == null) { + return 0; + } + + final int size = collection.size(); + int leftIdx = 0; + int rightIdx = size - 1; + while (leftIdx <= rightIdx) { + // Find the next element to remove moving left to right. + while (leftIdx < size && !predicate.test(collection.get(leftIdx))) { + leftIdx++; + } + + // Find the next element to keep moving right to left. + while (rightIdx > leftIdx && predicate.test(collection.get(rightIdx))) { + rightIdx--; + } + + if (leftIdx >= rightIdx) { + // Done. + break; + } + + Collections.swap(collection, leftIdx, rightIdx); + leftIdx++; + rightIdx--; + } + + // leftIdx is now at the end. + for (int i = size - 1; i >= leftIdx; i--) { + collection.remove(i); + } + return size - leftIdx; + } } 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/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java index 795012dab4d1..9d1447836b93 100644 --- a/core/java/com/android/internal/widget/LockPatternUtils.java +++ b/core/java/com/android/internal/widget/LockPatternUtils.java @@ -887,8 +887,7 @@ public class LockPatternUtils { * @return true if device encryption is enabled */ public static boolean isDeviceEncryptionEnabled() { - final String status = SystemProperties.get("ro.crypto.state", "unsupported"); - return "encrypted".equalsIgnoreCase(status); + return StorageManager.isEncrypted(); } /** @@ -896,7 +895,7 @@ public class LockPatternUtils { * @return true if device is file encrypted */ public static boolean isFileEncryptionEnabled() { - return StorageManager.isFileBasedEncryptionEnabled(); + return StorageManager.isFileEncryptedNativeOrEmulated(); } /** 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/BootReceiver.java b/core/java/com/android/server/BootReceiver.java index ab75b7c2775c..6d6c1622e5c2 100644 --- a/core/java/com/android/server/BootReceiver.java +++ b/core/java/com/android/server/BootReceiver.java @@ -29,6 +29,7 @@ import android.os.RecoverySystem; import android.os.RemoteException; import android.os.ServiceManager; import android.os.SystemProperties; +import android.os.storage.StorageManager; import android.provider.Downloads; import android.util.AtomicFile; import android.util.Slog; @@ -143,8 +144,7 @@ public class BootReceiver extends BroadcastReceiver { HashMap<String, Long> timestamps = readTimestamps(); if (SystemProperties.getLong("ro.runtime.firstboot", 0) == 0) { - if ("encrypted".equals(SystemProperties.get("ro.crypto.state")) - && "trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))) { + if (StorageManager.inCryptKeeperBounce()) { // Encrypted, first boot to get PIN/pattern/password so data is tmpfs // Don't set ro.runtime.firstboot so that we will do this again // when data is properly mounted 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/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp index 29c1075a3420..fb9b1e53aa8a 100644 --- a/core/jni/android/graphics/BitmapFactory.cpp +++ b/core/jni/android/graphics/BitmapFactory.cpp @@ -201,6 +201,26 @@ private: const unsigned int mSize; }; +// Necessary for decodes when the native decoder cannot scale to appropriately match the sampleSize +// (for example, RAW). If the sampleSize divides evenly into the dimension, we require that the +// scale matches exactly. If sampleSize does not divide evenly, we allow the decoder to choose how +// best to round. +static bool needsFineScale(const int fullSize, const int decodedSize, const int sampleSize) { + if (fullSize % sampleSize == 0 && fullSize / sampleSize != decodedSize) { + return true; + } else if ((fullSize / sampleSize + 1) != decodedSize && + (fullSize / sampleSize) != decodedSize) { + return true; + } + return false; +} + +static bool needsFineScale(const SkISize fullSize, const SkISize decodedSize, + const int sampleSize) { + return needsFineScale(fullSize.width(), decodedSize.width(), sampleSize) || + needsFineScale(fullSize.height(), decodedSize.height(), sampleSize); +} + static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding, jobject options) { // This function takes ownership of the input stream. Since the SkAndroidCodec // will take ownership of the stream, we don't necessarily need to take ownership @@ -250,7 +270,6 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding } } } - const bool willScale = scale != 1.0f; // Create the codec. NinePatchPeeker peeker; @@ -269,15 +288,28 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding prefColorType = kN32_SkColorType; } - // Determine the output size and return if the client only wants the size. + // Determine the output size. SkISize size = codec->getSampledDimensions(sampleSize); + + int scaledWidth = size.width(); + int scaledHeight = size.height(); + bool willScale = false; + + // Apply a fine scaling step if necessary. + if (needsFineScale(codec->getInfo().dimensions(), size, sampleSize)) { + willScale = true; + scaledWidth = codec->getInfo().width() / sampleSize; + scaledHeight = codec->getInfo().height() / sampleSize; + } + + // Set the options and return if the client only wants the size. if (options != NULL) { jstring mimeType = encodedFormatToString(env, codec->getEncodedFormat()); if (env->ExceptionCheck()) { return nullObjectReturn("OOM in encodedFormatToString()"); } - env->SetIntField(options, gOptions_widthFieldID, size.width()); - env->SetIntField(options, gOptions_heightFieldID, size.height()); + env->SetIntField(options, gOptions_widthFieldID, scaledWidth); + env->SetIntField(options, gOptions_heightFieldID, scaledHeight); env->SetObjectField(options, gOptions_mimeFieldID, mimeType); if (onlyDecodeSize) { @@ -285,6 +317,13 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding } } + // Scale is necessary due to density differences. + if (scale != 1.0f) { + willScale = true; + scaledWidth = static_cast<int>(scaledWidth * scale + 0.5f); + scaledHeight = static_cast<int>(scaledHeight * scale + 0.5f); + } + android::Bitmap* reuseBitmap = nullptr; unsigned int existingBufferSize = 0; if (javaBitmap != NULL) { @@ -381,13 +420,6 @@ static jobject doDecode(JNIEnv* env, SkStreamRewindable* stream, jobject padding return nullObjectReturn("codec->getAndroidPixels() failed."); } - int scaledWidth = size.width(); - int scaledHeight = size.height(); - if (willScale) { - scaledWidth = int(scaledWidth * scale + 0.5f); - scaledHeight = int(scaledHeight * scale + 0.5f); - } - jbyteArray ninePatchChunk = NULL; if (peeker.mPatch != NULL) { if (willScale) { diff --git a/core/jni/android_hardware_camera2_DngCreator.cpp b/core/jni/android_hardware_camera2_DngCreator.cpp index c6baf1c645bf..d80d8f262189 100644 --- a/core/jni/android_hardware_camera2_DngCreator.cpp +++ b/core/jni/android_hardware_camera2_DngCreator.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#define LOG_NDEBUG 0 +//#define LOG_NDEBUG 0 #define LOG_TAG "DngCreator_JNI" #include <inttypes.h> #include <string.h> @@ -1792,6 +1792,8 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image { // Set up orientation tags. + // Note: There's only one orientation field for the whole file, in IFD0 + // The main image and any thumbnails therefore have the same orientation. uint16_t orientation = nativeContext->getOrientation(); BAIL_IF_INVALID_RET_NULL_SP(writer->addEntry(TAG_ORIENTATION, 1, &orientation, TIFF_IFD_0), env, TAG_ORIENTATION, writer); @@ -1873,7 +1875,6 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image } Vector<uint16_t> tagsToMove; - tagsToMove.add(TAG_ORIENTATION); tagsToMove.add(TAG_NEWSUBFILETYPE); tagsToMove.add(TAG_ACTIVEAREA); tagsToMove.add(TAG_BITSPERSAMPLE); @@ -1904,12 +1905,6 @@ static sp<TiffWriter> DngCreator_setup(JNIEnv* env, jobject thiz, uint32_t image return nullptr; } - // Make sure both IFDs get the same orientation tag - sp<TiffEntry> orientEntry = writer->getEntry(TAG_ORIENTATION, TIFF_IFD_SUB1); - if (orientEntry.get() != nullptr) { - writer->addEntry(orientEntry, TIFF_IFD_0); - } - // Setup thumbnail tags { diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp index ee8fb195002d..f7a5e8a07fc0 100644 --- a/core/jni/android_util_Process.cpp +++ b/core/jni/android_util_Process.cpp @@ -17,6 +17,8 @@ #define LOG_TAG "Process" +// To make sure cpu_set_t is included from sched.h +#define _GNU_SOURCE 1 #include <utils/Log.h> #include <binder/IPCThreadState.h> #include <binder/IServiceManager.h> @@ -288,6 +290,139 @@ jint android_os_Process_getProcessGroup(JNIEnv* env, jobject clazz, jint pid) return (int) sp; } +#ifdef ENABLE_CPUSETS +/** Sample CPUset list format: + * 0-3,4,6-8 + */ +static void parse_cpuset_cpus(char *cpus, cpu_set_t *cpu_set) { + unsigned int start, end, matched, i; + char *cpu_range = strtok(cpus, ","); + while (cpu_range != NULL) { + start = end = 0; + matched = sscanf(cpu_range, "%u-%u", &start, &end); + cpu_range = strtok(NULL, ","); + if (start >= CPU_SETSIZE) { + ALOGE("parse_cpuset_cpus: ignoring CPU number larger than %d.", CPU_SETSIZE); + continue; + } else if (end >= CPU_SETSIZE) { + ALOGE("parse_cpuset_cpus: ignoring CPU numbers larger than %d.", CPU_SETSIZE); + end = CPU_SETSIZE - 1; + } + if (matched == 1) { + CPU_SET(start, cpu_set); + } else if (matched == 2) { + for (i = start; i <= end; i++) { + CPU_SET(i, cpu_set); + } + } else { + ALOGE("Failed to match cpus"); + } + } + return; +} + +/** + * Stores the CPUs assigned to the cpuset corresponding to the + * SchedPolicy in the passed in cpu_set. + */ +static void get_cpuset_cores_for_policy(SchedPolicy policy, cpu_set_t *cpu_set) +{ + FILE *file; + const char *filename; + + CPU_ZERO(cpu_set); + + switch (policy) { + case SP_BACKGROUND: + filename = "/dev/cpuset/background/cpus"; + break; + case SP_FOREGROUND: + case SP_AUDIO_APP: + case SP_AUDIO_SYS: + filename = "/dev/cpuset/foreground/cpus"; + break; + case SP_TOP_APP: + filename = "/dev/cpuset/top-app/cpus"; + break; + default: + filename = NULL; + } + + if (!filename) return; + + file = fopen(filename, "re"); + if (file != NULL) { + // Parse cpus string + char *line = NULL; + size_t len = 0; + ssize_t num_read = getline(&line, &len, file); + fclose (file); + if (num_read > 0) { + parse_cpuset_cpus(line, cpu_set); + } else { + ALOGE("Failed to read %s", filename); + } + free(line); + } + return; +} +#endif + + +/** + * Determine CPU cores exclusively assigned to the + * cpuset corresponding to the SchedPolicy and store + * them in the passed in cpu_set_t + */ +void get_exclusive_cpuset_cores(SchedPolicy policy, cpu_set_t *cpu_set) { +#ifdef ENABLE_CPUSETS + int i; + cpu_set_t tmp_set; + get_cpuset_cores_for_policy(policy, cpu_set); + for (i = 0; i < SP_CNT; i++) { + if ((SchedPolicy) i == policy) continue; + get_cpuset_cores_for_policy((SchedPolicy)i, &tmp_set); + // First get cores exclusive to one set or the other + CPU_XOR(&tmp_set, cpu_set, &tmp_set); + // Then get the ones only in cpu_set + CPU_AND(cpu_set, cpu_set, &tmp_set); + } +#else + (void) policy; + CPU_ZERO(cpu_set); +#endif + return; +} + +jintArray android_os_Process_getExclusiveCores(JNIEnv* env, jobject clazz) { + SchedPolicy sp; + cpu_set_t cpu_set; + jintArray cpus; + int pid = getpid(); + if (get_sched_policy(pid, &sp) != 0) { + signalExceptionForGroupError(env, errno); + return NULL; + } + get_exclusive_cpuset_cores(sp, &cpu_set); + int num_cpus = CPU_COUNT(&cpu_set); + cpus = env->NewIntArray(num_cpus); + if (cpus == NULL) { + jniThrowException(env, "java/lang/OutOfMemoryError", NULL); + return NULL; + } + + jint* cpu_elements = env->GetIntArrayElements(cpus, 0); + int count = 0; + for (int i = 0; i < CPU_SETSIZE && count < num_cpus; i++) { + if (CPU_ISSET(i, &cpu_set)) { + cpu_elements[count++] = i; + } + } + + env->ReleaseIntArrayElements(cpus, cpu_elements, 0); + return cpus; +} + static void android_os_Process_setCanSelfBackground(JNIEnv* env, jobject clazz, jboolean bgOk) { // Establishes the calling thread as illegal to put into the background. // Typically used only for the system process's main looper. @@ -1053,6 +1188,7 @@ static const JNINativeMethod methods[] = { {"setThreadGroup", "(II)V", (void*)android_os_Process_setThreadGroup}, {"setProcessGroup", "(II)V", (void*)android_os_Process_setProcessGroup}, {"getProcessGroup", "(I)I", (void*)android_os_Process_getProcessGroup}, + {"getExclusiveCores", "()[I", (void*)android_os_Process_getExclusiveCores}, {"setSwappiness", "(IZ)Z", (void*)android_os_Process_setSwappiness}, {"setArgV0", "(Ljava/lang/String;)V", (void*)android_os_Process_setArgV0}, {"setUid", "(I)I", (void*)android_os_Process_setUid}, diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml index b8b00bfcc111..0bbaa24a9ad4 100644 --- a/core/res/res/layout/notification_template_header.xml +++ b/core/res/res/layout/notification_template_header.xml @@ -20,9 +20,9 @@ android:id="@+id/notification_header" android:orientation="horizontal" android:layout_width="wrap_content" - android:layout_height="48dp" + android:layout_height="53dp" android:clipChildren="false" - android:paddingTop="5dp" + android:paddingTop="10dp" android:paddingBottom="16dp" android:paddingStart="@dimen/notification_content_margin_start" android:paddingEnd="16dp"> diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml index a37bfa9afc00..ccd26fb22cb0 100644 --- a/core/res/res/layout/notification_template_material_base.xml +++ b/core/res/res/layout/notification_template_material_base.xml @@ -41,7 +41,7 @@ android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginStart="@dimen/notification_content_margin_start" - android:layout_marginBottom="11dp" + android:layout_marginBottom="15dp" android:layout_marginEnd="@dimen/notification_content_margin_end" > <include layout="@layout/notification_template_progress" /> </FrameLayout> diff --git a/core/res/res/layout/notification_template_material_big_base.xml b/core/res/res/layout/notification_template_material_big_base.xml index f302087ec398..d53fb5f2e177 100644 --- a/core/res/res/layout/notification_template_material_big_base.xml +++ b/core/res/res/layout/notification_template_material_big_base.xml @@ -49,7 +49,7 @@ android:layout_height="wrap_content" android:layout_gravity="bottom" android:layout_marginStart="@dimen/notification_content_margin_start" - android:layout_marginBottom="11dp" + android:layout_marginBottom="15dp" android:layout_marginEnd="@dimen/notification_content_margin_end"> <include layout="@layout/notification_template_progress" /> </FrameLayout> diff --git a/core/res/res/layout/notification_template_material_big_media.xml b/core/res/res/layout/notification_template_material_big_media.xml index a5ed1875d830..04ea12d4f9fe 100644 --- a/core/res/res/layout/notification_template_material_big_media.xml +++ b/core/res/res/layout/notification_template_material_big_media.xml @@ -25,7 +25,7 @@ > <include layout="@layout/notification_template_header" android:layout_width="match_parent" - android:layout_height="48dp" + android:layout_height="53dp" android:layout_gravity="start"/> <LinearLayout android:layout_width="match_parent" @@ -50,9 +50,10 @@ android:id="@+id/media_actions" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="-15dp" + android:layout_marginTop="-21dp" android:paddingStart="8dp" - android:paddingBottom="8dp" + android:paddingBottom="12dp" + android:gravity="top" android:orientation="horizontal" android:layoutDirection="ltr" > @@ -65,7 +66,7 @@ android:layout_height="@dimen/media_notification_expanded_image_max_size" android:minWidth="40dp" android:layout_marginEnd="16dp" - android:layout_marginBottom="16dp" + android:layout_marginBottom="20dp" android:layout_gravity="bottom|end" android:scaleType="centerCrop" /> diff --git a/core/res/res/layout/notification_template_material_big_text.xml b/core/res/res/layout/notification_template_material_big_text.xml index 3c59b4e83a05..fdfefe10c3b5 100644 --- a/core/res/res/layout/notification_template_material_big_text.xml +++ b/core/res/res/layout/notification_template_material_big_text.xml @@ -39,7 +39,7 @@ <com.android.internal.widget.ImageFloatingTextView android:id="@+id/big_text" android:layout_width="match_parent" android:layout_height="0dp" - android:layout_marginTop="1dp" + android:layout_marginTop="0.5dp" android:paddingBottom="@dimen/notification_content_margin_bottom" android:textAppearance="@style/TextAppearance.Material.Notification" android:singleLine="false" diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml index cda063627dc5..809e525efb52 100644 --- a/core/res/res/layout/notification_template_material_media.xml +++ b/core/res/res/layout/notification_template_material_media.xml @@ -24,7 +24,7 @@ > <include layout="@layout/notification_template_header" android:layout_width="fill_parent" - android:layout_height="48dp" /> + android:layout_height="53dp" /> <LinearLayout android:id="@+id/notification_main_column" android:layout_width="match_parent" @@ -54,7 +54,7 @@ android:layout_height="match_parent" android:layout_gravity="bottom|end" android:layout_marginStart="10dp" - android:layout_marginBottom="8dp" + android:layout_marginBottom="12dp" android:layoutDirection="ltr" android:orientation="horizontal" > diff --git a/core/res/res/layout/notification_template_right_icon.xml b/core/res/res/layout/notification_template_right_icon.xml index 3b358ab01a96..15ccc6729792 100644 --- a/core/res/res/layout/notification_template_right_icon.xml +++ b/core/res/res/layout/notification_template_right_icon.xml @@ -19,7 +19,7 @@ android:layout_width="40dp" android:layout_height="40dp" android:layout_marginEnd="16dp" - android:layout_marginTop="32dp" + android:layout_marginTop="36dp" android:layout_gravity="top|end" android:scaleType="centerCrop" /> diff --git a/core/res/res/layout/notification_template_text.xml b/core/res/res/layout/notification_template_text.xml index 47b30ec99299..a318bda3bbfa 100644 --- a/core/res/res/layout/notification_template_text.xml +++ b/core/res/res/layout/notification_template_text.xml @@ -19,7 +19,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="top" - android:layout_marginTop="1dp" + android:layout_marginTop="0.5dp" android:ellipsize="marquee" android:fadingEdge="horizontal" android:gravity="top" diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml index 10cdae866024..de4ccaeec8ec 100644 --- a/core/res/res/values-af/strings.xml +++ b/core/res/res/values-af/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Stembystand"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Sluit nou"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Inhoud versteek"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Inhoud word versteek volgens beleid"</string> <string name="safeMode" msgid="2788228061547930246">"Veiligmodus"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Raak vir meer opsies."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-ontfouter gekoppel"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Raak om USB-ontfouting te deaktiveer."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Neem tans foutverslag …"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Deel foutverslag?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deel tans foutverslag …"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Jou IT-administrateur het \'n foutverslag versoek om met die foutsporing van hierdie toestel te help. Programme en data sal dalk gedeel word."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DEEL"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"WEIER"</string> <string name="select_input_method" msgid="8547250819326693584">"Verander sleutelbord"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Kies sleutelborde"</string> <string name="show_ime" msgid="2506087537466597099">"Hou dit op die skerm terwyl fisieke sleutelbord aktief is"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Muurpapier"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Verander muurpapier"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Kennisgewingluisteraar"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR-luisteraar"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Toestandverskaffer"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Kennisgewingassistent"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Kennisgewingklassifiseringsdiens"</string> <string name="vpn_title" msgid="19615213552042827">"VPN geaktiveer"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN is geaktiveer deur <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Raak om die netwerk te bestuur."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Ontspeld"</string> <string name="app_info" msgid="6856026610594615344">"Programinligting"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Voer \'n fabriekterugstelling uit om hierdie toestel normaal te gebruik"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Raak om meer te wete te kom."</string> </resources> diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml index 1fb3c51a7115..88e9367ba5cf 100644 --- a/core/res/res/values-am/strings.xml +++ b/core/res/res/values-am/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"የድምጽ እርዳታ"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"አሁን ቆልፍ"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"ይዘቶች ተደብቀዋል"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ይዘቶች በመመሪያ ተደብቀዋል"</string> <string name="safeMode" msgid="2788228061547930246">"የሚያስተማምን ሁነታ"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"ለተጨማሪ አማራጮች ነካ ያድርጉ።"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB አድስ ተያይዟል"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ማረሚያ ላለማንቃት ዳስስ።"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"የሳንካ ሪፖርትን በመውሰድ ላይ…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"የሳንካ ሪፖርት ይጋራ?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"የሳንካ ሪፖርትን በማጋራት ላይ…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"የእርስዎ አይቲ አስተዳዳሪ ለዚህ መሣሪያ መላ ለመፈለግ የሳንካ ሪፖርት ጠይቀዋል። መተግበሪያዎች እና ውሂብ ሊጋሩ ይችላሉ።"</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"አጋራ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"አትቀበል"</string> <string name="select_input_method" msgid="8547250819326693584">"ቁልፍ ሰሌዳ ይቀይሩ"</string> <string name="configure_input_methods" msgid="4769971288371946846">"ቁልፍ ሰሌዳዎችን ምረጥ"</string> <string name="show_ime" msgid="2506087537466597099">"አካላዊ የቁልፍ ሰሌዳ ገቢር ሆኖ ሳለ በማያ ገጽ ላይ አቆየው"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"የሁኔታ አቅራቢ"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"የማሳወቂያ ረዳት"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"የማሳወቂያ ደረጃ ሰጪ አገልግሎት"</string> <string name="vpn_title" msgid="19615213552042827">"VPN ነቅቷል።"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN በ<xliff:g id="APP">%s</xliff:g>ገብሯል"</string> <string name="vpn_text" msgid="3011306607126450322">"አውታረመረብ ለማደራጀት ንካ።"</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"ንቀል"</string> <string name="app_info" msgid="6856026610594615344">"የመተግበሪያ መረጃ"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"ይህን መሣሪያ በመደበኛነት ለመጠቀም የፋብሪካ ዳግም ያስጀምሩ"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"የበለጠ ለመረዳት ይንኩ።"</string> </resources> diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml index 518edabf54e2..84bc7683b45b 100644 --- a/core/res/res/values-ar/strings.xml +++ b/core/res/res/values-ar/strings.xml @@ -237,7 +237,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"المساعد الصوتي"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"قفل الآن"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"المحتويات مخفية"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"تم إخفاء المحتويات بواسطة السياسة"</string> <string name="safeMode" msgid="2788228061547930246">"الوضع الآمن"</string> @@ -1168,8 +1167,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"موفر الحالة"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"مساعد الإشعار"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"خدمة ترتيب أهمية الإشعارات"</string> <string name="vpn_title" msgid="19615213552042827">"تم تنشيط الشبكة الظاهرية الخاصة (VPN)"</string> <string name="vpn_title_long" msgid="6400714798049252294">"تم تنشيط VPN بواسطة <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"المس لإدارة الشبكة."</string> @@ -1640,4 +1640,6 @@ <string name="unpin_target" msgid="3556545602439143442">"إزالة تثبيت"</string> <string name="app_info" msgid="6856026610594615344">"معلومات عن التطبيق"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"يمكنك إعادة تعيين إعدادات المصنع لاستخدام هذا الجهاز بشكل عادي"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"المس للتعرف على مزيد من المعلومات."</string> </resources> diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml index d15518267e27..3953264e638f 100644 --- a/core/res/res/values-az-rAZ/strings.xml +++ b/core/res/res/values-az-rAZ/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Səs Yardımçısı"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"İndi kilidləyin"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Məzmun gizlidir"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Məzmun siyasət tərəfindən gizlədilib"</string> <string name="safeMode" msgid="2788228061547930246">"Təhlükəsiz rejim"</string> @@ -1052,16 +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> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <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> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <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 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> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Divar kağızı"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Divar kağızını dəyişin"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Bildiriş dinləyən"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR dinləyici"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Şərait provayderi"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Bildiriş köməkçisi"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Bildiriş qiymətləndirici xidmət"</string> <string name="vpn_title" msgid="19615213552042827">"VPN aktivləşdirildi"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN <xliff:g id="APP">%s</xliff:g> tərəfindən aktivləşdirilib"</string> <string name="vpn_text" msgid="3011306607126450322">"Şəbəkəni idarə etmək üçün toxunun."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Çıxarın"</string> <string name="app_info" msgid="6856026610594615344">"Tətbiq məlumatı"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Cihazı normal istifadə etmək üçün fabrik sıfırlaması"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Daha çox məlumat üçün toxunun."</string> </resources> diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml index 12ae1b0aedd3..5c73fafe6fed 100644 --- a/core/res/res/values-b+sr+Latn/strings.xml +++ b/core/res/res/values-b+sr+Latn/strings.xml @@ -231,7 +231,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Glasovna pomoć"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Zaključaj odmah"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Sadržaj je sakriven"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sadržaj je sakriven smernicama"</string> <string name="safeMode" msgid="2788228061547930246">"Bezbedni režim"</string> @@ -1060,16 +1059,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Dodirnite za još opcija."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Otklanjanje grešaka sa USB-a je uspostavljeno"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Dodirnite da biste onemogućili otklanjanje grešaka sa USB-a."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Izveštaj o grešci se generiše…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite li da podelite izveštaj o grešci?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deli se izveštaj o grešci…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IT administrator je zatražio izveštaj o grešci radi lakšeg rešavanja problema u vezi sa ovim uređajem. Aplikacije i podaci mogu da se dele."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DELI"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBIJ"</string> <string name="select_input_method" msgid="8547250819326693584">"Promenite tastaturu"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Izaberite tastature"</string> <string name="show_ime" msgid="2506087537466597099">"Zadrži ga na ekranu dok je fizička tastatura aktivna"</string> @@ -1148,8 +1143,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Pozadina"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Promena pozadine"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Monitor obaveštenja"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Obrađivač za virtuelnu realnost"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Dobavljač uslova"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Pomoćnik za obaveštenja"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Usluga rangiranja obaveštenja"</string> <string name="vpn_title" msgid="19615213552042827">"VPN je aktiviran"</string> <string name="vpn_title_long" msgid="6400714798049252294">"Aplikacija <xliff:g id="APP">%s</xliff:g> je aktivirala VPN"</string> <string name="vpn_text" msgid="3011306607126450322">"Dodirnite da biste upravljali mrežom."</string> @@ -1587,4 +1583,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Otkači"</string> <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Resetujte uređaj na fabrička podešavanja da biste ga normalno koristili"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Dodirnite da biste saznali više."</string> </resources> diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml index 9cdd298dc3a8..b2633a9f683a 100644 --- a/core/res/res/values-bg/strings.xml +++ b/core/res/res/values-bg/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласова помощ"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Заключване сега"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Скрито съдържание"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Съдържанието е скрито чрез правило"</string> <string name="safeMode" msgid="2788228061547930246">"Безопасен режим"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Докоснете за още опции."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Отстраняване на грешки през USB"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Докоснете за деактивиране"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Сигналът за програмна грешка се извлича…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Да се сподели ли сигналът за програмна грешка?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Сигналът за програмна грешка се споделя…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Системният ви администратор поиска сигнал за програмна грешка с цел отстраняване на неизправностите на това устройство. Възможно е да бъдат споделени приложения и данни."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"СПОДЕЛЯНЕ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ОТХВЪРЛЯНЕ"</string> <string name="select_input_method" msgid="8547250819326693584">"Промяна на клавиатурата"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Избиране на клавиатури"</string> <string name="show_ime" msgid="2506087537466597099">"Показване на екрана, докато физическата клавиатура е активна"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"Доставчик на условия"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Помощник за известия"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Услуга за класифициране на известията"</string> <string name="vpn_title" msgid="19615213552042827">"VPN е активирана"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN е активирана от <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Докоснете за управление на мрежата."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Освобождаване"</string> <string name="app_info" msgid="6856026610594615344">"Информация за приложението"</string> <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Възстановете фабричните настройки, за да използвате това устройство нормално"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Докоснете, за да научите повече."</string> </resources> diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml index a598d3bf66c4..2042c4c2b830 100644 --- a/core/res/res/values-bn-rBD/strings.xml +++ b/core/res/res/values-bn-rBD/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"ভয়েস সহায়তা"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"এখনই লক করুন"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"৯৯৯+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>টি)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"লুকানো বিষয়বস্তু"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"নীতির কারণে সামগ্রী লুকানো আছে"</string> <string name="safeMode" msgid="2788228061547930246">"নিরাপদ মোড"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"আরো বিকল্পের জন্য স্পর্শ করুন৷"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ডিবাগিং সংযুক্ত হয়েছে"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ডিবাগিং অক্ষম করতে স্পর্শ করুন৷"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ত্রুটির প্রতিবেদন নেওয়া হচ্ছে..."</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ত্রুটির প্রতিবেদন শেয়ার করবেন?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ত্রুটির প্রতিবেদন শেয়ার করা হচ্ছে..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"আপনার আইটি প্রশাসক এই ডিভাইসটির সমস্যা নিবারণে সহায়তা করতে একটি ত্রুটির প্রতিবেদন চেয়েছেন৷ অ্যাপ্লিকেশান এবং ডেটা শেয়ার করা হতে পারে৷"</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"শেয়ার করুন"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"অস্বীকার করুন"</string> <string name="select_input_method" msgid="8547250819326693584">"কীবোর্ড পরিবর্তন করুন"</string> <string name="configure_input_methods" msgid="4769971288371946846">"কীবোর্ড চয়ন করুন"</string> <string name="show_ime" msgid="2506087537466597099">"ফিজিক্যাল কীবোর্ড সক্রিয় থাকার সময় এটিকে স্ক্রীনে রাখুন"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"শর্ত প্রদানকারী"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"বিজ্ঞপ্তি সহায়ক"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"বিজ্ঞপ্তি র্যাঙ্কার পরিষেবা"</string> <string name="vpn_title" msgid="19615213552042827">"VPN সক্রিয়"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> এর দ্বারা VPN সক্রিয় করা হয়েছে"</string> <string name="vpn_text" msgid="3011306607126450322">"নেটওয়ার্ক পরিচালনা করতে স্পর্শ করুন৷"</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"আনপিন করুন"</string> <string name="app_info" msgid="6856026610594615344">"অ্যাপ্লিকেশানের তথ্য"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"এই ডিভাইসটিকে স্বাভাবিকভাবে ব্যবহার করতে ফ্যাক্টরি পুনরায় সেট করুন"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"আরো জানতে স্পর্শ করুন৷"</string> </resources> diff --git a/core/res/res/values-bs-rBA/strings.xml b/core/res/res/values-bs-rBA/strings.xml index 61ea35ceca35..f352620b23b4 100644 --- a/core/res/res/values-bs-rBA/strings.xml +++ b/core/res/res/values-bs-rBA/strings.xml @@ -231,7 +231,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Glasovna pomoć"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Zaključaj odmah"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Sadržaj je sakriven"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sadržaj skriven u skladu sa pravilima"</string> <string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string> @@ -1060,16 +1059,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Dodirnite za više opcija."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Uređaj za USB otklanjanje grešaka povezan"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Dodirnite da biste onemogućili USB otklanjanje grešaka."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Prijem izvještaja o grešci..."</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Podijeliti izvještaj o grešci?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Dijeljenje izvještaja o grešci..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Vaš IT administrator je zatražio izvještaj o grešci kako bi pomogao u rješavanju problema ovog uređaja. Aplikacije i podaci se mogu dijeliti."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PODIJELI"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBACI"</string> <string name="select_input_method" msgid="8547250819326693584">"Promijeni tastaturu"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Odaberite tastature"</string> <string name="show_ime" msgid="2506087537466597099">"Prikaži na ekranu dok je fizička tastatura aktivna"</string> @@ -1148,8 +1143,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Pozadinska slika"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Promijenite pozadinsku sliku"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Usluga za praćenje obavještenja"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR slušalac"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Pružalac uslova"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Pomoćnik za obavještenja"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Usluga rangiranja obavještenja"</string> <string name="vpn_title" msgid="19615213552042827">"VPN aktiviran"</string> <string name="vpn_title_long" msgid="6400714798049252294">"Aplikacija <xliff:g id="APP">%s</xliff:g> je aktivirala VPN"</string> <string name="vpn_text" msgid="3011306607126450322">"Dodirnite za upravljanje mrežom."</string> @@ -1587,4 +1583,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Otkači"</string> <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Vratite na fabričke postavke kako biste mogli normalno koristiti ovaj uređaj"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Dodirnite da saznate više."</string> </resources> diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml index 3c32e9a5112f..54828960573e 100644 --- a/core/res/res/values-ca/strings.xml +++ b/core/res/res/values-ca/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. per veu"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Bloqueja ara"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"+999"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Contingut amagat"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contingut amagat de conformitat amb la política"</string> <string name="safeMode" msgid="2788228061547930246">"Mode segur"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Toca per veure més opcions."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuració USB activada"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca per desactivar la depuració USB"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"S\'està creant l\'informe d\'errors…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vols compartir l\'informe d\'errors?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"S\'està compartint l\'informe d\'errors…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"L\'administrador de TI ha sol·licitat un informe d\'errors per resoldre els problemes d\'aquest dispositiu. És possible que es comparteixin aplicacions i dades."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTEIX"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REBUTJA"</string> <string name="select_input_method" msgid="8547250819326693584">"Canvia el teclat"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Tria els teclats"</string> <string name="show_ime" msgid="2506087537466597099">"El deixa a la pantalla mentre el teclat físic està actiu"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fons de pantalla"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Canvia el fons de pantalla"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Oient de notificacions"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Processador de realitat virtual"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Proveïdor de condicions"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Assistent de notificacions"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Servei de classificació de notificacions"</string> <string name="vpn_title" msgid="19615213552042827">"VPN activada"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> ha activat VPN"</string> <string name="vpn_text" msgid="3011306607126450322">"Toca per gestionar la xarxa."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"No fixis"</string> <string name="app_info" msgid="6856026610594615344">"Informació de l\'aplicació"</string> <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Restableix les dades de fàbrica del dispositiu per utilitzar-lo amb normalitat"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toca per obtenir més informació."</string> </resources> diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml index 9d3ecff9be9f..390dfd063eac 100644 --- a/core/res/res/values-cs/strings.xml +++ b/core/res/res/values-cs/strings.xml @@ -233,7 +233,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Hlas. asistence"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Zamknout"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Skrytý obsah"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Obsah skrytý zásadami"</string> <string name="safeMode" msgid="2788228061547930246">"Nouzový režim"</string> @@ -1068,16 +1067,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Klepnutím zobrazíte další možnosti."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladění přes USB připojeno"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotykem zakážete ladění USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Vytváření zprávy o chybě…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Sdílet zprávu o chybě?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Sdílení zprávy o chybě…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Administrátor IT si vyžádal zprávu o chybě, aby mohl problém odstranit. Aplikace a data mohou být sdílena."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"SDÍLET"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODMÍTNOUT"</string> <string name="select_input_method" msgid="8547250819326693584">"Změna klávesnice"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Vybrat klávesnici"</string> <string name="show_ime" msgid="2506087537466597099">"Ponechat na obrazovce, když je aktivní fyzická klávesnice"</string> @@ -1156,8 +1151,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapeta"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Změnit tapetu"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Aplikace poslouchající oznámení"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Přijímač virtuální reality"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Poskytovatel podmínky"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Asistent oznámení"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Služba na hodnocení důležitosti oznámení"</string> <string name="vpn_title" msgid="19615213552042827">"Síť VPN je aktivována"</string> <string name="vpn_title_long" msgid="6400714798049252294">"Aplikace <xliff:g id="APP">%s</xliff:g> aktivovala síť VPN"</string> <string name="vpn_text" msgid="3011306607126450322">"Dotykem zobrazíte správu sítě."</string> @@ -1606,4 +1602,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Odepnout"</string> <string name="app_info" msgid="6856026610594615344">"Informace o aplikaci"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Chcete-li toto zařízení normálně používat, obnovte jej do továrního nastavení"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Klepnutím zobrazíte další informace."</string> </resources> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 2ee9afde50d8..583a6b70603c 100644 --- a/core/res/res/values-da/strings.xml +++ b/core/res/res/values-da/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Taleassistent"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Lås nu"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Indholdet er skjult"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Indholdet er skjult af politikken"</string> <string name="safeMode" msgid="2788228061547930246">"Sikker tilstand"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Tryk for at se flere muligheder."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-fejlretning er tilsluttet"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Tryk for at deaktivere USB-fejlretning."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Opretter fejlrapport…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vil du dele fejlrapporten?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deler fejlrapport…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Din it-administrator har anmodet om en fejlrapport for bedre at kunne finde og rette fejlen på enheden. Apps og data deles muligvis."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DEL"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"AFVIS"</string> <string name="select_input_method" msgid="8547250819326693584">"Skift tastatur"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Vælg tastaturer"</string> <string name="show_ime" msgid="2506087537466597099">"Behold den på skærmen, mens det fysiske tastatur er aktivt"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Baggrund"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Skift baggrund"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Underretningslytter"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR-lyttefunktion"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Tjeneste til formidling af betingelser"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Underretningsassistent"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Tjeneste til rangering af underretninger"</string> <string name="vpn_title" msgid="19615213552042827">"VPN er aktiveret."</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN aktiveres af <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Tryk for at administrere netværket."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Frigør"</string> <string name="app_info" msgid="6856026610594615344">"Oplysninger om appen"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Nulstil enheden til fabriksindstillingerne for at bruge den på normal vis"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Tryk for at få flere oplysninger."</string> </resources> diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml index c9874b8d0553..b67402aac27b 100644 --- a/core/res/res/values-de/strings.xml +++ b/core/res/res/values-de/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Sprachassistent"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Jetzt sperren"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Inhalte ausgeblendet"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Inhalte aufgrund der Richtlinien ausgeblendet"</string> <string name="safeMode" msgid="2788228061547930246">"Abgesicherter Modus"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Für weitere Optionen tippen"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-Debugging"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Zum Deaktivieren berühren"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Fehlerbericht wird abgerufen…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Fehlerbericht teilen?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Fehlerbericht wird geteilt…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Dein IT-Administrator hat einen Fehlerbericht zur Fehlerbehebung für dieses Gerät angefordert. Apps und Daten werden unter Umständen geteilt."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"TEILEN"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ABLEHNEN"</string> <string name="select_input_method" msgid="8547250819326693584">"Tastatur ändern"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Tastatur auswählen"</string> <string name="show_ime" msgid="2506087537466597099">"Auf dem Display einblenden, wenn die physische Tastatur aktiv ist"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Hintergrund"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Hintergrund ändern"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Benachrichtigungs-Listener"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR-Listener"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Bedingungsprovider"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Benachrichtigungsassistent"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Service für Einstufung von Benachrichtigungen"</string> <string name="vpn_title" msgid="19615213552042827">"VPN aktiviert"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN wurde von <xliff:g id="APP">%s</xliff:g> aktiviert."</string> <string name="vpn_text" msgid="3011306607126450322">"Zum Verwalten des Netzwerks berühren"</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Markierung entfernen"</string> <string name="app_info" msgid="6856026610594615344">"App-Informationen"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Gerät zur normalen Verwendung auf Werkseinstellungen zurücksetzen"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Für weitere Informationen tippen."</string> </resources> diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml index 1cac5e54d7e1..845018982dbd 100644 --- a/core/res/res/values-el/strings.xml +++ b/core/res/res/values-el/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Φων.υποβοηθ."</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Κλείδωμα τώρα"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Κρυφό περιεχόμενο"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Το περιεχόμενο είναι κρυφό βάσει πολιτικής"</string> <string name="safeMode" msgid="2788228061547930246">"Ασφαλής λειτουργία"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Αγγίξτε για περισσότερες επιλογές."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Συνδέθηκε ο εντοπισμός σφαλμάτων USB"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Απεν. του εντοπ. σφαλμάτων USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Λήψη αναφοράς σφάλματος…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Κοινή χρήση αναφοράς σφάλματος;"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Κοινή χρήση αναφοράς σφάλματος…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Ο διαχειριστής IT σας ζήτησε μια αναφορά σφάλματος για να συμβάλει στην αντιμετώπιση του προβλήματος αυτής της συσκευής. Ενδέχεται να κοινοποιηθούν οι εφαρμογές και τα δεδομένα."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ΚΟΙΝΟΠΟΙΗΣΗ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ΑΠΟΡΡΙΨΗ"</string> <string name="select_input_method" msgid="8547250819326693584">"Αλλαγή πληκτρολογίου"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Επιλογή πληκτρολογίων"</string> <string name="show_ime" msgid="2506087537466597099">"Να παραμένει στην οθόνη όταν είναι ενεργό το φυσικό πληκτρολόγιο"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"Πάροχος συνθηκών"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Βοηθός ειδοποιήσεων"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Υπηρεσία κατάταξης ειδοποιήσεων"</string> <string name="vpn_title" msgid="19615213552042827">"Το VPN ενεργοποιήθηκε"</string> <string name="vpn_title_long" msgid="6400714798049252294">"Το VPN ενεργοποιήθηκε από την εφαρμογή <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Αγγίξτε για τη διαχείριση του δικτύου."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Ξεκαρφίτσωμα"</string> <string name="app_info" msgid="6856026610594615344">"Πληροφορίες εφαρμογής"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Επαναφέρετε τις εργοστασιακές ρυθμίσεις για να χρησιμοποιήσετε αυτήν τη συσκευή κανονικά"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Αγγίξτε για να μάθετε περισσότερα."</string> </resources> diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml index a6c0e659f23c..ac7ad91522ed 100644 --- a/core/res/res/values-en-rAU/strings.xml +++ b/core/res/res/values-en-rAU/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Contents hidden"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contents hidden by policy"</string> <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string> @@ -1136,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Change wallpaper"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Notification listener"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR listener"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Condition provider"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Notification assistant"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Notification ranker service"</string> <string name="vpn_title" msgid="19615213552042827">"VPN activated"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN is activated by <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Touch to manage the network."</string> @@ -1564,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string> <string name="app_info" msgid="6856026610594615344">"App info"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Restore this device to factory settings to use normally"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Touch to find out more."</string> </resources> diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml index a6c0e659f23c..ac7ad91522ed 100644 --- a/core/res/res/values-en-rGB/strings.xml +++ b/core/res/res/values-en-rGB/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Contents hidden"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contents hidden by policy"</string> <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string> @@ -1136,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Change wallpaper"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Notification listener"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR listener"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Condition provider"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Notification assistant"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Notification ranker service"</string> <string name="vpn_title" msgid="19615213552042827">"VPN activated"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN is activated by <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Touch to manage the network."</string> @@ -1564,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string> <string name="app_info" msgid="6856026610594615344">"App info"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Restore this device to factory settings to use normally"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Touch to find out more."</string> </resources> diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml index a6c0e659f23c..ac7ad91522ed 100644 --- a/core/res/res/values-en-rIN/strings.xml +++ b/core/res/res/values-en-rIN/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Lock now"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Contents hidden"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contents hidden by policy"</string> <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string> @@ -1136,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Change wallpaper"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Notification listener"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR listener"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Condition provider"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Notification assistant"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Notification ranker service"</string> <string name="vpn_title" msgid="19615213552042827">"VPN activated"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN is activated by <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Touch to manage the network."</string> @@ -1564,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string> <string name="app_info" msgid="6856026610594615344">"App info"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Restore this device to factory settings to use normally"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Touch to find out more."</string> </resources> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index e389a22ea9fe..4623d77a00ee 100644 --- a/core/res/res/values-es-rUS/strings.xml +++ b/core/res/res/values-es-rUS/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear ahora"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Contenidos ocultos"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenido oculto debido a la política"</string> <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Toca para ver más opciones."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración por USB conectada"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca para desactivar la depuración por USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Realizando un informe de errores…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"¿Compartir informe de errores?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Compartiendo informe de errores…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"El administrador de TI solicitó un informe de errores para solucionar los problemas de este dispositivo. Es posible que se compartan apps y datos."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTIR"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RECHAZAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Cambiar el teclado"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Seleccionar teclados"</string> <string name="show_ime" msgid="2506087537466597099">"Mantener en la pantalla cuando el teclado físico está activo"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Papel tapiz"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambiar fondo de pantalla"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Agente de escucha de notificaciones"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Procesador de realidad virtual"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Proveedor de condiciones"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Asistente de notificaciones"</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> <string name="vpn_title_long" msgid="6400714798049252294">"VPN está activado por <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Toca para administrar la red."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"No fijar"</string> <string name="app_info" msgid="6856026610594615344">"Información de la app"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Restablece la configuración de fábrica para usar este dispositivo con normalidad"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toca para obtener más información."</string> </resources> diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml index c4d1ffdc067e..65f5f240d2d6 100644 --- a/core/res/res/values-es/strings.xml +++ b/core/res/res/values-es/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear ahora"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"> 999"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Contenidos ocultos"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenidos ocultos por política"</string> <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string> @@ -276,7 +275,7 @@ <string name="permdesc_install_shortcut" msgid="8341295916286736996">"Permite que una aplicación añada accesos directos a la pantalla de inicio sin intervención del usuario."</string> <string name="permlab_uninstall_shortcut" msgid="4729634524044003699">"desinstalar accesos directos"</string> <string name="permdesc_uninstall_shortcut" msgid="6745743474265057975">"Permite que la aplicación elimine accesos directos de la pantalla de inicio sin la intervención del usuario."</string> - <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"redireccionar llamadas salientes"</string> + <string name="permlab_processOutgoingCalls" msgid="3906007831192990946">"redirigir llamadas salientes"</string> <string name="permdesc_processOutgoingCalls" msgid="5156385005547315876">"Permite que la aplicación vea el número que se marca al realizar una llamada con la opción de redirigir la llamada a otro número o cancelar la llamada."</string> <string name="permlab_receiveSms" msgid="8673471768947895082">"recibir mensajes de texto (SMS)"</string> <string name="permdesc_receiveSms" msgid="6424387754228766939">"Permite que la aplicación reciba y procese mensajes MMS, lo que significa que podría utilizar este permiso para controlar o eliminar mensajes enviados al dispositivo sin mostrárselos al usuario."</string> @@ -910,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> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Toca para obtener más opciones"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB habilitada"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca aquí para inhabilitarla"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Creando informe de errores…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"¿Compartir informe de errores?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Compartiendo informe de errores…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Tu administrador de TI ha solicitado un informe de errores para solucionar problemas de este dispositivo. Es posible que se compartan las aplicaciones y los datos."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTIR"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RECHAZAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Elegir teclados"</string> <string name="show_ime" msgid="2506087537466597099">"Debe seguir en pantalla mientras el teclado físico esté activo"</string> @@ -1140,8 +1135,9 @@ <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 RV"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Proveedor de condiciones"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Asistente de notificaciones"</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> <string name="vpn_title_long" msgid="6400714798049252294">"VPN activada por <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Toca para administrar la red."</string> @@ -1450,7 +1446,7 @@ <item quantity="one">Vuelve a intentarlo en 1 segundo</item> </plurals> <string name="restr_pin_try_later" msgid="973144472490532377">"Volver a intentar más tarde"</string> - <string name="immersive_cling_title" msgid="8394201622932303336">"Mostrando pantalla completa"</string> + <string name="immersive_cling_title" msgid="8394201622932303336">"Modo de pantalla completa"</string> <string name="immersive_cling_description" msgid="3482371193207536040">"Para salir, desliza hacia abajo desde arriba."</string> <string name="immersive_cling_positive" msgid="5016839404568297683">"Entendido"</string> <string name="done_label" msgid="2093726099505892398">"Listo"</string> @@ -1572,4 +1568,6 @@ <string name="unpin_target" msgid="3556545602439143442">"No fijar"</string> <string name="app_info" msgid="6856026610594615344">"Información de la aplicación"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Restablece los datos de fábrica para utilizar este dispositivo con normalidad"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toca para obtener más información."</string> </resources> diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml index f2faf003d09b..c35d222da2f9 100644 --- a/core/res/res/values-et-rEE/strings.xml +++ b/core/res/res/values-et-rEE/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Häälabi"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Lukusta kohe"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Sisu on peidetud"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sisu on eeskirjadega peidetud"</string> <string name="safeMode" msgid="2788228061547930246">"Turvarežiim"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Puudutage rohkemate valikute kuvamiseks."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-silumine ühendatud"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Puudutage USB-silumise keelamiseks."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Veaaruande võtmine …"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Kas jagada veaaruannet?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Veaaruande jagamine …"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IT-administraator taotles veaaruannet, mis aitaks seadmes vigu otsida. Rakendusi ja andmeid võidakse jagada."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"JAGA"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"KEELDU"</string> <string name="select_input_method" msgid="8547250819326693584">"Klaviatuuri muutmine"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Vali klaviatuurid"</string> <string name="show_ime" msgid="2506087537466597099">"Hoia seda ekraanil, kui füüsiline klaviatuur on aktiivne"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Taustapilt"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Muutke taustapilti"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Märguannete kuulamisteenus"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Virtuaalreaalses režiimis kuulaja"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Tingimuse pakkuja"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Märguannete abi"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Märguannete tähtsuse määramise teenus"</string> <string name="vpn_title" msgid="19615213552042827">"VPN on aktiveeritud"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN-i aktiveeris <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Võrgu haldamiseks puudutage."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Vabasta"</string> <string name="app_info" msgid="6856026610594615344">"Rakenduse teave"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Seadme tavapäraseks kasutamiseks lähtestage see tehaseseadetele"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Lisateabe saamiseks puudutage."</string> </resources> diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml index a24831a93135..bb83a9e57db8 100644 --- a/core/res/res/values-eu-rES/strings.xml +++ b/core/res/res/values-eu-rES/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Ahots-laguntza"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Blokeatu"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Edukiak ezkutatuta daude"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Gidalerro batzuk ezkutatu dira, gidalerroei jarraiki"</string> <string name="safeMode" msgid="2788228061547930246">"Modu segurua"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Ukitu aukera gehiago ikusteko."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB arazketa konektatuta"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB arazketa desgaitzeko, ukitu hau."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Akatsen txostena sortzen…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Akatsen txostena partekatu nahi duzu?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Akatsen txostena partekatzen…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IKT administratzaileak akatsen txostena eskatu du gailuko arazoa konpontzeko. Baliteke aplikazioak eta datuak partekatzea."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PARTEKATU"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"BAZTERTU"</string> <string name="select_input_method" msgid="8547250819326693584">"Aldatu teklatua"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Aukeratu teklatuak"</string> <string name="show_ime" msgid="2506087537466597099">"Erakutsi pantailan teklatu fisikoa aktibo dagoen bitartean"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Horma-papera"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Aldatu horma-papera"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Jakinarazpenak hautemateko zerbitzua"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Errealitate birtualeko hautemailea"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Baldintza-hornitzailea"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Jakinarazpenen laguntzailea"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Jakinarazpenen sailkapen-zerbitzua"</string> <string name="vpn_title" msgid="19615213552042827">"VPN eginbidea aktibatuta"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> aplikazioak VPN konexioa aktibatu du"</string> <string name="vpn_text" msgid="3011306607126450322">"Ukitu sarea kudeatzeko."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Kendu aingura"</string> <string name="app_info" msgid="6856026610594615344">"Aplikazioari buruzko informazioa"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Berrezarri jatorrizko egoerara gailua ohi bezala erabiltzen jarraitu ahal izateko"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Ukitu informazio gehiago lortzeko."</string> </resources> diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml index 17a5f5b48c5d..eeab6d35a3f4 100644 --- a/core/res/res/values-fa/strings.xml +++ b/core/res/res/values-fa/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"دستیار صوتی"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"اکنون قفل شود"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"بیشتر از 999"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"محتواها پنهان هستند"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"محتوا بر اساس خطمشی پنهان شده است"</string> <string name="safeMode" msgid="2788228061547930246">"حالت ایمن"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"برای گزینههای بیشتر لمس کنید."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"اشکالزدایی USB متصل شد"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"غیرفعالکردن اشکالزداییUSB: با لمس آن."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"درحال گرفتن گزارش اشکال…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"گزارش اشکال به اشتراک گذاشته شود؟"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"درحال اشتراکگذاری گزارش اشکال…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"سرپرست فناوری اطلاعات شما برای کمک به عیبیابی این دستگاه، گزارش اشکال درخواست کرده است. ممکن است برنامهها و دادهها به اشتراک گذاشته شوند."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"اشتراکگذاری"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"نپذیرفتن"</string> <string name="select_input_method" msgid="8547250819326693584">"تغییر صفحهکلید"</string> <string name="configure_input_methods" msgid="4769971288371946846">"انتخاب صفحهکلیدها"</string> <string name="show_ime" msgid="2506087537466597099">"وقتی صفحهکلید فیزیکی فعال است این ویرایشگر را روی صفحه نگهمیدارد"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"ارائهدهنده وضعیت"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"دستیار اعلان"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"سرویس رتبهبندی اعلان"</string> <string name="vpn_title" msgid="19615213552042827">"VPN فعال شد"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN توسط <xliff:g id="APP">%s</xliff:g> فعال شده است"</string> <string name="vpn_text" msgid="3011306607126450322">"برای مدیریت شبکه لمس کنید."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"برداشتن پین"</string> <string name="app_info" msgid="6856026610594615344">"اطلاعات برنامه"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"بازنشانی کارخانهای برای استفاده عادی از این دستگاه"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"برای یادگیری بیشتر لمس کنید."</string> </resources> diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml index 15cba76bf812..d45e0bd60efe 100644 --- a/core/res/res/values-fi/strings.xml +++ b/core/res/res/values-fi/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Ääniapuri"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Lukitse nyt"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Sisältö piilotettu"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sisältö on piilotettu käytännön perusteella."</string> <string name="safeMode" msgid="2788228061547930246">"Suojattu tila"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Lisää vaihtoehtoja koskettamalla"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-vianetsintä yhdistetty"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Sulje USB-vianetsintä koskettamalla."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Luodaan virheraporttia…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Jaetaanko virheraportti?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Jaetaan virheraporttia…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Järjestelmänvalvoja pyysi virheraporttia voidakseen auttaa laitteen vianetsinnässä. Sovelluksia ja tietoja voidaan jakaa."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"JAA"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"HYLKÄÄ"</string> <string name="select_input_method" msgid="8547250819326693584">"Vaihda näppäimistö"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Valitse näppäimistöt"</string> <string name="show_ime" msgid="2506087537466597099">"Pidä näytöllä, kun fyysinen näppäimistö on aktiivinen."</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Taustakuva"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Vaihda taustakuvaa"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Ilmoituskuuntelija"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Virtuaalitodellisuuden kuuntelija"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Ehtojen toimituspalvelu"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Ilmoitusapuri"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Ilmoitusten sijoituspalvelu"</string> <string name="vpn_title" msgid="19615213552042827">"VPN on aktivoitu"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> on aktivoinut VPN-yhteyden"</string> <string name="vpn_text" msgid="3011306607126450322">"Voit hallinnoida verkkoa koskettamalla."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Irrota"</string> <string name="app_info" msgid="6856026610594615344">"Sovelluksen tiedot"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Palauta tehdasasetukset, jotta voit käyttää laitetta tavallisesti"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Lue lisätietoja koskettamalla."</string> </resources> diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml index 83e793620b41..6fa6f4915f5b 100644 --- a/core/res/res/values-fr-rCA/strings.xml +++ b/core/res/res/values-fr-rCA/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. vocale"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Verrouiller"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Contenus masqués"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenu masqué conformément aux politiques"</string> <string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Touchez pour afficher plus d\'options."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB connecté"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Appuyez pour désactiver le débogage USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Création d\'un rapport de bogue en cours..."</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Partager le rapport de bogue?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Partage du rapport de bogue en cours..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Votre administrateur informatique a demandé un rapport de bogue pour l\'aider à dépanner cet appareil. Les applications et les données peuvent être partagées."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PARTAGER"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REFUSER"</string> <string name="select_input_method" msgid="8547250819326693584">"Changer de clavier"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Choisir les claviers"</string> <string name="show_ime" msgid="2506087537466597099">"Afficher lorsque le clavier physique est activé"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fond d\'écran"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Changer de fond d\'écran"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Outil d\'écoute des notifications"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Écouteur de réalité virtuelle"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Fournisseur de conditions"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Assistant des notifications"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Service de classement des notifications"</string> <string name="vpn_title" msgid="19615213552042827">"VPN activé"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN activé par <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Appuyez ici pour gérer le réseau."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Annuler l\'épinglage"</string> <string name="app_info" msgid="6856026610594615344">"Détails de l\'application"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Rétablissez la configuration d\'usine pour utiliser cet appareil normalement"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Touchez ici pour en savoir plus."</string> </resources> diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml index 2e047ad49803..02ad9e6a2d56 100644 --- a/core/res/res/values-fr/strings.xml +++ b/core/res/res/values-fr/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Assistance vocale"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Verrouiller"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Contenus masqués"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenu masqué conformément aux règles"</string> <string name="safeMode" msgid="2788228061547930246">"Mode sécurisé"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Appuyez pour afficher plus d\'options"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Débogage USB activé"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Appuyez pour désact. débogage USB"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Création du rapport de bug…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Partager le rapport de bug ?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Partage du rapport de bug…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Votre administrateur informatique a demandé un rapport de bug pour l\'aider à résoudre le problème lié à cet appareil. Il est possible que des applications et des données soient partagées."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PARTAGER"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REFUSER"</string> <string name="select_input_method" msgid="8547250819326693584">"Changer de clavier"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Sélectionner des claviers"</string> <string name="show_ime" msgid="2506087537466597099">"Afficher lorsque le clavier physique est activé"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fond d\'écran"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Changer de fond d\'écran"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Outil d\'écoute des notifications"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Écouteur de réalité virtuelle"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Fournisseur de conditions"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Assistant de notifications"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Service de classement des notifications"</string> <string name="vpn_title" msgid="19615213552042827">"VPN activé"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN activé par <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Appuyez ici pour gérer le réseau."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Retirer"</string> <string name="app_info" msgid="6856026610594615344">"Infos sur l\'appli"</string> <string name="negative_duration" msgid="5688706061127375131">"− <xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Rétablir la configuration d\'usine pour utiliser cet appareil normalement"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Appuyez ici pour en savoir plus."</string> </resources> diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml index e721037ae603..cb0ac76e4ee2 100644 --- a/core/res/res/values-gl-rES/strings.xml +++ b/core/res/res/values-gl-rES/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistente voz"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Contido oculto"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Ocultouse contido por causa da política"</string> <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Toca para ver máis opcións."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuración USB conectada"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Toca aquí para desactivala"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Creando informe de erros…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Queres compartir o informe de erros?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Compartindo informe de erros..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"O teu administrador de TI solicitou un informe de erros para axudar a solucionar os problemas deste dispositivo. É posible que se compartan aplicacións e datos."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTIR"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ANULAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Cambiar teclado"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Seleccionar teclados"</string> <string name="show_ime" msgid="2506087537466597099">"Manteno na pantalla mentres o teclado físico estea activo"</string> @@ -1140,8 +1135,9 @@ <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">"Axente de escoita de notificacións"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Axente de escoita de RV"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Provedor de condicións"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Asistente de notificacións"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Servizo de clasificación de notificacións"</string> <string name="vpn_title" msgid="19615213552042827">"VPN activada"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> activou a VPN"</string> <string name="vpn_text" msgid="3011306607126450322">"Toca aquí para xestionar a rede."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Soltar"</string> <string name="app_info" msgid="6856026610594615344">"Información da aplicación"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Restablecemento da configuración de fábrica para usar este dispositivo con normalidade"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toca para acceder a máis información"</string> </resources> diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml index 6b0553734341..6270867d1e03 100644 --- a/core/res/res/values-gu-rIN/strings.xml +++ b/core/res/res/values-gu-rIN/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"વૉઇસ સહાય"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"હવે લૉક કરો"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"સામગ્રીઓ છુપાવેલ છે"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"નીતિ દ્વારા સામગ્રી છુપાવાઈ"</string> <string name="safeMode" msgid="2788228061547930246">"સુરક્ષિત મોડ"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"વધુ વિકલ્પો માટે ટચ કરો."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ડીબગિંગ કનેક્ટ થયું."</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ડીબગિંગ અક્ષમ કરવા માટે ટચ કરો."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"બગ રિપોર્ટ લઈ રહ્યાં છે…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"બગ રિપોર્ટ શેર કરીએ?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"બગ રિપોર્ટ શેર કરી રહ્યાં છે…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"તમારા IT વ્યવસ્થાપક એ આ ઉપકરણની સમસ્યા નિવારણમાં સહાય માટે બગ રિપોર્ટની વિનંતી કરી છે. ઍપ્લિકેશનો અને ડેટા શેર કરવામાં આવી શકે છે."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"શેર કરો"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"નકારો"</string> <string name="select_input_method" msgid="8547250819326693584">"કીબોર્ડ બદલો"</string> <string name="configure_input_methods" msgid="4769971288371946846">"કીબોર્ડ્સ પસંદ કરો"</string> <string name="show_ime" msgid="2506087537466597099">"જ્યારે ભૌતિક કીબોર્ડ સક્રિય હોય ત્યારે તેને સ્ક્રીન પર રાખો"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"શરત પ્રદાતા"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"સૂચના સહાયક"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"સૂચના રેંકર સેવા"</string> <string name="vpn_title" msgid="19615213552042827">"VPN સક્રિય કર્યું"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> દ્વારા VPN સક્રિય થયું"</string> <string name="vpn_text" msgid="3011306607126450322">"નેટવર્કને સંચાલિત કરવા માટે ટચ કરો."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"અનપિન કરો"</string> <string name="app_info" msgid="6856026610594615344">"ઍપ્લિકેશન માહિતી"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"આ ઉપકરણને સામાન્ય રીતે ઉપયોગ કરવા માટે ફેક્ટરી રીસેટ કરો"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"વધુ જાણવા માટે ટચ કરો."</string> </resources> diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml index 6c55445f5725..82e1d83b1139 100644 --- a/core/res/res/values-hi/strings.xml +++ b/core/res/res/values-hi/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"वॉइस सहायक"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"अभी लॉक करें"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"छिपी हुई सामग्री"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"सामग्री पॉलिसी के द्वारा छिपी हुई है"</string> <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"और विकल्पों के लिए स्पर्श करें."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग कनेक्ट किया गया"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डीबग करना अक्षम करने के लिए स्पर्श करें."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"बग रिपोर्ट प्राप्त की जा रही है…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग रिपोर्ट साझा करें?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"बग रिपोर्ट साझा की जा रही है…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"आपके आईटी व्यवस्थापक ने इस डिवाइस के समस्या निवारण में सहायता के लिए एक बग रिपोर्ट का अनुरोध किया है. ऐप्स और डेटा को साझा किया जा सकता है."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"साझा करें"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"अस्वीकार करें"</string> <string name="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदलें"</string> <string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड चुनें"</string> <string name="show_ime" msgid="2506087537466597099">"भौतिक कीबोर्ड के सक्रिय होने के दौरान इसे स्क्रीन पर बनाए रखें"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"स्थिति प्रदाता"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"नोटिफिकेशन सहायक"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"नोटिफ़िकेशन रैंकर सेवा"</string> <string name="vpn_title" msgid="19615213552042827">"VPN सक्रिय"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN को <xliff:g id="APP">%s</xliff:g> द्वारा सक्रिय किया गया है"</string> <string name="vpn_text" msgid="3011306607126450322">"नेटवर्क प्रबंधित करने के लिए स्पर्श करें."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"अनपिन करें"</string> <string name="app_info" msgid="6856026610594615344">"ऐप की जानकारी"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"इस डिवाइस का सामान्य रूप से उपयोग करने के लिए फ़ैक्टरी रीसेट करें"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"अधिक जानने के लिए स्पर्श करें."</string> </resources> diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml index c32c5eeb1662..cd23a1af5075 100644 --- a/core/res/res/values-hr/strings.xml +++ b/core/res/res/values-hr/strings.xml @@ -231,7 +231,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Glasovna pomoć"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Zaključaj sada"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Sadržaj je skriven"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Sadržaj je skriven prema pravilima"</string> <string name="safeMode" msgid="2788228061547930246">"Siguran način rada"</string> @@ -1060,16 +1059,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Dodirnite za više opcija."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Priključen je alat za uklanjanje pogrešaka USB-om"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Dodirnite da se onemogući otklanjanje pogrešaka USB-om."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Izrada izvješća o programskoj pogrešci…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite li podijeliti izvješće o programskoj pogrešci?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Dijeljenje izvješća o programskoj pogrešci…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IT administrator zatražio je izvješće o programskoj pogrešci radi lakšeg rješavanja problema na uređaju. Moguće je da će se aplikacije i podaci dijeliti."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DIJELI"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODBIJ"</string> <string name="select_input_method" msgid="8547250819326693584">"Promjena tipkovnice"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Odaberi tipkovnice"</string> <string name="show_ime" msgid="2506087537466597099">"Zadržava se na zaslonu dok je fizička tipkovnica aktivna"</string> @@ -1148,8 +1143,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Pozadinska slika"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Promjena pozadinske slike"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Slušatelj obavijesti"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Slušatelj virtualne stvarnosti"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Davatalj uvjeta"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Pomoćnik za obavijesti"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Usluga rangiranja obavijesti"</string> <string name="vpn_title" msgid="19615213552042827">"VPN aktiviran"</string> <string name="vpn_title_long" msgid="6400714798049252294">"Aplikacija <xliff:g id="APP">%s</xliff:g> aktivirala je VPN"</string> <string name="vpn_text" msgid="3011306607126450322">"Dodirnite za upravljanje mrežom."</string> @@ -1587,4 +1583,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Otkvači"</string> <string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Uređaj je vraćen na tvorničke postavke da biste ga mogli upotrebljavati na pravilan način"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Dodirnite da biste saznali više."</string> </resources> diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml index 91f5280e24bf..ffa8d214543d 100644 --- a/core/res/res/values-hu/strings.xml +++ b/core/res/res/values-hu/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Hangsegéd"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Zárolás most"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Tartalom elrejtve"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"A tartalom irányelv miatt elrejtve"</string> <string name="safeMode" msgid="2788228061547930246">"Biztonsági üzemmód"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Érintse meg a további lehetőségekhez."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hibakereső csatlakoztatva"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Érintse meg az USB hibakeresés kikapcsolásához."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Hibajelentés készítése…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Megosztja a hibajelentést?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Hibajelentés megosztása…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"A rendszergazda hibajelentést kért, hogy segíthessen az eszközzel kapcsolatos probléma megoldásában. Előfordulhat, hogy a rendszer megosztja az alkalmazásokat és adatokat."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"MEGOSZTÁS"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ELUTASÍTÁS"</string> <string name="select_input_method" msgid="8547250819326693584">"Billentyűzet megváltoztatása"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Billentyűzetek kiválasztása"</string> <string name="show_ime" msgid="2506087537466597099">"Maradjon a képernyőn, amíg a billentyűzet aktív"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Háttérkép"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Háttérkép megváltoztatása"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Értesítésfigyelő"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Virtuálisvalóság-figyelő"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Feltételbiztosító"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Értesítési segéd"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Értesítésrangsoroló szolgáltatás"</string> <string name="vpn_title" msgid="19615213552042827">"VPN aktiválva"</string> <string name="vpn_title_long" msgid="6400714798049252294">"A(z) <xliff:g id="APP">%s</xliff:g> aktiválta a VPN-t"</string> <string name="vpn_text" msgid="3011306607126450322">"Érintse meg a hálózat kezeléséhez."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Feloldás"</string> <string name="app_info" msgid="6856026610594615344">"Alkalmazásinformáció"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Gyári beállítások visszaállítása az eszköz normál módú használatához"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Érintse meg a további információkért."</string> </resources> diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml index f009c7b16032..909a5c9b7c86 100644 --- a/core/res/res/values-hy-rAM/strings.xml +++ b/core/res/res/values-hy-rAM/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Ձայնային օգնութ"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Կողպել հիմա"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Բովանդակությունը թաքցված է"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Բովանդակությունը թաքցվել է ըստ քաղաքականության"</string> <string name="safeMode" msgid="2788228061547930246">"Անվտանգ ռեժիմ"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Հպեք՝ լրացուցիչ ընտրանքների համար:"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB վրիպազերծումը միացված է"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Հպեք` USB կարգաբերումը կասեցնելու համար:"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Վրիպակի զեկույցի ստեղծում…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Տրամադրե՞լ վրիպակի զեկույցը:"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Վրիպակի զեկույցի տրամադրում…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Այս սարքի անսարքությունների վերացման նպատակով ձեր ՏՏ ադմինիստրատորին անհրաժեշտ է վրիպակի զեկույց: Կարող են տրամադրվել տեղեկություններ ձեր հավելվածների մասին և այլ տվյալներ:"</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ՏՐԱՄԱԴՐԵԼ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ՄԵՐԺԵԼ"</string> <string name="select_input_method" msgid="8547250819326693584">"Փոխել ստեղնաշարը"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Ընտրել ստեղնաշար"</string> <string name="show_ime" msgid="2506087537466597099">"Պահել էկրանին մինչդեռ ֆիզիկական ստեղնաշարն ակտիվ է"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"Պայմանների մատակարար"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Ծանուցումների օգնական"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Ըստ կարևորության ծանուցումների դասակարգման ծառայություն"</string> <string name="vpn_title" msgid="19615213552042827">"VPN-ը ակտիվացված է"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN-ն ակտիվացված է <xliff:g id="APP">%s</xliff:g>-ի կողմից"</string> <string name="vpn_text" msgid="3011306607126450322">"Հպեք` ցանցի կառավարման համար:"</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Ապամրացնել"</string> <string name="app_info" msgid="6856026610594615344">"Հավելվածի տվյալներ"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Սարքը սովորական ռեժիմում օգտագործելու համար կատարեք գործարանային վերակայում"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Հպեք՝ ավելին իմանալու համար:"</string> </resources> diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml index 8351f343afc0..14b7526bf10a 100644 --- a/core/res/res/values-in/strings.xml +++ b/core/res/res/values-in/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Bantuan Suara"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Kunci sekarang"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Konten tersembunyi"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Konten disembunyikan menurut kebijakan"</string> <string name="safeMode" msgid="2788228061547930246">"Mode aman"</string> @@ -1136,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Ubah wallpaper"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Pendengar pemberitahuan"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Pemroses Realitas Maya"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Penyedia ketentuan"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Asisten notifikasi"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Layanan penentu peringkat notifikasi"</string> <string name="vpn_title" msgid="19615213552042827">"VPN diaktifkan"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN diaktifkan oleh <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Sentuh untuk mengelola jaringan."</string> @@ -1564,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Lepas pin"</string> <string name="app_info" msgid="6856026610594615344">"Info aplikasi"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Dikembalikan ke setelan pabrik untuk menggunakan perangkat ini secara normal"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Sentuh untuk mempelajari lebih lanjut."</string> </resources> diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml index f43adcf371c2..e3278f3823a4 100644 --- a/core/res/res/values-is-rIS/strings.xml +++ b/core/res/res/values-is-rIS/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Raddaðstoð"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Læsa núna"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Innihald falið"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Efni falið með reglu"</string> <string name="safeMode" msgid="2788228061547930246">"Örugg stilling"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Snertu til að fá fleiri valkosti."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-villuleit tengd"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Snertu til að slökkva á USB-villuleit."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Tekur við villutilkynningu…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Deila villutilkynningu?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deilir villutilkynningu..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Kerfisstjórinn þinn óskaði eftir villutilkynningu til að auðvelda úrræðaleit á þessu tæki. Forritum og gögnum verður hugsanlega deilt."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DEILA"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"HAFNA"</string> <string name="select_input_method" msgid="8547250819326693584">"Skipta um lyklaborð"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Velja lyklaborð"</string> <string name="show_ime" msgid="2506087537466597099">"Haltu því á skjánum meðan vélbúnaðarlyklaborðið er virkt"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Veggfóður"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Skipta um veggfóður"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Tilkynningahlustun"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Sýndarveruleikavöktun"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Skilyrðaveita"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Tilkynningaaðstoð"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Tilkynningaröðun"</string> <string name="vpn_title" msgid="19615213552042827">"VPN virkjað"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN er virkjað með <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Snertu til að hafa umsjón með netinu."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Losa"</string> <string name="app_info" msgid="6856026610594615344">"Forritsupplýsingar"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Núllstilltu til að nota þetta tæki í venjulegri stillingu"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Snertu til að fá frekari upplýsingar."</string> </resources> diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml index 9e02d34b3875..6f1c1ec12019 100644 --- a/core/res/res/values-it/strings.xml +++ b/core/res/res/values-it/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Blocca ora"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Contenuti nascosti"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contenuti nascosti in base alle norme"</string> <string name="safeMode" msgid="2788228061547930246">"Modalità provvisoria"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Tocca per visualizzare più opzioni."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Debug USB collegato"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Tocca per disattivare il debug USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Recupero della segnalazione di bug…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Condividere la segnalazione di bug?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Condivisione della segnalazione di bug…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"L\'amministratore IT ha richiesto una segnalazione di bug per poter risolvere più facilmente i problemi di questo dispositivo. Potrebbero essere condivisi dati e app."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"CONDIVIDI"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RIFIUTO"</string> <string name="select_input_method" msgid="8547250819326693584">"Cambia tastiera"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Scegli tastiera"</string> <string name="show_ime" msgid="2506087537466597099">"Tieni sullo schermo quando è attiva la tastiera fisica"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Sfondo"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Cambia sfondo"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Listener di notifica"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Listener realtà virtuale"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Provider condizioni"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Assistente notifica"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Servizio di classificazione delle notifiche"</string> <string name="vpn_title" msgid="19615213552042827">"VPN attiva"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN attivata da <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Tocca per gestire la rete."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Sblocca"</string> <string name="app_info" msgid="6856026610594615344">"Informazioni app"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Esegui il ripristino dei dati di fabbrica per utilizzare normalmente il dispositivo"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Tocca per ulteriori informazioni."</string> </resources> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 48c4c29758a9..c79befabcc68 100644 --- a/core/res/res/values-iw/strings.xml +++ b/core/res/res/values-iw/strings.xml @@ -233,7 +233,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"נעל עכשיו"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"התוכן מוסתר"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"התוכן מוסתר על ידי המדיניות"</string> <string name="safeMode" msgid="2788228061547930246">"מצב בטוח"</string> @@ -1152,8 +1151,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"ספק תנאי"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"אסיסטנט ההודעות"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"שירות של דירוג הודעות"</string> <string name="vpn_title" msgid="19615213552042827">"VPN מופעל"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN מופעל על ידי <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"גע כדי לנהל את הרשת."</string> @@ -1602,4 +1602,6 @@ <string name="unpin_target" msgid="3556545602439143442">"בטל הצמדה"</string> <string name="app_info" msgid="6856026610594615344">"פרטי אפליקציה"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"איפוס להגדרות היצרן לצורך שימוש במכשיר זה באופן רגיל"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"גע לקבלת מידע נוסף."</string> </resources> diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml index 810d70de5bb6..5c9729532bd8 100644 --- a/core/res/res/values-ja/strings.xml +++ b/core/res/res/values-ja/strings.xml @@ -213,8 +213,7 @@ <string name="bugreport_option_interactive_title" msgid="8635056131768862479">"対話型レポート"</string> <string name="bugreport_option_interactive_summary" msgid="8180152634022797629">"ほとんどの場合はこのオプションを使用します。レポートの進行状況を追跡し、問題についての詳細情報を確認することができます。レポート作成に時間がかかってもあまり使用されないセクションは省略されることがあります。"</string> <string name="bugreport_option_full_title" msgid="6354382025840076439">"完全レポート"</string> - <!-- no translation found for bugreport_option_full_summary (6687306111256813257) --> - <skip /> + <string name="bugreport_option_full_summary" msgid="6687306111256813257">"端末の反応がないとき、または速度が遅すぎるときにシステムへの影響を最小限に抑えたい場合は、このオプションを使用します。またすべてのレポート セクションを表示したい場合にもこのオプションを使用します。スクリーンショットは作成されず、詳細情報も表示できません。"</string> <plurals name="bugreport_countdown" formatted="false" msgid="6878900193900090368"> <item quantity="other"><xliff:g id="NUMBER_1">%d</xliff:g> 秒後にバグレポートのスクリーンショットが作成されます。</item> <item quantity="one"><xliff:g id="NUMBER_0">%d</xliff:g> 秒後にバグレポートのスクリーンショットが作成されます。</item> @@ -230,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"音声アシスト"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"今すぐロック"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g> 件)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"コンテンツが非表示"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ポリシーによって非表示になっているコンテンツ"</string> <string name="safeMode" msgid="2788228061547930246">"セーフモード"</string> @@ -1053,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"タップしてその他のオプションを表示"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USBデバッグが接続されました"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"タップしてUSBデバッグを無効化"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"バグレポートを取得しています…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"バグレポートを共有しますか?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"バグレポートの共有中…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IT 管理者からこの端末のトラブルシューティングに役立てるためバグレポートを共有するようリクエストがありました。アプリやデータが共有されることがあります。"</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"共有する"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"共有しない"</string> <string name="select_input_method" msgid="8547250819326693584">"キーボードの変更"</string> <string name="configure_input_methods" msgid="4769971288371946846">"キーボードの選択"</string> <string name="show_ime" msgid="2506087537466597099">"物理キーボードが有効になっている間は、画面に表示されます"</string> @@ -1141,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"コンディションプロバイダ"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"通知アシスタント"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"通知ランカー サービス"</string> <string name="vpn_title" msgid="19615213552042827">"VPNが有効になりました"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPNが<xliff:g id="APP">%s</xliff:g>により有効化されました"</string> <string name="vpn_text" msgid="3011306607126450322">"タップしてネットワークを管理します。"</string> @@ -1551,16 +1546,11 @@ <string name="language_picker_section_suggested" msgid="8414489646861640885">"言語の候補"</string> <string name="language_picker_section_all" msgid="3097279199511617537">"すべての言語"</string> <string name="locale_search_menu" msgid="2560710726687249178">"検索"</string> - <!-- no translation found for work_mode_off_title (8954725060677558855) --> - <skip /> - <!-- no translation found for work_mode_off_message (3286169091278094476) --> - <skip /> - <!-- no translation found for work_mode_turn_on (2062544985670564875) --> - <skip /> - <!-- no translation found for suspended_package_title (3408150347778524435) --> - <skip /> - <!-- no translation found for suspended_package_message (6341091587106868601) --> - <skip /> + <string name="work_mode_off_title" msgid="8954725060677558855">"Work モード OFF"</string> + <string name="work_mode_off_message" msgid="3286169091278094476">"仕事用プロファイルで、アプリ、バックグラウンド同期などの関連機能の使用を許可します。"</string> + <string name="work_mode_turn_on" msgid="2062544985670564875">"ON にする"</string> + <string name="suspended_package_title" msgid="3408150347778524435">"%1$sが無効です"</string> + <string name="suspended_package_message" msgid="6341091587106868601">"%1$s管理者によって無効になっています。詳しくは管理者までお問い合わせください。"</string> <string name="new_sms_notification_title" msgid="8442817549127555977">"新着メッセージがあります"</string> <string name="new_sms_notification_content" msgid="7002938807812083463">"表示するには SMS アプリを開きます"</string> <string name="user_encrypted_title" msgid="9054897468831672082">"一部機能が制限されている可能性"</string> @@ -1574,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"固定を解除"</string> <string name="app_info" msgid="6856026610594615344">"アプリ情報"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"この端末は正常に使用するために出荷時設定にリセットされました"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"タップして詳細をご確認ください。"</string> </resources> diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml index 0b164eb11021..15167f735215 100644 --- a/core/res/res/values-ka-rGE/strings.xml +++ b/core/res/res/values-ka-rGE/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"ხმოვანი ასისტ."</string> <string name="global_action_lockdown" msgid="8751542514724332873">"ახლა ჩაკეტვა"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"შიგთავსი დამალულია"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"შიგთავსი დამალულია წესების შესაბამისად"</string> <string name="safeMode" msgid="2788228061547930246">"უსაფრთხო რეჟიმი"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"შეეხეთ დამატებითი პარამეტრებისთვის."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB გამართვა შეერთებულია"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"შეეხეთ, რათა შეწყვიტოთ USB-ის გამართვა."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"მიმდინარეობს ხარვეზის შესახებ ანგარიშის შექმნა…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"გსურთ ხარვეზის შესახებ ანგარიშის გაზიარება?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"მიმდინარეობს ხარვეზის შესახებ ანგარიშის გაზიარება…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"ამ მოწყობილობის პრობლემების აღმოფხვრაში დასახმარებლად, თქვენი IT ადმინისტრატორი ხარვეზის შესახებ ანგარიშს ითხოვს, რა დროსაც შეიძლება გაზიარდეს აპები და მონაცემები."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"გაზიარება"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"უარყოფა"</string> <string name="select_input_method" msgid="8547250819326693584">"კლავიატურის შეცვლა"</string> <string name="configure_input_methods" msgid="4769971288371946846">"კლავიატურების არჩევა"</string> <string name="show_ime" msgid="2506087537466597099">"აქტიური ფიზიკური კლავიატურისას ეკრანზე შენარჩუნება"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"მდგომარეობის პროვაიდერი"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"შეტყობინებათა ასისტენტი"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"შეტყობინებების მნიშვნელობის დონის შეფასების სერვისი"</string> <string name="vpn_title" msgid="19615213552042827">"VPN გააქტიურებულია"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN გააქტიურებულია <xliff:g id="APP">%s</xliff:g>-ის მიერ"</string> <string name="vpn_text" msgid="3011306607126450322">"შეეხეთ ქსელის სამართავად."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"ჩამაგრების მოხსნა"</string> <string name="app_info" msgid="6856026610594615344">"აპის შესახებ"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"ამ მოწყობილობის ჩვეულებრივად გამოსაყენებლად, დააბრუნეთ ქარხნული პარამეტრები"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"შეეხეთ მეტის გასაგებად."</string> </resources> diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml index d803c500f83f..6d31dd1f195d 100644 --- a/core/res/res/values-kk-rKZ/strings.xml +++ b/core/res/res/values-kk-rKZ/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Дауыс көмекшісі"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Қазір бекіту"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Мазмұн жасырылған"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Мазмұн саясатқа сай жасырылған"</string> <string name="safeMode" msgid="2788228061547930246">"Қауіпсіз режим"</string> @@ -1052,10 +1051,10 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Қосымша параметрлер үшін түртіңіз."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB жөндеу қосылған"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB жөндеуді өшіру үшін түртіңіз."</string> - <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Қате туралы есеп құрылуда…"</string> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Қате туралы есеп алынуда…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Қате туралы есепті бөлісу керек пе?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Қате туралы есеп бөлісілуде…"</string> - <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"АТ әкімшісі осы құрылғы ақауларын жоюға көмектесу үшін қате туралы есепті сұрады. Қолданбалар және деректер бөлісілуі мүмкін."</string> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"АТ әкімшісі осы құрылғы ақауларын жоюға көмектесу үшін қате туралы есепті сұрады. Қолданбалар мен деректерді бөлісуі мүмкін."</string> <string name="share_remote_bugreport_action" msgid="6249476773913384948">"БӨЛІСУ"</string> <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ҚАБЫЛДАМАУ"</string> <string name="select_input_method" msgid="8547250819326693584">"Пернетақтаны өзгерту"</string> @@ -1136,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"Шарт провайдері"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Хабарландыру көмекшісі"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Хабарландыруларды жіктеу қызметі"</string> <string name="vpn_title" msgid="19615213552042827">"VPN белсенді"</string> <string name="vpn_title_long" msgid="6400714798049252294">"ВЖЭ <xliff:g id="APP">%s</xliff:g> арқылы қосылған"</string> <string name="vpn_text" msgid="3011306607126450322">"Желіні басқару үшін түрту."</string> @@ -1564,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Босату"</string> <string name="app_info" msgid="6856026610594615344">"Қолданба ақпараты"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Осы құрылғыны әдеттегідей пайдалану үшін зауыттық параметрлерді қалпына келтіріңіз"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Қосымша мәліметтер алу үшін түртіңіз."</string> </resources> diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml index 9f9e961578fb..e3e46b05ccad 100644 --- a/core/res/res/values-km-rKH/strings.xml +++ b/core/res/res/values-km-rKH/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"ជំនួយសម្លេង"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"ចាក់សោឥឡូវនេះ"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"បានលាក់មាតិកា"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"មាតិកាត្រូវបានលាក់ដោយផ្អែកលើគោលការណ៍"</string> <string name="safeMode" msgid="2788228061547930246">"របៀបសុវត្ថិភាព"</string> @@ -1054,16 +1053,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"ប៉ះដើម្បីបានជម្រើសថែមទៀត។"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"បានភ្ជាប់ការកែកំហុសយូអេសប៊ី"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"ប៉ះ ដើម្បីបិទការកែកំហុសយូអេសប៊ី។"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"កំពុងទទួលយករបាយការណ៍កំហុស…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ចែករំលែករបាយការណ៍កំហុសឬ?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"កំពុងចែករំលែករបាយកំហុស…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"អ្នកគ្រប់គ្រងផ្នែកព័ត៌មានវិទ្យារបស់អ្នកបានស្នើរបាយការណ៍កំហុសដើម្បីដោះស្រាយកំហុសឧបករណ៍នេះ។ កម្មវិធី និងទិន្នន័យអាចនឹងត្រូវបានចែករំលែក។"</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ចែករំលែក"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"បដិសេធ"</string> <string name="select_input_method" msgid="8547250819326693584">"ប្ដូរក្ដារចុច"</string> <string name="configure_input_methods" msgid="4769971288371946846">"ជ្រើសក្ដារចុច"</string> <string name="show_ime" msgid="2506087537466597099">"ទុកវានៅលើអេក្រង់ខណៈពេលក្តារចុចពិតប្រាកដកំពុងសកម្ម"</string> @@ -1142,8 +1137,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"ក្រុមហ៊ុនផ្ដល់លក្ខខណ្ឌ"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"ជំនួយការជូនដំណឹង"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"សេវាកម្មវាយតម្លៃការជូនដំណឹង"</string> <string name="vpn_title" msgid="19615213552042827">"បានធ្វើឲ្យ VPN សកម្ម"</string> <string name="vpn_title_long" msgid="6400714798049252294">"បានធ្វើឲ្យ VPN សកម្មដោយ <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"ប៉ះ ដើម្បីគ្រប់គ្រងបណ្ដាញ។"</string> @@ -1570,4 +1566,6 @@ <string name="unpin_target" msgid="3556545602439143442">"មិនខ្ទាស់"</string> <string name="app_info" msgid="6856026610594615344">"ព័ត៌មានកម្មវិធី"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"កំណត់ដូចចេញពីរោងចក្រឡើងវិញដើម្បីប្រើឧបករណ៍នេះតាមធម្មតា"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"ប៉ះ ដើម្បីស្វែងយល់បន្ថែម។"</string> </resources> diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml index 46ef93167487..7a41d4bb7077 100644 --- a/core/res/res/values-kn-rIN/strings.xml +++ b/core/res/res/values-kn-rIN/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"ಧ್ವನಿ ಸಹಾಯಕ"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"ಈಗ ಲಾಕ್ ಮಾಡಿ"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"ವಿಷಯಗಳನ್ನು ಮರೆಮಾಡಲಾಗಿದೆ"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ನೀತಿಯಿಂದ ಮರೆಮಾಡಲಾಗಿರುವ ವಿಷಯಗಳು"</string> <string name="safeMode" msgid="2788228061547930246">"ಸುರಕ್ಷಿತ ಮೋಡ್"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗೆ ಸ್ಪರ್ಶಿಸಿ."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ಡೀಬಗಿಂಗ್ ಸಂಪರ್ಕ"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ಡೀಬಗಿಂಗ್ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಸ್ಪರ್ಶಿಸಿ."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ದೋಷದ ವರದಿಯನ್ನು ತೆಗೆದುಕೊಳ್ಳಲಾಗುತ್ತಿದೆ…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ಬಗ್ ವರದಿಯನ್ನು ಹಂಚುವುದೇ?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ಬಗ್ ವರದಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಲಾಗುತ್ತಿದೆ…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"ಈ ಸಾಧನದ ಸಮಸ್ಯೆ ನಿವಾರಿಸಲು ಸಹಾಯ ಮಾಡಲು ನಿಮ್ಮ IT ನಿರ್ವಾಹಕರು ಬಗ್ ವರದಿಯನ್ನು ವಿನಂತಿಸಿದ್ದಾರೆ. ಅಪ್ಲಿಕೇಶನ್ಗಳು ಮತ್ತು ಡೇಟಾವನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ಹಂಚಿಕೊಳ್ಳಿ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ನಿರಾಕರಿಸು"</string> <string name="select_input_method" msgid="8547250819326693584">"ಕೀಬೋರ್ಡ್ ಬದಲಿಸಿ"</string> <string name="configure_input_methods" msgid="4769971288371946846">"ಕೀಬೋರ್ಡ್ಗಳನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string> <string name="show_ime" msgid="2506087537466597099">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್ ಸಕ್ರಿಯವಾಗಿರುವಾಗ ಅದನ್ನು ಪರದೆಯ ಮೇಲೆ ಇರಿಸಿಕೊಳ್ಳಿ"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"ಕಂಡೀಶನ್ ಪೂರೈಕೆದಾರರು"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"ಅಧಿಸೂಚನೆ ಸಹಾಯಕ"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"ಅಧಿಸೂಚನೆ ಶ್ರೇಣಿಯ ಸೇವೆ"</string> <string name="vpn_title" msgid="19615213552042827">"VPN ಸಕ್ರಿಯಗೊಂಡಿದೆ"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> ಮೂಲಕ VPN ಸಕ್ರಿಯಗೊಂಡಿದೆ"</string> <string name="vpn_text" msgid="3011306607126450322">"ನೆಟ್ವರ್ಕ್ ನಿರ್ವಹಿಸಲು ಸ್ಪರ್ಶಿಸಿ"</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"ಅನ್ಪಿನ್"</string> <string name="app_info" msgid="6856026610594615344">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"ಈ ಸಾಧನವನ್ನು ಸಾಮಾನ್ಯ ರೀತಿಯಲ್ಲಿ ಬಳಸಲು ಫ್ಯಾಕ್ಟರಿ ರಿಸೆಟ್ ಮಾಡಿ"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಸ್ಪರ್ಶಿಸಿ."</string> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index f8d0598d2f49..b236d398d0a3 100644 --- a/core/res/res/values-ko/strings.xml +++ b/core/res/res/values-ko/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"음성 지원"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"지금 잠그기"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>개)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"숨겨진 콘텐츠"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"콘텐츠가 정책에 의해 숨겨졌습니다."</string> <string name="safeMode" msgid="2788228061547930246">"안전 모드"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"더 많은 옵션을 확인하려면 터치하세요."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB 디버깅 연결됨"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB 디버깅을 사용하지 않으려면 터치하세요."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"버그 보고서 가져오는 중..."</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"버그 보고서를 공유하시겠습니까?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"버그 신고서 공유 중..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IT 관리자가 이 기기의 문제해결을 위해 버그 보고서를 요청했습니다. 앱과 데이터가 공유될 수 있습니다."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"공유"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"거부"</string> <string name="select_input_method" msgid="8547250819326693584">"키보드 변경"</string> <string name="configure_input_methods" msgid="4769971288371946846">"키보드 선택"</string> <string name="show_ime" msgid="2506087537466597099">"물리적 키보드가 활성 상태인 경우 화면에 켜 둠"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"조건 제공자"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"알림 어시스턴트"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"알림 순위 지정 서비스"</string> <string name="vpn_title" msgid="19615213552042827">"VPN이 활성화됨"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN이 <xliff:g id="APP">%s</xliff:g>에 의해 활성화됨"</string> <string name="vpn_text" msgid="3011306607126450322">"네트워크를 관리하려면 터치하세요."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"고정 해제"</string> <string name="app_info" msgid="6856026610594615344">"앱 정보"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"정상적인 기기 사용을 위한 초기화"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"자세한 내용을 보려면 터치하세요."</string> </resources> diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml index 8670af073691..3a30b55fb7a4 100644 --- a/core/res/res/values-ky-rKG/strings.xml +++ b/core/res/res/values-ky-rKG/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Үн жардамчысы"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Азыр кулпулоо"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Мазмундар жашырылган"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Тийиштүү саясат боюнча жашырылган мазмундар"</string> <string name="safeMode" msgid="2788228061547930246">"Коопсуз режим"</string> @@ -1053,16 +1052,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Көбүрөөк параметр үчүн тийип коюңуз."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB мүчүлүштүктөрдү оңдоо туташтырылган"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB мүчүлүштүктөрдү жоюу мүмкүнчүлүгүн өчүрүү үчүн тийип коюңуз."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Мүчүлүштүк тууралуу кабар алынууда…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Мүчүлүштүк тууралуу баяндама бөлүшүлсүнбү?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Мүчүлүштүк тууралуу баяндама бөлүшүлүүдө…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Бул түзмөктүн бузулууларын аныктап оңдоо үчүн IT администраторуңуз мүчүлүштүктөр тууралуу маалыматты сурап жатат. Колдонмолор менен дайындар бөлүшүлүшү мүмкүн."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"БӨЛҮШҮҮ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ЧЕТКЕ КАГУУ"</string> <string name="select_input_method" msgid="8547250819326693584">"Баскычтопту өзгөртүү"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Баскычтопторду тандаңыз"</string> <string name="show_ime" msgid="2506087537466597099">"Баскычтоп иштетилгенде экранда көрүнүп турсун"</string> @@ -1141,8 +1136,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"Шарт түзүүчү"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Эскертме жардамчысы"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Эскертмени баалоо кызматы"</string> <string name="vpn_title" msgid="19615213552042827">"VPN иштетилди"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN <xliff:g id="APP">%s</xliff:g> аркылуу жандырылды"</string> <string name="vpn_text" msgid="3011306607126450322">"желени башкаруу үчүн басыңыз."</string> @@ -1569,4 +1565,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Кадоодон алып коюу"</string> <string name="app_info" msgid="6856026610594615344">"Колдонмо тууралуу"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Бул түзмөктү кадимкидей колдонуу үчүн заводдук баштапкы абалына келтириңиз"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Көбүрөөк билүү үчүн тийип коюңуз."</string> </resources> diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml index 8f9d820f72c4..5ad178673fad 100644 --- a/core/res/res/values-lo-rLA/strings.xml +++ b/core/res/res/values-lo-rLA/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"ຊ່ວຍເຫຼືອທາງສຽງ"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"ລັອກດຽວນີ້"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"ເນື້ອຫາຖືກເຊື່ອງໄວ້"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ເນື້ອຫາຖືກເຊື່ອງຕາມນະໂຍບາຍ"</string> <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string> @@ -1136,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"ຜູ່ສະໜອງເງື່ອນໄຂ"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"ຕົວຊ່ວຍການແຈ້ງເຕືອນ"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"ບໍລິການຈັດອັນດັບການແຈ້ງເຕືອນ"</string> <string name="vpn_title" msgid="19615213552042827">"ເປີດນຳໃຊ້ VPN ແລ້ວ"</string> <string name="vpn_title_long" msgid="6400714798049252294">"ເປີດໃຊ້ VPN ໂດຍ <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"ແຕະເພື່ອຈັດການເຄືອຂ່າຍ."</string> @@ -1564,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"ຖອນປັກໝຸດ"</string> <string name="app_info" msgid="6856026610594615344">"ຂໍ້ມູນແອັບ"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"ຣີເຊັດເປັນຄ່າໂຮງງານເພື່ອໃຊ້ອຸປະກອນນີ້ປົກກະຕິ"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ."</string> </resources> diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml index 8e8f5b8a9cf7..5496adaf6e07 100644 --- a/core/res/res/values-lt/strings.xml +++ b/core/res/res/values-lt/strings.xml @@ -233,7 +233,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Užrakinti dabar"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Turinys paslėptas"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Turinys paslėptas vadovaujantis politika"</string> <string name="safeMode" msgid="2788228061547930246">"Saugos režimas"</string> @@ -1068,16 +1067,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Palieskite, kad būtų rodoma daugiau parinkčių."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB derinimas prijungtas"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Neleisti USB derinimo."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Pateikiamas pranešimas apie riktą…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Bendrinti pranešimą apie riktą?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Bendrinamas pranešimas apie riktą..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Jūsų IT administratorius pateikė pranešimo apie riktą užklausą, kad galėtų padėti pašalinti triktis šiame įrenginyje. Programos ir duomenys gali būti bendrinami."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"BENDRINTI"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ATMESTI"</string> <string name="select_input_method" msgid="8547250819326693584">"Klaviatūros keitimas"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Pasirinkti klaviatūras"</string> <string name="show_ime" msgid="2506087537466597099">"Palikti ekrane, kol fizinė klaviatūra aktyvi"</string> @@ -1156,8 +1151,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Darbalaukio fonas"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Keisti darbalaukio foną"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Pranešimų skaitymo priemonė"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Virtualiosios realybės apdorojimo priemonė"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Sąlygos teikėjas"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Pranešimų pagelbiklis"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Pranešimų reitingavimo paslauga"</string> <string name="vpn_title" msgid="19615213552042827">"VPN suaktyvintas"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN suaktyvino „<xliff:g id="APP">%s</xliff:g>“"</string> <string name="vpn_text" msgid="3011306607126450322">"Palieskite, kad valdytumėte tinklą."</string> @@ -1606,4 +1602,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Atsegti"</string> <string name="app_info" msgid="6856026610594615344">"Programos informacija"</string> <string name="negative_duration" msgid="5688706061127375131">"–<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Atkurkite gamyklinius nustatymus, kad galėtumėte įprastai naudoti šį įrenginį"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Palieskite, kad sužinotumėte daugiau."</string> </resources> diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml index 5b1710560ea6..59ffdc3224f4 100644 --- a/core/res/res/values-lv/strings.xml +++ b/core/res/res/values-lv/strings.xml @@ -231,7 +231,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Balss palīgs"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Bloķēt tūlīt"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"Pārsniedz"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Saturs paslēpts"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Saskaņā ar politiku saturs ir paslēpts."</string> <string name="safeMode" msgid="2788228061547930246">"Drošais režīms"</string> @@ -1060,16 +1059,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Citas opcijas"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB atkļūdošana ir pievienota."</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Iespējot USB atkļūdošanu."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Notiek kļūdas pārskata izveide…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vai kopīgot kļūdas pārskatu?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Notiek kļūdas pārskata kopīgošana…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Jūsu IT administrators pieprasīja kļūdas pārskatu, lai palīdzētu novērst problēmu šajā ierīcē. Var tikt kopīgotas lietotnes un dati."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"KOPĪGOT"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"NORAIDĪT"</string> <string name="select_input_method" msgid="8547250819326693584">"Tastatūras maiņa"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Izvēlēties tastatūru"</string> <string name="show_ime" msgid="2506087537466597099">"Paturēt ekrānā, kamēr ir aktīva fiziskā tastatūra"</string> @@ -1148,8 +1143,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Fona tapete"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Tapetes maiņa"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Paziņojumu uztvērējs"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR klausītājs"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Nosacījumu sniedzējs"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Paziņojumu palīgs"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Paziņojumu ranžēšanas pakalpojums"</string> <string name="vpn_title" msgid="19615213552042827">"VPN ir aktivizēts."</string> <string name="vpn_title_long" msgid="6400714798049252294">"Lietojumprogramma <xliff:g id="APP">%s</xliff:g> aktivizēja VPN."</string> <string name="vpn_text" msgid="3011306607126450322">"Pieskarieties, lai pārvaldītu tīklu."</string> @@ -1587,4 +1583,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Atspraust"</string> <string name="app_info" msgid="6856026610594615344">"Lietotnes informācija"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Rūpnīcas datu atiestatīšana ierīces normālai darbībai"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Pieskarieties, lai uzzinātu vairāk."</string> </resources> diff --git a/core/res/res/values-mcc232-mnc11/config.xml b/core/res/res/values-mcc232-mnc11/config.xml new file mode 100644 index 000000000000..91e37b446077 --- /dev/null +++ b/core/res/res/values-mcc232-mnc11/config.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + ** Copyright 2016, The Android Open Source Project + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + */ +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Don't use roaming icon for considered operators --> + <string-array translatable="false" name="config_operatorConsideredNonRoaming"> + <item>23201</item> + </string-array> +</resources> diff --git a/core/res/res/values-mcc232-mnc12/config.xml b/core/res/res/values-mcc232-mnc12/config.xml new file mode 100644 index 000000000000..91e37b446077 --- /dev/null +++ b/core/res/res/values-mcc232-mnc12/config.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* + ** Copyright 2016, The Android Open Source Project + ** + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** + ** http://www.apache.org/licenses/LICENSE-2.0 + ** + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + */ +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- Don't use roaming icon for considered operators --> + <string-array translatable="false" name="config_operatorConsideredNonRoaming"> + <item>23201</item> + </string-array> +</resources> diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml index d59d1f3022e9..d0a7b20e8bbd 100644 --- a/core/res/res/values-mk-rMK/strings.xml +++ b/core/res/res/values-mk-rMK/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласовна помош"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Заклучи сега"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Содржините се скриени"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Содржините се скриени поради политиката"</string> <string name="safeMode" msgid="2788228061547930246">"Безбеден режим"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Допри за повеќе опции."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Поврзано е отстранување грешки преку УСБ"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Допрете за да се оневозможи отстранувањето грешки преку USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Се зема извештајот за грешки…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Да се сподели извештајот за грешки?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Се споделува извештај за грешки…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Вашиот администратор за информатичка технологија побара извештај за грешки за да ви помогне во отстранувањето на грешките на овој уред. Апликациите и податоците може да бидат споделени."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"СПОДЕЛИ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ОДБИЈ"</string> <string name="select_input_method" msgid="8547250819326693584">"Измени тастатура"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Избери тастатури"</string> <string name="show_ime" msgid="2506087537466597099">"Прикажувај го на екранот додека е активна физичката тастатура"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"Давател на услов"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Помошник за известувања"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Услуга за рангирање известувања"</string> <string name="vpn_title" msgid="19615213552042827">"Активирана VPN"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN е активирана со <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Допри за да управуваш со мрежата."</string> @@ -1570,4 +1566,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Откачете"</string> <string name="app_info" msgid="6856026610594615344">"Информации за апликација"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Ресетирање на фабрички вредности за уредот да се користи нормално"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Допрете за да дознаете повеќе."</string> </resources> diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml index 61fadeaba871..829e06aac987 100644 --- a/core/res/res/values-ml-rIN/strings.xml +++ b/core/res/res/values-ml-rIN/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"വോയ്സ് സഹായം"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"ഇപ്പോൾ ലോക്കുചെയ്യുക"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"കോൺടാക്റ്റുകൾ മറച്ചു"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"നയം അനുസരിച്ച് ഉള്ളടക്കം മറച്ചിരിക്കുന്നു"</string> <string name="safeMode" msgid="2788228061547930246">"സുരക്ഷിത മോഡ്"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് സ്പർശിക്കൂ."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ഡീബഗ്ഗിംഗ് കണക്റ്റുചെയ്തു"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ഡീബഗ്ഗിംഗ് ഓഫാക്കാൻ സ്പർശിക്കൂ."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ബഗ് റിപ്പോർട്ട് എടുക്കുന്നു…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ബഗ് റിപ്പോർട്ട് പങ്കിടണോ?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ബഗ് റിപ്പോർട്ട് പങ്കിടുന്നു…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"ഈ ഉപകരണത്തിലെ പ്രശ്നം പരിഹരിക്കുന്നതിന് നിങ്ങളുടെ ഐടി അഡ്മിൻ ഒരു ബഗ് റിപ്പോർട്ട് അഭ്യർത്ഥിച്ചു. ആപ്സും ഡാറ്റയും പങ്കിടപ്പെട്ടേക്കും."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"പങ്കിടുക"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"നിരസിക്കുക"</string> <string name="select_input_method" msgid="8547250819326693584">"കീബോഡ് മാറ്റുക"</string> <string name="configure_input_methods" msgid="4769971288371946846">"കീബോർഡുകൾ തിരഞ്ഞെടുക്കുക"</string> <string name="show_ime" msgid="2506087537466597099">"ഫിസിക്കൽ കീബോർഡ് സജീവമായിരിക്കുമ്പോൾ സ്ക്രീനിൽ നിലനിർത്തുക"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"കണ്ടീഷൻ ദാതാവ്"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"അറിയിപ്പ് സഹായി"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"അറിയിപ്പ് റാങ്കർ സേവനം"</string> <string name="vpn_title" msgid="19615213552042827">"VPN സജീവമാക്കി"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> ഉപയോഗിച്ച് VPN പ്രവർത്തനക്ഷമമാക്കി"</string> <string name="vpn_text" msgid="3011306607126450322">"നെറ്റ്വർക്ക് നിയന്ത്രിക്കാൻ സ്പർശിക്കുക."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"അൺപിൻ ചെയ്യുക"</string> <string name="app_info" msgid="6856026610594615344">"ആപ്പ് വിവരം"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"ഈ ഉപകരണം സാധാരണ നിലയിൽ ഉപയോഗിക്കാൻ ഫാക്ടറി പുനഃസജ്ജീകരണം നടത്തുക"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"കൂടുതലറിയുന്നതിന് സ്പർശിക്കുക."</string> </resources> diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml index 1f683cb686eb..9414f4e646a1 100644 --- a/core/res/res/values-mn-rMN/strings.xml +++ b/core/res/res/values-mn-rMN/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Дуут туслах"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Одоо түгжих"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Контентыг нуусан"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Удирдамжийн дагуу нуусан агуулга"</string> <string name="safeMode" msgid="2788228061547930246">"Аюулгүй горим"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Нэмэлт сонголтыг харахын тулд дарна."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB дебаг холбогдсон"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB дебагийг идэвхгүй болгох бол хүрнэ үү."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Алдааны тайланг авч байна..."</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Алдааны тайланг хуваалцах уу?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Алдааны тайланг хуваалцаж байна..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Энэ төхөөрөмжийн асуудлыг шийдвэрлэхийн тулд таны IT админ алдааны тайланг хүслээ. Апп болон өгөгдлийг хуваалцсан байж болзошгүй."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ХУВААЛЦАХ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ТАТГАЛЗАХ"</string> <string name="select_input_method" msgid="8547250819326693584">"Гарыг өөрчлөх"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Гар сонгох"</string> <string name="show_ime" msgid="2506087537466597099">"Бодит гар идэвхтэй үед үүнийг дэлгэцэнд харуулна уу"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"Нөхцөл нийлүүлэгч"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Мэдэгдлийн туслагч"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Мэдэгдлийг ангилах үйлчилгээ"</string> <string name="vpn_title" msgid="19615213552042827">"VPN идэвхтэй болов"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN-г <xliff:g id="APP">%s</xliff:g> идэвхтэй болгов"</string> <string name="vpn_text" msgid="3011306607126450322">"Сүлжээг удирдах бол хүрнэ үү."</string> @@ -1566,4 +1562,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Unpin"</string> <string name="app_info" msgid="6856026610594615344">"Апп-н мэдээлэл"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Энэ төхөөрөмжийг хэвийн ашиглахын тулд үйлдвэрийн тохиргоонд дахин тохируулна уу"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Дэлгэрэнгүй үзэх бол дарна уу."</string> </resources> diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml index 91b27ecab8bf..67351eac138b 100644 --- a/core/res/res/values-mr-rIN/strings.xml +++ b/core/res/res/values-mr-rIN/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"व्हॉइस सहाय्य"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"आता लॉक करा"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"लपविलेली सामग्री"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"धोरणाद्वारे सामग्री लपविली"</string> <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"अधिक पर्यायांसाठी स्पर्श करा."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB डीबग करणे कनेक्ट केले"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB डीबग करणे अक्षम करण्यासाठी स्पर्श करा."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"दोष अहवाल घेत आहे..."</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"बग अहवाल सामायिक करायचा?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"दोष अहवाल सामायिक करीत आहे..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"आपल्या IT प्रशासकाने या डिव्हाइसच्या समस्येचे निवारण करण्यात मदत करण्यासाठी दोष अहवालाची विनंती केली. अॅप्स आणि डेटा सामायिक केले जाऊ शकतात."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"सामायिक करा"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"नकार द्या"</string> <string name="select_input_method" msgid="8547250819326693584">"कीबोर्ड बदला"</string> <string name="configure_input_methods" msgid="4769971288371946846">"कीबोर्ड निवडा"</string> <string name="show_ime" msgid="2506087537466597099">"भौतिक कीबोर्ड सक्रिय असताना त्यास स्क्रीनवर ठेवा"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"अट प्रदाता"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"सूचना सहाय्यक"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"सूचना रॅंकर सेवा"</string> <string name="vpn_title" msgid="19615213552042827">"VPN सक्रिय"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> द्वारे VPN सक्रिय केले आहे"</string> <string name="vpn_text" msgid="3011306607126450322">"नेटवर्क व्यवस्थापित करण्यासाठी स्पर्श करा."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"अनपिन करा"</string> <string name="app_info" msgid="6856026610594615344">"अॅप माहिती"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"हे डिव्हाइस सामान्यपणे वापरण्यासाठी फॅक्टरी रीसेट करा"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"अधिक जाणून घेण्यासाठी स्पर्श करा."</string> </resources> diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml index 55556632da6b..5c342f0608e3 100644 --- a/core/res/res/values-ms-rMY/strings.xml +++ b/core/res/res/values-ms-rMY/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Bantuan Suara"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Kunci sekarang"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Kandungan tersembunyi"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Kandungan disembunyikan oleh dasar"</string> <string name="safeMode" msgid="2788228061547930246">"Mod selamat"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Sentuh untuk mendapatkan lagi pilihan."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Penyahpepijatan USB disambungkan"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Sentuh untuk melumpuhkan penyahpepijatan USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Mengambil laporan pepijat…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Kongsi laporan pepijat?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Berkongsi laporan pepijat…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Pentadbir IT anda meminta laporan pepijat untuk membantu menyelesaikan masalah peranti ini. Apl dan data mungkin dikongsi."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"KONGSI"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"TOLAK"</string> <string name="select_input_method" msgid="8547250819326693584">"Tukar papan kekunci"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Pilih papan kekunci"</string> <string name="show_ime" msgid="2506087537466597099">"Pastikannya pada skrin, semasa papan kekunci fizikal aktif"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Kertas dinding"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Tukar kertas dinding"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Pendengar pemberitahuan"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Pendengar VR"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Pembekal keadaan"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Pembantu pemberitahuan"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Perkhidmatan penentu kedudukan pemberitahuan"</string> <string name="vpn_title" msgid="19615213552042827">"VPN diaktifkan"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN diaktifkan oleh <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Sentuh untuk mengurus rangkaian."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Nyahsemat"</string> <string name="app_info" msgid="6856026610594615344">"Maklumat apl"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Lakukan tetapan semula kilang untuk menggunakan peranti ini seperti biasa"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Sentuh untuk mengetahui lebih lanjut."</string> </resources> diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml index c9f2ffcfefa2..e66cf66a06f7 100644 --- a/core/res/res/values-my-rMM/strings.xml +++ b/core/res/res/values-my-rMM/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"အသံ အကူအညီ"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"ယခု သော့ပိတ်ရန်"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"၉၉၉+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"အကြောင်းအရာများ ဝှက်ထား"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"မူဝါဒမှ အကြောင်းအရာများကို ဝှက်ထားသည်"</string> <string name="safeMode" msgid="2788228061547930246">"အန္တရာယ်ကင်းမှု စနစ်(Safe mode)"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"ထပ်မံရွေးချယ်စရာများအတွက် ထိပါ"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB အမှားစစ်ခြင်းအား ချိတ်ဆက်ထားသည်"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ဒီဘာဂင် ပိတ်ရန် ထိပါ။"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ချွတ်ယွင်းချက် အစီရင်ခံစာပြုစုနေသည်..."</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ချွတ်ယွင်းချက် အစီရင်ခံစာကို မျှဝေမလား။"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ချွတ်ယွင်းမှုအစီရင်ခံစာ မျှဝေနေသည်…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"ဤစက်ပစ္စည်းကို ပြဿနာအဖြေရှာရာတွင် ကူညီရန် သင့်အိုင်တီစီမံခန့်ခွဲသူသည် ချွတ်ယွင်းချက်အစီရင်ခံစာကို တောင်းဆိုထားသည်။ အက်ပ်များနှင့် ဒေတာကိုမျှဝေထားနိုင်ပါသည်။"</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"မျှဝေပါ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ငြင်းပယ်ပါ"</string> <string name="select_input_method" msgid="8547250819326693584">"ကီးဘုတ် ပြောင်းလဲရန်"</string> <string name="configure_input_methods" msgid="4769971288371946846">"ကီးဘုတ်များကို ရွေးရန်"</string> <string name="show_ime" msgid="2506087537466597099">"စက်၏ကီးဘုတ်ကိုအသုံးပြုနေစဉ် ၎င်းကိုမျက်နှာပြင်ပေါ်တွင် ထားပါ"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"အခြေအနေ စီမံပေးသူ"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"သတိပေးချက် အကူ"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"သတိပေးချက် အဆင့်သတ်မှတ်ခြင်းဝန်ဆောင်မှု"</string> <string name="vpn_title" msgid="19615213552042827">"VPN ဖွင့်ထားပါသည်"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g>မှVPNအလုပ်လုပ်နေသည်"</string> <string name="vpn_text" msgid="3011306607126450322">"ကွန်ရက် ထိန်းသိမ်းရန် တို့ထိပါ"</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"ဖြုတ်ပါ"</string> <string name="app_info" msgid="6856026610594615344">"အက်ပ်အချက်အလက်"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"ဤစက်ပစ္စည်းကို သာမန်အသုံးပြုနိုင်ရန် စက်ရုံထုတ်အတိုင်း ပြန်လည်သတ်မှတ်ပါ"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"ပိုမိုလေ့လာရန် တို့ပါ။"</string> </resources> diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml index 4ff66086b5e5..6c2358b4e13c 100644 --- a/core/res/res/values-nb/strings.xml +++ b/core/res/res/values-nb/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Talehjelp"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Lås nå"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Innholdet er skjult"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Innholdet er skjult i henhold til retningslinjene"</string> <string name="safeMode" msgid="2788228061547930246">"Sikkermodus"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Trykk for å se flere alternativer."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-feilsøking tilkoblet"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Trykk for å slå av USB-feilsøking."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Kjører feilrapport …"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vil du dele feilrapporten?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Deler feilrapporten …"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IT-administratoren har bedt om en feilrapport for å hjelpe med feilsøkingen på denne enheten. Apper og data kan bli delt."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DEL"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"AVSLÅ"</string> <string name="select_input_method" msgid="8547250819326693584">"Endre tastatur"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Velg tastatur"</string> <string name="show_ime" msgid="2506087537466597099">"Ha den på skjermen mens det fysiske tastaturet er aktivt"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Bakgrunnsbilde"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Velg bakgrunnsbilde"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Varsellytteren"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Lyttetjeneste for virtuell virkelighet"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Betingelsesleverandør"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Varselassistent"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Tjeneste for rangering av varsler"</string> <string name="vpn_title" msgid="19615213552042827">"VPN er aktivert"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN er aktivert av <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Trykk for å administrere nettverket."</string> @@ -1570,4 +1566,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Løsne"</string> <string name="app_info" msgid="6856026610594615344">"Info om appen"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Tilbakestill til fabrikkstandard for å bruke denne enheten som normalt"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Trykk for å finne ut mer."</string> </resources> diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml index 80f160219c26..40d13f091cea 100644 --- a/core/res/res/values-ne-rNP/strings.xml +++ b/core/res/res/values-ne-rNP/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"आवाज सहायता"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"अब बन्द गर्नुहोस्"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"९९९+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"लुकेका सामाग्रीहरू"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"नीतिद्वारा लुकाइएका सामग्री"</string> <string name="safeMode" msgid="2788228061547930246">"सुरक्षित मोड"</string> @@ -1142,8 +1141,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"सर्त प्रदायक"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"सूचना सहायक"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"सूचनालाई श्रेणी प्रदान गर्ने सेवा"</string> <string name="vpn_title" msgid="19615213552042827">"VPN सक्रिय भयो"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN <xliff:g id="APP">%s</xliff:g>द्वारा सक्रिय गरिएको हो"</string> <string name="vpn_text" msgid="3011306607126450322">"नेटवर्क प्रबन्ध गर्न छुनुहोस्।"</string> @@ -1570,4 +1570,6 @@ <string name="unpin_target" msgid="3556545602439143442">"अनपिन गर्नुहोस्"</string> <string name="app_info" msgid="6856026610594615344">"अनुप्रयोगका बारे जानकारी"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"यस यन्त्रलाई सामान्य रूपमा प्रयोग गर्नका लागि फ्याक्ट्री रिसेट गर्नुहोस्"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"थप जान्नका लागि स्पर्श गर्नुहोस्।"</string> </resources> diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml index 06b63b9ccd10..b48fc3329b41 100644 --- a/core/res/res/values-nl/strings.xml +++ b/core/res/res/values-nl/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Spraakassistent"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Nu vergrendelen"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Inhoud verborgen"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Content verborgen op basis van beleid"</string> <string name="safeMode" msgid="2788228061547930246">"Veilige modus"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Tik voor meer opties."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-foutopsporing verbonden"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Tik om USB-foutopsporing uit te schakelen."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Bugrapport genereren…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Bugrapport delen?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Bugrapport delen…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Je IT-beheerder heeft een bugrapport aangevraagd om problemen met dit apparaat op te lossen. Apps en gegevens kunnen worden gedeeld."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DELEN"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"WEIGEREN"</string> <string name="select_input_method" msgid="8547250819326693584">"Toetsenbord wijzigen"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Toetsenborden kiezen"</string> <string name="show_ime" msgid="2506087537466597099">"Dit op het scherm weergeven terwijl het fysieke toetsenbord actief is"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Achtergrond"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Achtergrond wijzigen"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Listener voor meldingen"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR-listener"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Provider van voorwaarden"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Meldingsassistent"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Rangschikkingsservice voor meldingen"</string> <string name="vpn_title" msgid="19615213552042827">"VPN is geactiveerd"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN wordt geactiveerd door <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Raak aan om het netwerk te beheren."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Losmaken"</string> <string name="app_info" msgid="6856026610594615344">"App-info"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Zet dit apparaat terug op de fabrieksinstellingen om het normaal te gebruiken"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Tik voor meer informatie."</string> </resources> diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml index 89d2df87802a..7ff207183f3e 100644 --- a/core/res/res/values-pa-rIN/strings.xml +++ b/core/res/res/values-pa-rIN/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"ਵੌਇਸ ਅਸਿਸਟ"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"ਹੁਣ ਲੌਕ ਕਰੋ"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"ਸਮੱਗਰੀਆਂ ਲੁਕਾਈਆਂ ਗਈਆਂ"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ਨੀਤੀ ਦੁਆਰਾ ਸਮੱਗਰੀ ਲੁਕਾਈ ਗਈ"</string> <string name="safeMode" msgid="2788228061547930246">"ਸੁਰੱਖਿਅਤ ਮੋਡ"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਸਪਰਸ਼ ਕਰੋ।"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ਡੀਬਗਿੰਗ ਕਨੈਕਟ ਕੀਤੀ"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ਡੀਬਗਿੰਗ ਨੂੰ ਅਸਮਰੱਥ ਬਣਾਉਣ ਲਈ ਛੋਹਵੋ।"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"ਬੱਗ ਰਿਪਰੋਟ ਪ੍ਰਾਪਤ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ..."</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"ਕੀ ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕਰਨੀ ਹੈ?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"ਬੱਗ ਰਿਪੋਰਟ ਸਾਂਝੀ ਕੀਤੀ ਜਾ ਰਹੀ ਹੈ…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"ਤੁਹਾਡੇ IT ਪ੍ਰਸ਼ਾਸਕ ਨੇ ਇਸ ਡੀਵਾਈਸ ਦੀ ਸਮੱਸਿਆ ਨੂੰ ਠੀਕ ਕਰਨ ਵਿੱੱਚ ਮਦਦ ਲਈ ਬੱਗ ਰਿਪੋਰਟ ਦੀ ਬੇਨਤੀ ਕੀਤੀ ਹੈ। ਐਪਾਂ ਅਤੇ ਡੈਟੇ ਨੂੰ ਸਾਂਝਾ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।"</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ਸਾਂਝੀ ਕਰੋ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ਅਸਵੀਕਾਰ ਕਰੋ"</string> <string name="select_input_method" msgid="8547250819326693584">"ਕੀਬੋਰਡ ਬਦਲੋ"</string> <string name="configure_input_methods" msgid="4769971288371946846">"ਕੀਬੋਰਡਸ ਚੁਣੋ"</string> <string name="show_ime" msgid="2506087537466597099">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ ਸਰਗਰਮ ਹੋਣ ਦੌਰਾਨ ਇਸ ਨੂੰ ਸਕ੍ਰੀਨ \'ਤੇ ਬਣਾਈ ਰੱਖੋ"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"ਸਥਿਤੀ ਪ੍ਰਦਾਤਾ"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"ਸੂਚਨਾ ਸਹਾਇਕ"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"ਸੂਚਨਾ ਰੈਂਕਰ ਸੇਵਾ"</string> <string name="vpn_title" msgid="19615213552042827">"VPN ਸਕਿਰਿਆ ਕੀਤਾ"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN <xliff:g id="APP">%s</xliff:g> ਰਾਹੀਂ ਸਕਿਰਿਆ ਬਣਾਇਆ ਗਿਆ ਹੈ"</string> <string name="vpn_text" msgid="3011306607126450322">"ਨੈਟਵਰਕ ਵਿਵਸਥਿਤ ਕਰਨ ਲਈ ਛੋਹਵੋ।"</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"ਅਨਪਿੰਨ ਕਰੋ"</string> <string name="app_info" msgid="6856026610594615344">"ਐਪ ਜਾਣਕਾਰੀ"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"ਇਸ ਡੀਵਾਈਸ ਨੂੰ ਸਧਾਰਨ ਰੂਪ ਵਿੱਚ ਵਰਤਣ ਲਈ ਫੈਕਟਰੀ ਰੀਸੈੱਟ ਕਰੋ"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"ਹੋਰ ਜਾਣਨ ਲਈ ਸਪਰਸ਼ ਕਰੋ।"</string> </resources> diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml index 773cc8883385..b68b45a8508e 100644 --- a/core/res/res/values-pl/strings.xml +++ b/core/res/res/values-pl/strings.xml @@ -233,7 +233,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Asystent głosowy"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Zablokuj teraz"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Treści ukryte"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Treść ukryta z powodu zasad"</string> <string name="safeMode" msgid="2788228061547930246">"Tryb awaryjny"</string> @@ -1068,16 +1067,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Kliknij, by zobaczyć więcej opcji."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Podłączono moduł debugowania USB"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotknij, aby wyłączyć debugowanie USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Zgłaszam błąd…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Udostępnić raport o błędzie?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Udostępniam raport o błędzie…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Administrator poprosił o raport o błędzie, który pomoże w rozwiązaniu problemów na tym urządzeniu. Mogą zostać udostępnione aplikacje i dane."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"UDOSTĘPNIJ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODRZUĆ"</string> <string name="select_input_method" msgid="8547250819326693584">"Zmień klawiaturę"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Wybierz klawiatury"</string> <string name="show_ime" msgid="2506087537466597099">"Pozostaw na ekranie, gdy aktywna jest klawiatura fizyczna"</string> @@ -1156,8 +1151,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapeta"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Zmień tapetę"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Odbiornik powiadomień"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Odbiornik rzeczywistości wirtualnej"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Dostawca warunków"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Asystent powiadomień"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Usługa rankingu powiadomień"</string> <string name="vpn_title" msgid="19615213552042827">"VPN aktywny"</string> <string name="vpn_title_long" msgid="6400714798049252294">"Obsługa sieci VPN została włączona przez aplikację <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Dotknij, aby zarządzać siecią."</string> @@ -1606,4 +1602,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Odepnij"</string> <string name="app_info" msgid="6856026610594615344">"O aplikacji"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Aby używać tego urządzenia normalnie, przywróć ustawienia fabryczne"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Kliknij, by dowiedzieć się więcej."</string> </resources> diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml index 2e55c372a3bc..cd0de0e2feb8 100644 --- a/core/res/res/values-pt-rBR/strings.xml +++ b/core/res/res/values-pt-rBR/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Ajuda de voz"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Conteúdo oculto"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Conteúdo ocultado pela política"</string> <string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Toque para ver mais opções."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desativar a depuração do USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Gerando relatório do bug..."</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Compartilhar relatório do bug?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Compartilhando relatório do bug…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Seu administrador de TI solicitou um relatório de bug para ajudar a resolver problemas deste dispositivo. É possível que apps e dados sejam compartilhados."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTILHAR"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RECUSAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string> <string name="show_ime" msgid="2506087537466597099">"Manter na tela enquanto o teclado físico estiver ativo"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Plano de fundo"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Alterar plano de fundo"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Ouvinte de notificações"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Ouvinte de RV"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Provedor de condições"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Assistente de notificação"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Serviço de classificação de notificação"</string> <string name="vpn_title" msgid="19615213552042827">"VPN ativada"</string> <string name="vpn_title_long" msgid="6400714798049252294">"A VPN está ativada por <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Toque para gerenciar a rede."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Liberar guia"</string> <string name="app_info" msgid="6856026610594615344">"Informações do app"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Redefinir para a configuração original para usar este dispositivo normalmente"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toque para saber mais."</string> </resources> diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml index 548ef45d819c..dde0131118e4 100644 --- a/core/res/res/values-pt-rPT/strings.xml +++ b/core/res/res/values-pt-rPT/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Assist. de voz"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Conteúdo oculto"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Conteúdo ocultado pela política"</string> <string name="safeMode" msgid="2788228061547930246">"Modo seguro"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Toque para ver mais opções."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB ligada"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desat. a depuração USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"A criar relatório de erro…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Pretende partilhar o relatório de erro?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"A partilhar relatório de erro…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"O seu administrador de TI solicitou um relatório de erro para ajudar na resolução de problemas deste dispositivo. As aplicações e os dados podem ser partilhados."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PARTILHAR"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RECUSAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string> <string name="show_ime" msgid="2506087537466597099">"Manter no ecrã enquanto o teclado físico estiver ativo"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Imagem de fundo"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Alterar imagem de fundo"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Serviço de escuta de notificações"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Serviço de escuta de RV"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Fornecedor de condição"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Assistente de notificações"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Serviço de classificação de notificações"</string> <string name="vpn_title" msgid="19615213552042827">"VPN ativada"</string> <string name="vpn_title_long" msgid="6400714798049252294">"A VPN foi ativada pelo <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Toque para gerir a rede."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Soltar"</string> <string name="app_info" msgid="6856026610594615344">"Informações da aplicação"</string> <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Fazer uma reposição de dados de fábrica para utilizar este dispositivo normalmente"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toque para saber mais."</string> </resources> diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml index 2e55c372a3bc..cd0de0e2feb8 100644 --- a/core/res/res/values-pt/strings.xml +++ b/core/res/res/values-pt/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Ajuda de voz"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Bloquear agora"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Conteúdo oculto"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Conteúdo ocultado pela política"</string> <string name="safeMode" msgid="2788228061547930246">"Modo de segurança"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Toque para ver mais opções."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Depuração USB conectada"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Toque para desativar a depuração do USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Gerando relatório do bug..."</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Compartilhar relatório do bug?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Compartilhando relatório do bug…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Seu administrador de TI solicitou um relatório de bug para ajudar a resolver problemas deste dispositivo. É possível que apps e dados sejam compartilhados."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"COMPARTILHAR"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RECUSAR"</string> <string name="select_input_method" msgid="8547250819326693584">"Alterar teclado"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Escolher teclados"</string> <string name="show_ime" msgid="2506087537466597099">"Manter na tela enquanto o teclado físico estiver ativo"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Plano de fundo"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Alterar plano de fundo"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Ouvinte de notificações"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Ouvinte de RV"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Provedor de condições"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Assistente de notificação"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Serviço de classificação de notificação"</string> <string name="vpn_title" msgid="19615213552042827">"VPN ativada"</string> <string name="vpn_title_long" msgid="6400714798049252294">"A VPN está ativada por <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Toque para gerenciar a rede."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Liberar guia"</string> <string name="app_info" msgid="6856026610594615344">"Informações do app"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Redefinir para a configuração original para usar este dispositivo normalmente"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toque para saber mais."</string> </resources> diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml index 57be99c05aac..1c6e02445908 100644 --- a/core/res/res/values-ro/strings.xml +++ b/core/res/res/values-ro/strings.xml @@ -231,7 +231,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Asistent vocal"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Blocați acum"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"˃999"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Conținutul este ascuns"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Conținutul este ascuns conform politicii"</string> <string name="safeMode" msgid="2788228061547930246">"Mod sigur"</string> @@ -1060,16 +1059,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Atingeți pentru mai multe opțiuni."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Depanarea USB este conectată"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Atingeți pentru a dezactiva depanarea USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Se creează un raport de eroare…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Trimiteți raportul de eroare?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Se trimite raportul de eroare…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Administratorul IT a solicitat un raport de eroare pentru a remedia problemele acestui dispozitiv. Este posibil să se permită accesul la date și aplicații."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"TRIMITEȚI"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REFUZAȚI"</string> <string name="select_input_method" msgid="8547250819326693584">"Schimbați tastatura"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Alegeți tastaturi"</string> <string name="show_ime" msgid="2506087537466597099">"Se păstrează pe ecran cât timp este activată tastatura fizică"</string> @@ -1148,8 +1143,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Imagine de fundal"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Modificați imaginea de fundal"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Serviciu de citire a notificărilor"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Instrument de ascultare pentru Realitatea virtuală"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Furnizor de condiții"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Asistent pentru notificări"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Serviciul de clasificare a notificărilor"</string> <string name="vpn_title" msgid="19615213552042827">"VPN activat"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN este activată de <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Atingeți pentru a gestiona rețeaua."</string> @@ -1587,4 +1583,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Anulați fixarea"</string> <string name="app_info" msgid="6856026610594615344">"Informații despre aplicație"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Reveniți la setările din fabrică pentru a folosi acest dispozitiv ca de obicei"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Atingeți pentru a afla mai multe."</string> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index 291f53ef0b1a..f13435797101 100644 --- a/core/res/res/values-ru/strings.xml +++ b/core/res/res/values-ru/strings.xml @@ -233,7 +233,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Аудиоподсказки"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Заблокировать"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">">999"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Содержимое скрыто"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Содержимое скрыто в соответствии с заданными правилами"</string> <string name="safeMode" msgid="2788228061547930246">"Безопасный режим"</string> @@ -1152,8 +1151,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"Поставщик условий"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Ассистент уведомлений"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Сервис для оценки важности уведомлений"</string> <string name="vpn_title" msgid="19615213552042827">"Сеть VPN активна"</string> <string name="vpn_title_long" msgid="6400714798049252294">"Сеть VPN активирована приложением <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Нажмите, чтобы открыть настройки."</string> @@ -1602,4 +1602,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Открепить"</string> <string name="app_info" msgid="6856026610594615344">"О приложении"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Сброс до заводских настроек в целях безопасности"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Нажмите, чтобы узнать больше."</string> </resources> diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml index a44933f302d7..9a6d3af92557 100644 --- a/core/res/res/values-si-rLK/strings.xml +++ b/core/res/res/values-si-rLK/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"හඬ සහායක"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"දැන් අගුළු දමන්න"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"සැඟවුණු සම්බන්ධතා"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"ප්රතිපත්තිය විසින් අන්තර්ගතය සඟවන ලදී"</string> <string name="safeMode" msgid="2788228061547930246">"ආරක්ෂිත ආකාරය"</string> @@ -1138,8 +1137,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"තත්ත්වය සපයන්නා"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"දැනුම්දීම් සහායක"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"දැනුම්දීම් ශ්රේණිගත කිරීමේ සේවාව"</string> <string name="vpn_title" msgid="19615213552042827">"VPN ක්රියාත්මකයි"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> මඟින් VPN සක්රීය කරන ලදි"</string> <string name="vpn_text" msgid="3011306607126450322">"ජාලය කළමනාකරණය කිරීමට ස්පර්ශ කරන්න."</string> @@ -1566,4 +1566,6 @@ <string name="unpin_target" msgid="3556545602439143442">"ගලවන්න"</string> <string name="app_info" msgid="6856026610594615344">"යෙදුම් තොරතුරු"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"මෙම උපාංගය සාමාන්ය ලෙස භාවිත කිරීමට කර්මාන්තශාලා යළි සැකසීම"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"තව දැන ගැනීමට ස්පර්ශ කරන්න."</string> </resources> diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml index 80a42932b5eb..f4794a6cacdb 100644 --- a/core/res/res/values-sk/strings.xml +++ b/core/res/res/values-sk/strings.xml @@ -233,7 +233,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Hlasový asistent"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Uzamknúť"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Skrytý obsah"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Obsah je na základe pravidiel skrytý"</string> <string name="safeMode" msgid="2788228061547930246">"Núdzový režim"</string> @@ -1068,16 +1067,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Ďalšie možnosti zobrazíte klepnutím."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Ladenie cez USB pripojené"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Klepnutím zakážete ladenie cez USB"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Preberá sa hlásenie chyby…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Chcete zdieľať hlásenie chyby?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Zdieľa sa hlásenie chyby…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Správca IT si vyžiadal hlásenie chyby, aby mohol vyriešiť problém na tomto zariadení. Aplikácie a dáta môžu byť zdieľané."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ZDIEĽAŤ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ODMIETNUŤ"</string> <string name="select_input_method" msgid="8547250819326693584">"Zmeniť klávesnicu"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Vybrať klávesnicu"</string> <string name="show_ime" msgid="2506087537466597099">"Ponechať na obrazovke, keď je aktívna fyzická klávesnica"</string> @@ -1156,8 +1151,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Tapeta"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Zmeniť tapetu"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Aplikácia na počúvanie upozornení"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Prijímač VR"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Poskytovateľ podmienky"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Asistent upozornení"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Služba na hodnotenie upozornení"</string> <string name="vpn_title" msgid="19615213552042827">"Sieť VPN je aktivovaná"</string> <string name="vpn_title_long" msgid="6400714798049252294">"Aplikáciu <xliff:g id="APP">%s</xliff:g> aktivovala sieť VPN"</string> <string name="vpn_text" msgid="3011306607126450322">"Dotykom môžete spravovať sieť."</string> @@ -1606,4 +1602,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Uvoľniť"</string> <string name="app_info" msgid="6856026610594615344">"Info o aplikácii"</string> <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Ak chcete toto zariadenie používať normálnym spôsobom, obnovte na ňom továrenské nastavenia"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Klepnutím získate ďalšie informácie."</string> </resources> diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml index 5e85770e44f6..3e0cfaff83cf 100644 --- a/core/res/res/values-sl/strings.xml +++ b/core/res/res/values-sl/strings.xml @@ -233,7 +233,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Glas. pomočnik"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Zakleni zdaj"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999 +"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Vsebina je skrita"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Pravilnik je skril vsebino"</string> <string name="safeMode" msgid="2788228061547930246">"Varni način"</string> @@ -1068,16 +1067,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Za več možnosti se dotaknite."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Iskanje in odpravljanje napak USB je povezano"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Dotaknite se, če želite onemogočiti iskanje in odpravljanje napak prek vrat USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Zajemanje poročila o napakah …"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Želite poslati poročilo o napakah?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Pošiljanje poročila o napakah …"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Skrbnik za IT je zahteval poročilo o napakah za pomoč pri odpravljanju napak v tej napravi. Aplikacije in podatki bodo morda dani v skupno rabo."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"SKUPNA RABA"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"NE SPREJMEM"</string> <string name="select_input_method" msgid="8547250819326693584">"Sprememba tipkovnice"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Izbira tipkovnic"</string> <string name="show_ime" msgid="2506087537466597099">"Ohrani na zaslonu, dokler je aktivna fizična tipkovnica"</string> @@ -1156,8 +1151,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Ozadje"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Spreminjanje ozadja"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Poslušalec obvestil"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Poslušalec za navidezno resničnost"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Ponudnik pogojev"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Pomočnik za obvestila"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Storitev za določanje stopenj pomembnosti obvestil"</string> <string name="vpn_title" msgid="19615213552042827">"VPN aktiviran"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN je aktivirala aplikacija <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Dotaknite se, če želite upravljati omrežje."</string> @@ -1606,4 +1602,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Odpenjanje"</string> <string name="app_info" msgid="6856026610594615344">"Podatki o aplikaciji"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Napravo ponastavite na tovarniške nastavitve, če jo želite uporabljati brez težav"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Dotaknite se, če želite izvedeti več."</string> </resources> diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml index 9c9268bec495..bc8bd2ba50e0 100644 --- a/core/res/res/values-sq-rAL/strings.xml +++ b/core/res/res/values-sq-rAL/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Ndihma zanore"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Kyç tani"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Përmbajtjet janë të fshehura"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Përmbajtja është e fshehur për shkak të politikës"</string> <string name="safeMode" msgid="2788228061547930246">"Modaliteti i sigurisë"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Prek për më shumë opsione."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Korrigjuesi i USB-së i lidhur"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Prek për të çaktivizuar korrigjimin e gabimeve të USB-së."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Po merret raporti i defekteve në kod…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Të ndahet raporti i defektit në kod?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Po ndan raportin e defekteve në kod..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Administratori i teknologjisë së informacionit kërkoi një raport të defekteve në kod për të ndihmuar me zgjidhjen e problemeve. Aplikacioni dhe të dhënat mund të ndahen."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"SHPËRNDA"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REFUZO"</string> <string name="select_input_method" msgid="8547250819326693584">"Ndërro tastierë"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Zgjidh tastierat"</string> <string name="show_ime" msgid="2506087537466597099">"Mbaje në ekran ndërsa tastiera fizike është aktive"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Imazhi i sfondit"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Ndrysho imazhin e sfondit"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Dëgjues njoftimesh"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Dëgjues VR"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Ofrues kushtesh"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Asistenti i njoftimeve"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Shërbimi i klasifikimit të njoftimeve"</string> <string name="vpn_title" msgid="19615213552042827">"VPN-ja u aktivizua"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN-ja është aktivizuar nga <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Prek për të menaxhuar rrjetin."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Zhgozhdo"</string> <string name="app_info" msgid="6856026610594615344">"Informacioni mbi aplikacionin"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Rivendos cilësimet e fabrikës për ta përdorur normalisht këtë pajisje"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Prek për të mësuar më shumë."</string> </resources> diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml index 528832f08cb8..d14c166d71a9 100644 --- a/core/res/res/values-sr/strings.xml +++ b/core/res/res/values-sr/strings.xml @@ -231,7 +231,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Гласовна помоћ"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Закључај одмах"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Садржај је сакривен"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Садржај је сакривен смерницама"</string> <string name="safeMode" msgid="2788228061547930246">"Безбедни режим"</string> @@ -1060,16 +1059,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Додирните за још опција."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Отклањање грешака са USB-а је успостављено"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Додирните да бисте онемогућили отклањање грешака са USB-а."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Извештај о грешци се генерише…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Желите ли да поделите извештај о грешци?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Дели се извештај о грешци…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"ИТ администратор је затражио извештај о грешци ради лакшег решавања проблема у вези са овим уређајем. Апликације и подаци могу да се деле."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ДЕЛИ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ОДБИЈ"</string> <string name="select_input_method" msgid="8547250819326693584">"Промените тастатуру"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Изаберите тастатуре"</string> <string name="show_ime" msgid="2506087537466597099">"Задржи га на екрану док је физичка тастатура активна"</string> @@ -1148,8 +1143,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"Добављач услова"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Помоћник за обавештења"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Услуга рангирања обавештења"</string> <string name="vpn_title" msgid="19615213552042827">"VPN је активиран"</string> <string name="vpn_title_long" msgid="6400714798049252294">"Апликација <xliff:g id="APP">%s</xliff:g> је активирала VPN"</string> <string name="vpn_text" msgid="3011306607126450322">"Додирните да бисте управљали мрежом."</string> @@ -1587,4 +1583,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Откачи"</string> <string name="app_info" msgid="6856026610594615344">"Информације о апликацији"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Ресетујте уређај на фабричка подешавања да бисте га нормално користили"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Додирните да бисте сазнали више."</string> </resources> diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml index daa767ae176a..3eb4ae346ee6 100644 --- a/core/res/res/values-sv/strings.xml +++ b/core/res/res/values-sv/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Lås nu"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Innehåll har dolts"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Innehåll har dolts p.g.a. en policy"</string> <string name="safeMode" msgid="2788228061547930246">"Säkert läge"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Visa fler alternativ genom att trycka."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB-felsökning ansluten"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Tryck om du vill inaktivera USB-felsökning."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Felrapporten överförs …"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Vill du dela felrapporten?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Felrapporten delas …"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"IT-administratören har bett om en felrapport som hjälp vid felsökningen av den här enheten. Appar och data kan komma att delas."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"DELA"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"AVVISA"</string> <string name="select_input_method" msgid="8547250819326693584">"Byt tangentbord"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Välj tangentbord"</string> <string name="show_ime" msgid="2506087537466597099">"Ha kvar den på skärmen när det fysiska tangentbordet används"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Bakgrund"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Ändra bakgrund"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Meddelandelyssnare"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Lyssnare för virtuell verklighet"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Leverantör"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Aviseringsassistent"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Rankningstjänst för aviseringar"</string> <string name="vpn_title" msgid="19615213552042827">"VPN är aktiverat"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN aktiveras av <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Tryck om du vill hantera nätverket."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Lossa"</string> <string name="app_info" msgid="6856026610594615344">"Info om appen"</string> <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Återställ standardinställningarna om du vill använda enheten normalt"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Tryck här om du vill läsa mer."</string> </resources> diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml index d807aac4101b..04994d55a1ce 100644 --- a/core/res/res/values-sw/strings.xml +++ b/core/res/res/values-sw/strings.xml @@ -231,7 +231,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Usaidizi wa Sauti"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Funga sasa"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Maudhui yamefichwa"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Maudhui yamefichwa kulingana na sera"</string> <string name="safeMode" msgid="2788228061547930246">"Mtindo salama"</string> @@ -1138,8 +1137,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Mandhari"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Badilisha mandhari"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Kisikilizi cha arifa"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Kisikilizaji cha Uhalisia Pepe"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Mtoa masharti"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Mratibu wa arifa"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Huduma ya kupanga arifa"</string> <string name="vpn_title" msgid="19615213552042827">"VPN imewezeshwa"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN imeamilishwa na <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Gusa ili kudhibiti mtandao."</string> @@ -1566,4 +1566,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Bandua"</string> <string name="app_info" msgid="6856026610594615344">"Maelezo ya programu"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Rejesha mipangilio ya kiwandani katika kifaa hiki ili ukitumie kwa njia ya kawaida"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Gusa ili kupata maelezo zaidi."</string> </resources> diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml index 40011d24794e..2cb08c9e2d96 100644 --- a/core/res/res/values-ta-rIN/strings.xml +++ b/core/res/res/values-ta-rIN/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"குரல் உதவி"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"இப்போது பூட்டு"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"மறைந்துள்ள உள்ளடக்கம்"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"கொள்கையின்படி உள்ளடக்கம் மறைக்கப்பட்டது"</string> <string name="safeMode" msgid="2788228061547930246">"பாதுகாப்பு பயன்முறை"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"கூடுதல் விருப்பங்களுக்காகத் தொடவும்."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB பிழைதிருத்தம் இணைக்கப்பட்டது"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB பிழைத்திருத்தத்தை முடக்க, தொடவும்."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"பிழை அறிக்கையை எடுக்கிறது…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"பிழை அறிக்கையைப் பகிரவா?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"பிழை அறிக்கையைப் பகிர்கிறது…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"இந்தச் சாதனத்தின் பிழைகாண்பதற்கு உதவ, உங்கள் ஐடி நிர்வாகி பிழை அறிக்கையைக் கோரியுள்ளார். பயன்பாடுகளும் தரவும் பகிரப்படலாம்."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"பகிர்"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"வேண்டாம்"</string> <string name="select_input_method" msgid="8547250819326693584">"விசைப்பலகையை மாற்று"</string> <string name="configure_input_methods" msgid="4769971288371946846">"விசைப்பலகைகளைத் தேர்வுசெய்க"</string> <string name="show_ime" msgid="2506087537466597099">"கைமுறை விசைப்பலகை இயக்கத்தில் இருக்கும் போது IMEஐ திரையில் வைத்திரு"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"நிபந்தனை வழங்குநர்"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"அறிவிப்பு உதவி"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"அறிவிப்பை மதிப்பீடு செய்யும் சேவை"</string> <string name="vpn_title" msgid="19615213552042827">"VPN செயல்படுத்தப்பட்டது"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> ஆல் VPN செயல்படுத்தப்பட்டது"</string> <string name="vpn_text" msgid="3011306607126450322">"நெட்வொர்க்கை நிர்வகிக்கத் தொடவும்."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"பின்னை அகற்று"</string> <string name="app_info" msgid="6856026610594615344">"பயன்பாட்டுத் தகவல்"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"சாதாரணமாக இந்தச் சாதனத்தைப் பயன்படுத்த, ஆரம்ப நிலைக்கு மீட்டமைக்கவும்"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"மேலும் அறிய தொடவும்."</string> </resources> diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml index 22aa04de9580..4fd8aadd4b02 100644 --- a/core/res/res/values-te-rIN/strings.xml +++ b/core/res/res/values-te-rIN/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"వాయిస్ సహాయకం"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"ఇప్పుడు లాక్ చేయండి"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"కంటెంట్లు దాచబడ్డాయి"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"విధానం ద్వారా కంటెంట్లు దాచబడ్డాయి"</string> <string name="safeMode" msgid="2788228061547930246">"సురక్షిత మోడ్"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"మరిన్ని ఎంపికల కోసం తాకండి."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB డీబగ్గింగ్ కనెక్ట్ చేయబడింది"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB డీబగ్గింగ్ను నిలిపివేయడానికి తాకండి."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"బగ్ నివేదికను తీస్తోంది…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"బగ్ నివేదికను భాగస్వామ్యం చేయాలా?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"బగ్ నివేదికను భాగస్వామ్యం చేస్తోంది..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"మీ ఐటి నిర్వాహకులు ఈ పరికరం సమస్యకు పరిష్కారాన్ని కనుగొనడంలో సహాయం కోసం బగ్ నివేదికను అభ్యర్థించారు. అనువర్తనాలు మరియు డేటా భాగస్వామ్యం చేయబడవచ్చు."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"భాగస్వామ్యం చేయి"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"తిరస్కరిస్తున్నాను"</string> <string name="select_input_method" msgid="8547250819326693584">"కీబోర్డ్ను మార్చు"</string> <string name="configure_input_methods" msgid="4769971288371946846">"కీబోర్డ్లను ఎంచుకోండి"</string> <string name="show_ime" msgid="2506087537466597099">"దీన్ని భౌతిక కీబోర్డ్ సక్రియంగా ఉన్నప్పుడు స్క్రీన్పై ఉంచుతుంది"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"షరతు ప్రదాత"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"నోటిఫికేషన్ సహాయకం"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"నోటిఫికేషన్ ర్యాంకర్ సేవ"</string> <string name="vpn_title" msgid="19615213552042827">"VPN సక్రియం చేయబడింది"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> ద్వారా VPN సక్రియం చేయబడింది"</string> <string name="vpn_text" msgid="3011306607126450322">"నెట్వర్క్ను నిర్వహించడానికి తాకండి."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"అన్పిన్ చేయి"</string> <string name="app_info" msgid="6856026610594615344">"అనువర్తన సమాచారం"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"ఈ పరికరాన్ని సాధారణంగా ఉపయోగించడానికి ఫ్యాక్టరీ రీసెట్ చేయండి"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"మరింత తెలుసుకోవడానికి తాకండి."</string> </resources> diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml index 2e6f62ebc3aa..fabecc39661b 100644 --- a/core/res/res/values-th/strings.xml +++ b/core/res/res/values-th/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"ตัวช่วยเสียง"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"ล็อกเลย"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"เนื้อหาถูกซ่อนไว้"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"มีการซ่อนเนื้อหาโดยนโยบาย"</string> <string name="safeMode" msgid="2788228061547930246">"โหมดปลอดภัย"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"แตะเพื่อดูตัวเลือกเพิ่มเติม"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"เชื่อมต่อการแก้ไขข้อบกพร่อง USB แล้ว"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"แตะเพื่อปิดใช้งานการแก้ไขข้อบกพร่อง USB"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"กำลังสร้างรายงานข้อบกพร่อง…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"แชร์รายงานข้อบกพร่องไหม"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"กำลังแชร์รายงานข้อบกพร่อง…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"ผู้ดูแลระบบไอทีของคุณขอรายงานข้อบกพร่องเพื่อช่วยในการแก้ปัญหาอุปกรณ์นี้ อาจมีการแชร์แอปและข้อมูล"</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"แชร์"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ปฏิเสธ"</string> <string name="select_input_method" msgid="8547250819326693584">"เปลี่ยนแป้นพิมพ์"</string> <string name="configure_input_methods" msgid="4769971288371946846">"เลือกแป้นพิมพ์"</string> <string name="show_ime" msgid="2506087537466597099">"เปิดทิ้งไว้บนหน้าจอในระหว่างใช้งานแป้นพิมพ์จริง"</string> @@ -1140,8 +1135,9 @@ <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">"Listener ความเป็นจริงเสมือน"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"ผู้เสนอเงื่อนไข"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"ผู้ช่วยการแจ้งเตือน"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"บริการตัวจัดอันดับการแจ้งเตือน"</string> <string name="vpn_title" msgid="19615213552042827">"VPN เปิดใช้งานแล้ว"</string> <string name="vpn_title_long" msgid="6400714798049252294">"เปิดใช้งาน VPN โดย <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"แตะเพื่อจัดการเครือข่าย"</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"เลิกปักหมุด"</string> <string name="app_info" msgid="6856026610594615344">"ข้อมูลแอป"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"รีเซ็ตเป็นค่าเริ่มต้นเพื่อใช้อุปกรณ์นี้ตามปกติ"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"แตะเพื่อเรียนรู้เพิ่มเติม"</string> </resources> diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml index 71c3460195b1..981567d3c1f8 100644 --- a/core/res/res/values-tl/strings.xml +++ b/core/res/res/values-tl/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"I-lock ngayon"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Nakatago ang mga content"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Itinago ang mga content alinsunod sa patakaran"</string> <string name="safeMode" msgid="2788228061547930246">"Safe mode"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Pindutin para sa higit pang mga opsyon."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Konektado ang debugging ng USB"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Pindutin upang i-disable ang pagde-debug ng USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Kinukuha ang ulat ng bug…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Gusto mo bang ibahagi ang ulat ng bug?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Ibinabahagi ang ulat ng bug…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Humiling ang iyong IT admin ng isang ulat ng bug upang makatulong sa pag-troubleshoot sa device na ito. Maaaring ibahagi ang mga app at data."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"IBAHAGI"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"TANGGIHAN"</string> <string name="select_input_method" msgid="8547250819326693584">"Baguhin ang keyboard"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Pumili ng mga keyboard"</string> <string name="show_ime" msgid="2506087537466597099">"Panatilihin ito sa screen habang aktibo ang pisikal na keyboard"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Wallpaper"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Baguhin ang wallpaper"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Notification listener"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"VR listener"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Nagbibigay ng kundisyon"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Notification assistant"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Serbisyo sa pag-rank ng notification"</string> <string name="vpn_title" msgid="19615213552042827">"Naka-activate ang VPN"</string> <string name="vpn_title_long" msgid="6400714798049252294">"Isinaaktibo ang VPN ng <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Pindutin upang pamahalaan ang network."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"I-unpin"</string> <string name="app_info" msgid="6856026610594615344">"Impormasyon ng app"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Mag-factory reset upang magamit nang normal ang device na ito"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Pindutin upang matuto nang higit pa."</string> </resources> diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml index c60983bed4eb..af5652b5b3ec 100644 --- a/core/res/res/values-tr/strings.xml +++ b/core/res/res/values-tr/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Sesli Yardım"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Şimdi kilitle"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"İçerik gizlendi"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"İçerikler politika nedeniyle gizlendi"</string> <string name="safeMode" msgid="2788228061547930246">"Güvenli mod"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Daha fazla seçenek için dokunun."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB hata ayıklaması bağlandı"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB hata ayıklama özelliğini devre dışı bırakmak için dokunun."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Hata raporu alınıyor…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Hata raporu paylaşılsın mı?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Hata raporu paylaşılıyor..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"BT yöneticiniz, bu cihazda sorun gidermeye yardımcı olması için bir hata raporu istedi. Uygulamalar ve veriler paylaşılabilir."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"PAYLAŞ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"REDDET"</string> <string name="select_input_method" msgid="8547250819326693584">"Klavyeyi değiştir"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Klavyeyi seç"</string> <string name="show_ime" msgid="2506087537466597099">"Fiziksel klavye etkin durumdayken ekranda tut"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Duvar Kağıdı"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Duvar kağıdını değiştir"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Bildirim dinleyici"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Sanal Gerçeklik dinleyici"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Durum sağlayıcı"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Bildirim yardımcısı"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Bildirim sıralama hizmeti"</string> <string name="vpn_title" msgid="19615213552042827">"VPN etkinleştirildi"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN, <xliff:g id="APP">%s</xliff:g> tarafından etkinleştirildi"</string> <string name="vpn_text" msgid="3011306607126450322">"Ağı yönetmek için dokunun."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Sabitlemeyi kaldır"</string> <string name="app_info" msgid="6856026610594615344">"Uygulama bilgileri"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Cihazı normal olarak kullanmak için fabrika ayarlarına sıfırlayın"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Daha fazla bilgi edinmek için dokunun."</string> </resources> diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml index ed0a978313d7..344797f3245b 100644 --- a/core/res/res/values-uk/strings.xml +++ b/core/res/res/values-uk/strings.xml @@ -233,7 +233,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Голос. підказки"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Блокувати зараз"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Вміст сховано"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Вміст сховано згідно з правилом"</string> <string name="safeMode" msgid="2788228061547930246">"Безп. режим"</string> @@ -1068,16 +1067,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Торкніться, щоб побачити більше опцій."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Налагодження USB завершено"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Торкніться, щоб вимкнути налагодження USB."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Створюється повідомлення про помилку…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Надіслати звіт про помилку?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Надсилається звіт про помилку…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Ваш IT-адміністратор просить надіслати повідомлення про помилку, щоб вирішити проблему з пристроєм. Він може отримати доступ до ваших додатків і даних."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ПОДІЛИТИСЯ"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"ВІДХИЛИТИ"</string> <string name="select_input_method" msgid="8547250819326693584">"Змінити клавіатуру"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Вибрати клавіатури"</string> <string name="show_ime" msgid="2506087537466597099">"Утримуйте на екрані, коли активна фізична клавіатура"</string> @@ -1156,8 +1151,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"Постачальник умов"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Диспетчер сповіщень"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Служба позиціонування сповіщень"</string> <string name="vpn_title" msgid="19615213552042827">"Мережу VPN активовано"</string> <string name="vpn_title_long" msgid="6400714798049252294">"Мережу VPN активовано програмою <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Торкніться, щоб керувати мережею."</string> @@ -1606,4 +1602,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Відкріпити"</string> <string name="app_info" msgid="6856026610594615344">"Про додаток"</string> <string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Відновлення заводських налаштувань для належної роботи пристрою"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Торкніться, щоб дізнатися більше."</string> </resources> diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml index d3140259ea8a..a58f5c282ce9 100644 --- a/core/res/res/values-ur-rPK/strings.xml +++ b/core/res/res/values-ur-rPK/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Voice Assist"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"ابھی مقفل کریں"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"مواد مخفی ہیں"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"مواد پالیسی کے تحت مخفی ہے"</string> <string name="safeMode" msgid="2788228061547930246">"حفاظتی وضع"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"مزید اختیارات کیلئے ٹچ کریں۔"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB ڈیبگ کرنا مربوط ہو گیا"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"USB ڈیبگنگ کو غیر فعال کرنے کیلئے ٹچ کریں۔"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"بگ رپورٹ لی جا رہی ہے…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"بگ رپورٹ کا اشتراک کریں؟"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"بگ رپورٹ کا اشتراک ہو رہا ہے…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"آپ کے IT منتظم نے اس آلہ کا مسئلہ حل کرنے میں مدد کیلئے ایک بگ رپورٹ کی درخواست کی ہے۔ ایپس اور ڈیٹا کا اشتراک ہو سکتا ہے۔"</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"اشتراک کریں"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"مسترد کریں"</string> <string name="select_input_method" msgid="8547250819326693584">"کی بورڈ تبدیل کریں"</string> <string name="configure_input_methods" msgid="4769971288371946846">"کی بورڈز منتخب کریں"</string> <string name="show_ime" msgid="2506087537466597099">"جب فزیکل کی بورڈ فعال ہو تو IME کو اسکرین پر رکھیں"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"شرط فراہم کنندہ"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"اطلاع کا معاون"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"اطلاع کی درجہ بندی سروس"</string> <string name="vpn_title" msgid="19615213552042827">"VPN فعال ہوگیا"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> کے ذریعہ VPN فعال ہے"</string> <string name="vpn_text" msgid="3011306607126450322">"نیٹ ورک کا نظم کرنے کیلئے چھوئیں۔"</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"پن ہٹائیں"</string> <string name="app_info" msgid="6856026610594615344">"ایپ کی معلومات"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"اس آلہ کو معمولاً استعمال کرنے کیلئے فیکٹری ری سیٹ کریں"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"مزید جاننے کیلئے ٹچ کریں۔"</string> </resources> diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml index 8da4e41627f7..f95a37d62e05 100644 --- a/core/res/res/values-uz-rUZ/strings.xml +++ b/core/res/res/values-uz-rUZ/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Ovozli yordam"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Qulflash"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Kontent yashirildi"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Qoidaga muvofiq kontent yashirilgan"</string> <string name="safeMode" msgid="2788228061547930246">"Xavfsiz usul"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Sozlash uchun bosing."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"USB orqali nosozliklarni tuzatish"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"O‘chirib qo‘yish uchun bosing."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Xatoliklar hisoboti olinmoqda…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Xatoliklar hisoboti yuborilsinmi?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Xatoliklar hisoboti yuborilmoqda…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Administratoringiz bu qurilma nosozliklarini tuzatish uchun xatoliklar hisobotini so‘ramoqda. Ilova va ma’lumotlardan foydalanilishi mumkin."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"ULASHISH"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"RAD ETISH"</string> <string name="select_input_method" msgid="8547250819326693584">"Klaviaturani o‘zgartirish"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Klaviaturani tanlash"</string> <string name="show_ime" msgid="2506087537466597099">"Tashqi klaviaturadan foydalanilayotganda buni ekranda saqlab turish"</string> @@ -1140,8 +1135,9 @@ <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 rejimi"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Shartlarni taqdim etuvchi"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Bildirishnoma yordamchisi"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Bildirishnomalarni baholash xizmati"</string> <string name="vpn_title" msgid="19615213552042827">"VPN faollashtirildi"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN <xliff:g id="APP">%s</xliff:g> tomonidan faollashtirilgan"</string> <string name="vpn_text" msgid="3011306607126450322">"Tarmoqni boshqarish uchun bosing."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Olib tashlash"</string> <string name="app_info" msgid="6856026610594615344">"Ilova haqida"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Bu qurilmadan odatdagidek foydalanish uchun zavod sozlamalarini tiklang"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Ko‘proq o‘rganish uchun bosing."</string> </resources> diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml index 3dcab7d793b4..283198f435df 100644 --- a/core/res/res/values-vi/strings.xml +++ b/core/res/res/values-vi/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Trợ lý thoại"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Khóa ngay"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Nội dung bị ẩn"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Nội dung bị ẩn theo chính sách"</string> <string name="safeMode" msgid="2788228061547930246">"Chế độ an toàn"</string> @@ -1136,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Hình nền"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Thay đổi hình nền"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Trình xử lý thông báo"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Trình nghe VR"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Trình cung cấp điều kiện"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Trợ lý thông báo"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Dịch vụ xếp hạng thông báo"</string> <string name="vpn_title" msgid="19615213552042827">"Đã kích hoạt VPN"</string> <string name="vpn_title_long" msgid="6400714798049252294">"VPN được <xliff:g id="APP">%s</xliff:g> kích hoạt"</string> <string name="vpn_text" msgid="3011306607126450322">"Chạm để quản lý mạng."</string> @@ -1564,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Bỏ ghim"</string> <string name="app_info" msgid="6856026610594615344">"Thông tin ứng dụng"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Thiết lập cài đặt gốc để sử dụng thiết bị này một cách bình thường"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Chạm để tìm hiểu thêm."</string> </resources> diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml index 58d385d4e872..8dfbaed93296 100644 --- a/core/res/res/values-zh-rCN/strings.xml +++ b/core/res/res/values-zh-rCN/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"语音助理"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"立即锁定"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g> 条)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"内容已隐藏"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"内容已隐藏(根据政策规定)"</string> <string name="safeMode" msgid="2788228061547930246">"安全模式"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"触摸以查看更多选项。"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"已连接到USB调试"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"触摸可停用USB调试。"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在生成错误报告…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享错误报告吗?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"正在分享错误报告…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"您的 IT 管理员希望获取错误报告,以便排查此设备的问题。报告可能会透露您设备上的应用和数据。"</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"分享"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"拒绝"</string> <string name="select_input_method" msgid="8547250819326693584">"更改键盘"</string> <string name="configure_input_methods" msgid="4769971288371946846">"选择键盘"</string> <string name="show_ime" msgid="2506087537466597099">"连接到实体键盘时使其在屏幕上保持显示状态"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"条件提供程序"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"通知助手"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"通知重要性排序服务"</string> <string name="vpn_title" msgid="19615213552042827">"已激活VPN"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g>已激活VPN"</string> <string name="vpn_text" msgid="3011306607126450322">"触摸可管理网络。"</string> @@ -1336,9 +1332,9 @@ <string name="kg_text_message_separator" product="default" msgid="4160700433287233771">" — "</string> <string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"删除"</string> <string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"要将音量调高到推荐水平以上吗?\n\n长时间保持高音量可能会损伤听力。"</string> - <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"持续按住双指即可启用无障碍功能。"</string> - <string name="accessibility_enabled" msgid="1381972048564547685">"无障碍功能已启用。"</string> - <string name="enable_accessibility_canceled" msgid="3833923257966635673">"已取消无障碍功能。"</string> + <string name="continue_to_enable_accessibility" msgid="1626427372316070258">"持续按住双指即可启用辅助功能。"</string> + <string name="accessibility_enabled" msgid="1381972048564547685">"辅助功能已启用。"</string> + <string name="enable_accessibility_canceled" msgid="3833923257966635673">"已取消辅助功能。"</string> <string name="user_switched" msgid="3768006783166984410">"当前用户是<xliff:g id="NAME">%1$s</xliff:g>。"</string> <string name="user_switching_message" msgid="2871009331809089783">"正在切换为<xliff:g id="NAME">%1$s</xliff:g>…"</string> <string name="user_logging_out_message" msgid="8939524935808875155">"正在将<xliff:g id="NAME">%1$s</xliff:g>退出帐号…"</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"取消固定"</string> <string name="app_info" msgid="6856026610594615344">"应用信息"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"恢复出厂设置即可正常使用此设备"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"触摸即可了解详情。"</string> </resources> diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml index faa320d0dcff..c52d84371178 100644 --- a/core/res/res/values-zh-rHK/strings.xml +++ b/core/res/res/values-zh-rHK/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"語音助手"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"立即鎖定"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"內容已隱藏"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"已根據政策隱藏內容"</string> <string name="safeMode" msgid="2788228061547930246">"安全模式"</string> @@ -1136,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"條件供應商"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"通知小幫手"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"通知排序服務"</string> <string name="vpn_title" msgid="19615213552042827">"VPN 已啟用。"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> 已啟用 VPN"</string> <string name="vpn_text" msgid="3011306607126450322">"輕觸即可管理網絡。"</string> @@ -1564,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"取消固定"</string> <string name="app_info" msgid="6856026610594615344">"應用程式資料"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"將此裝置回復至原廠設定,方可正常使用"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"輕觸以瞭解詳情。"</string> </resources> diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml index d6820db2bcd6..8ff0fed42aaf 100644 --- a/core/res/res/values-zh-rTW/strings.xml +++ b/core/res/res/values-zh-rTW/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"語音小幫手"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"立即鎖定"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"超過 999"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"內容已隱藏"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"內容已依據政策隱藏"</string> <string name="safeMode" msgid="2788228061547930246">"安全模式"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"輕觸即可顯示更多選項。"</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"已連接 USB 偵錯工具"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"輕觸即可停用 USB 偵錯。"</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"正在接收錯誤報告…"</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"要分享錯誤報告嗎?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"正在分享錯誤報告…"</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"您的 IT 管理員要求您提供錯誤報告,以便排解這個裝置發生的問題。報告可能會揭露裝置中的應用程式和相關資料。"</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"分享"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"拒絕"</string> <string name="select_input_method" msgid="8547250819326693584">"變更鍵盤"</string> <string name="configure_input_methods" msgid="4769971288371946846">"選擇鍵盤"</string> <string name="show_ime" msgid="2506087537466597099">"有連接的實體鍵盤時保持顯示"</string> @@ -1140,8 +1135,9 @@ <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="condition_provider_service_binding_label" msgid="1321343352906524564">"條件提供者"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"通知小幫手"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"通知重要性排序服務"</string> <string name="vpn_title" msgid="19615213552042827">"VPN 已啟用"</string> <string name="vpn_title_long" msgid="6400714798049252294">"<xliff:g id="APP">%s</xliff:g> 已啟用 VPN"</string> <string name="vpn_text" msgid="3011306607126450322">"輕觸即可管理網路。"</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"取消固定"</string> <string name="app_info" msgid="6856026610594615344">"應用程式資訊"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"恢復原廠設定即可正常使用這個裝置"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"輕觸即可瞭解詳情。"</string> </resources> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index ed5ec7d282fe..fe2c8a61c8cd 100644 --- a/core/res/res/values-zu/strings.xml +++ b/core/res/res/values-zu/strings.xml @@ -229,7 +229,6 @@ <string name="global_action_voice_assist" msgid="7751191495200504480">"Isisekeli sezwi"</string> <string name="global_action_lockdown" msgid="8751542514724332873">"Khiya manje"</string> <string name="status_bar_notification_info_overflow" msgid="5301981741705354993">"999+"</string> - <string name="notification_children_count_bracketed" msgid="1769425473168347839">"(<xliff:g id="NOTIFICATIONCOUNT">%d</xliff:g>)"</string> <string name="notification_hidden_text" msgid="1135169301897151909">"Okuqukethwe kufihliwe"</string> <string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Okuqukethwe kufihlwe inqubomgomo"</string> <string name="safeMode" msgid="2788228061547930246">"Imodi ephephile"</string> @@ -1052,16 +1051,12 @@ <string name="usb_notification_message" msgid="7347368030849048437">"Thinta ukuze uthole ezinye izinketho."</string> <string name="adb_active_notification_title" msgid="6729044778949189918">"Ukulungisa iphutha le-USB kuxhunyiwe"</string> <string name="adb_active_notification_message" msgid="1016654627626476142">"Thinta ukwenza ukuthi ukudibhaga kwe-USB kungasebenzi."</string> - <!-- no translation found for taking_remote_bugreport_notification_title (6742483073875060934) --> - <skip /> + <string name="taking_remote_bugreport_notification_title" msgid="6742483073875060934">"Ithatha umbiko wesiphazamisi..."</string> <string name="share_remote_bugreport_notification_title" msgid="4987095013583691873">"Yabelana ngombiko wesiphazamisi?"</string> <string name="sharing_remote_bugreport_notification_title" msgid="7572089031496651372">"Yabelana ngombiko wesiphazamisi..."</string> - <!-- no translation found for share_remote_bugreport_notification_message_finished (8610614010660772643) --> - <skip /> - <!-- no translation found for share_remote_bugreport_action (6249476773913384948) --> - <skip /> - <!-- no translation found for decline_remote_bugreport_action (6230987241608770062) --> - <skip /> + <string name="share_remote_bugreport_notification_message_finished" msgid="8610614010660772643">"Umqondisi wakho we-IT ucele umbiko wesiphazamisi ukukusiza ukuxazulula inkinga kule divayisi. Izinhlelo zokusebenza nedatha ingabiwa."</string> + <string name="share_remote_bugreport_action" msgid="6249476773913384948">"YABELANA"</string> + <string name="decline_remote_bugreport_action" msgid="6230987241608770062">"YENQABA"</string> <string name="select_input_method" msgid="8547250819326693584">"Shintsha ikhibhodi"</string> <string name="configure_input_methods" msgid="4769971288371946846">"Khetha amakhibhodi"</string> <string name="show_ime" msgid="2506087537466597099">"Yigcine kusikrini ngenkathi kusebenza ikhibhodi ephathekayo"</string> @@ -1140,8 +1135,9 @@ <string name="wallpaper_binding_label" msgid="1240087844304687662">"Iphephadonga"</string> <string name="chooser_wallpaper" msgid="7873476199295190279">"Shintsha iphephadonga"</string> <string name="notification_listener_binding_label" msgid="2014162835481906429">"Umlaleli wesaziso"</string> + <string name="vr_listener_binding_label" msgid="4316591939343607306">"Isilaleli se-VR"</string> <string name="condition_provider_service_binding_label" msgid="1321343352906524564">"Umhlinzeki wesimo"</string> - <string name="notification_assistant_binding_label" msgid="909456055569102952">"Umsizi wesaziso"</string> + <string name="notification_ranker_binding_label" msgid="774540592299064747">"Isevisi yesilinganisi sesaziso"</string> <string name="vpn_title" msgid="19615213552042827">"I-VPN isiyasebenza"</string> <string name="vpn_title_long" msgid="6400714798049252294">"i-VPN ivuswe ngu <xliff:g id="APP">%s</xliff:g>"</string> <string name="vpn_text" msgid="3011306607126450322">"Thinta ukuze wengamele inethiwekhi."</string> @@ -1568,4 +1564,6 @@ <string name="unpin_target" msgid="3556545602439143442">"Susa ukuphina"</string> <string name="app_info" msgid="6856026610594615344">"Ulwazi lohlelo lokusebenza"</string> <string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string> + <string name="audit_safemode_notification" msgid="6351827251856877200">"Setha kabusha ngokwefekthri ukuze usebenzise le divayisi ngokuvamile"</string> + <string name="audit_safemode_notification_details" msgid="1860601176690176413">"Thinta ukuze ufunde kabanzi."</string> </resources> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 9ccd7f0a77dd..50c7bfbd0d0f 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -593,6 +593,9 @@ i the appearance matches the branding of the app requesting the fingerprint scan.--> <attr name="fingerprintAuthDrawable" format="reference" /> + <!-- Asset that should be used to show users the position of the NFC antenna on the device. --> + <attr name="nfcAntennaPositionDrawable" format="reference" /> + <!-- ============ --> <!-- Panel styles --> <!-- ============ --> diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml index 7857107106ce..51cd0299b4f2 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) @@ -2440,9 +2447,13 @@ flag). --> <bool name="config_forceWindowDrawsStatusBarBackground">true</bool> - <!-- If set, this will force the navigation bar to always be drawn with an opaque - background. --> - <bool name="config_forceNavBarAlwaysOpaque">false</bool> + <!-- Controls the opacity of the navigation bar depending on the visibility of the + various workspace stacks. + 0 - Nav bar is always opaque when either the freeform stack or docked stack is visible. + 1 - Nav bar is always translucent when the freeform stack is visible, otherwise always + opaque. + --> + <integer name="config_navBarOpacityMode">0</integer> <!-- Default bounds [left top right bottom] on screen for picture-in-picture windows. --> <string translatable="false" name="config_defaultPictureInPictureBounds">"0 0 100 100"</string> diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 152473afe077..081d6135c680 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -151,16 +151,13 @@ <dimen name="notification_content_picture_margin">56dp</dimen> <!-- height of the content margin to accomodate for the header --> - <dimen name="notification_content_margin_top">30dp</dimen> + <dimen name="notification_content_margin_top">37.5dp</dimen> <!-- height of the content margin on the bottom --> - <dimen name="notification_content_margin_bottom">13dp</dimen> - - <!-- height of notification header view if present --> - <dimen name="notification_header_height">32dp</dimen> + <dimen name="notification_content_margin_bottom">16dp</dimen> <!-- Height of a small notification in the status bar --> - <dimen name="notification_min_height">84dp</dimen> + <dimen name="notification_min_height">92dp</dimen> <!-- The width of the big icons in notifications. --> <dimen name="notification_large_icon_width">64dp</dimen> @@ -177,7 +174,7 @@ <dimen name="media_notification_expanded_image_max_size">94dp</dimen> <!-- The maximum size of the image in the expanded media notification --> - <dimen name="media_notification_expanded_image_margin_bottom">16dp</dimen> + <dimen name="media_notification_expanded_image_margin_bottom">20dp</dimen> <!-- The margin of the content to an image--> <dimen name="notification_content_image_margin_end">8dp</dimen> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 06e2248bbb5a..2b0ef4266ee1 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -2705,6 +2705,7 @@ <public type="attr" name="countDown" /> <public type="attr" name="canRecord" /> <public type="attr" name="tunerCount" /> + <public type="attr" name="nfcAntennaPositionDrawable" /> <public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" /> <public type="style" name="Widget.Material.SeekBar.Discrete" /> diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml index cad0e7b4570e..14707413c4dc 100644 --- a/core/res/res/values/symbols.xml +++ b/core/res/res/values/symbols.xml @@ -382,6 +382,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" /> @@ -2394,7 +2395,7 @@ <java-symbol type="string" name="config_packagedKeyboardName" /> <java-symbol type="bool" name="config_forceWindowDrawsStatusBarBackground" /> - <java-symbol type="bool" name="config_forceNavBarAlwaysOpaque" /> + <java-symbol type="integer" name="config_navBarOpacityMode" /> <java-symbol type="color" name="system_bar_background_semi_transparent" /> <!-- EditText suggestion popup. --> @@ -2423,13 +2424,13 @@ <java-symbol type="drawable" name="ic_collapse_notification" /> <java-symbol type="drawable" name="ic_expand_bundle" /> <java-symbol type="drawable" name="ic_collapse_bundle" /> - <java-symbol type="dimen" name="notification_header_height" /> <java-symbol type="dimen" name="notification_min_content_height" /> <java-symbol type="dimen" name="notification_header_shrink_min_width" /> <java-symbol type="dimen" name="notification_content_margin_start" /> <java-symbol type="dimen" name="notification_content_margin_end" /> <java-symbol type="dimen" name="notification_content_picture_margin" /> <java-symbol type="dimen" name="notification_content_margin_top" /> + <java-symbol type="dimen" name="notification_content_margin_bottom" /> <java-symbol type="string" name="importance_from_user" /> <java-symbol type="string" name="importance_from_person" /> 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/app/DownloadManagerBaseTest.java b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java index af2a9446f348..bae4ecc14469 100644 --- a/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java +++ b/core/tests/coretests/src/android/app/DownloadManagerBaseTest.java @@ -81,8 +81,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase { protected static final int DEFAULT_WAIT_POLL_TIME = 5 * 1000; // 5 seconds protected static final int WAIT_FOR_DOWNLOAD_POLL_TIME = 1 * 1000; // 1 second - protected static final int MAX_WAIT_FOR_DOWNLOAD_TIME = 5 * 60 * 1000; // 5 minutes - protected static final int MAX_WAIT_FOR_LARGE_DOWNLOAD_TIME = 15 * 60 * 1000; // 15 minutes + protected static final int MAX_WAIT_FOR_DOWNLOAD_TIME = 30 * 1000; // 30 seconds protected static final int DOWNLOAD_TO_SYSTEM_CACHE = 1; protected static final int DOWNLOAD_TO_DOWNLOAD_CACHE_DIR = 2; @@ -970,7 +969,7 @@ public class DownloadManagerBaseTest extends InstrumentationTestCase { protected void verifyInt(Cursor cursor, String columnName, int expected) { int index = cursor.getColumnIndex(columnName); int actual = cursor.getInt(index); - assertEquals(expected, actual); + assertEquals(String.format("Expected = %d : Actual = %d", expected, actual), expected, actual); } /** diff --git a/core/tests/coretests/src/android/app/DownloadManagerFunctionalTest.java b/core/tests/coretests/src/android/app/DownloadManagerFunctionalTest.java index 7019980f46b9..4a5385256923 100644 --- a/core/tests/coretests/src/android/app/DownloadManagerFunctionalTest.java +++ b/core/tests/coretests/src/android/app/DownloadManagerFunctionalTest.java @@ -23,18 +23,16 @@ import android.net.Uri; import android.os.Environment; import android.os.ParcelFileDescriptor; import android.test.suitebuilder.annotation.LargeTest; - -import android.test.suitebuilder.annotation.Suppress; import com.google.mockwebserver.MockResponse; import java.io.File; +import java.util.concurrent.TimeoutException; import java.util.Iterator; import java.util.Set; /** * Integration tests of the DownloadManager API. */ -@Suppress // Failing. public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest { private static final String TAG = "DownloadManagerFunctionalTest"; private final static String CACHE_DIR = @@ -79,7 +77,11 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest { request.setTitle(DEFAULT_FILENAME); long dlRequest = mDownloadManager.enqueue(request); - waitForDownloadOrTimeout(dlRequest); + try { + waitForDownloadOrTimeout(dlRequest); + } catch (TimeoutException ex) { + // it is expected to timeout as download never finishes + } Cursor cursor = getCursor(dlRequest); try { @@ -114,7 +116,7 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest { verifyDownload(dlRequest, blobData); mDownloadManager.remove(dlRequest); } - + /** * Helper to verify a standard single-file download from the mock server, and clean up after * verification @@ -135,9 +137,7 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest { verifyFileSize(pfd, fileSize); verifyFileContents(pfd, fileData); - int colIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME); - String fileName = cursor.getString(colIndex); - assertTrue(fileName.startsWith(CACHE_DIR)); + assertTrue(new File(CACHE_DIR + "/" + DEFAULT_FILENAME).exists()); } finally { pfd.close(); cursor.close(); @@ -161,7 +161,6 @@ public class DownloadManagerFunctionalTest extends DownloadManagerBaseTest { Uri localUri = Uri.fromFile(existentFile); request.setDestinationUri(localUri); - long dlRequest = mDownloadManager.enqueue(request); // wait for the download to complete diff --git a/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java b/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java index 5d4648987811..47554a68645a 100644 --- a/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java +++ b/core/tests/coretests/src/android/content/res/ConfigurationBoundResourceCacheTest.java @@ -17,20 +17,18 @@ package android.content.res; import android.test.ActivityInstrumentationTestCase2; +import android.test.suitebuilder.annotation.SmallTest; import android.util.TypedValue; import com.android.frameworks.coretests.R; import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; public class ConfigurationBoundResourceCacheTest extends ActivityInstrumentationTestCase2<ResourceCacheActivity> { ConfigurationBoundResourceCache<Float> mCache; - Method mCalcConfigChanges; - public ConfigurationBoundResourceCacheTest() { super(ResourceCacheActivity.class); } @@ -41,33 +39,42 @@ public class ConfigurationBoundResourceCacheTest mCache = new ConfigurationBoundResourceCache<>(); } + @SmallTest public void testGetEmpty() { - assertNull(mCache.get(-1, null)); + final Resources res = getActivity().getResources(); + assertNull(mCache.getInstance(-1, res, null)); } + @SmallTest public void testSetGet() { mCache.put(1, null, new DummyFloatConstantState(5f)); - assertEquals(5f, mCache.get(1, null)); - assertNotSame(5f, mCache.get(1, null)); - assertEquals(null, mCache.get(1, getActivity().getTheme())); + final Resources res = getActivity().getResources(); + assertEquals(5f, mCache.getInstance(1, res, null)); + assertNotSame(5f, mCache.getInstance(1, res, null)); + assertEquals(null, mCache.getInstance(1, res, getActivity().getTheme())); } + @SmallTest public void testSetGetThemed() { mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f)); - assertEquals(null, mCache.get(1, null)); - assertEquals(5f, mCache.get(1, getActivity().getTheme())); - assertNotSame(5f, mCache.get(1, getActivity().getTheme())); + final Resources res = getActivity().getResources(); + assertEquals(null, mCache.getInstance(1, res, null)); + assertEquals(5f, mCache.getInstance(1, res, getActivity().getTheme())); + assertNotSame(5f, mCache.getInstance(1, res, getActivity().getTheme())); } + @SmallTest public void testMultiThreadPutGet() { mCache.put(1, getActivity().getTheme(), new DummyFloatConstantState(5f)); mCache.put(1, null, new DummyFloatConstantState(10f)); - assertEquals(10f, mCache.get(1, null)); - assertNotSame(10f, mCache.get(1, null)); - assertEquals(5f, mCache.get(1, getActivity().getTheme())); - assertNotSame(5f, mCache.get(1, getActivity().getTheme())); + final Resources res = getActivity().getResources(); + assertEquals(10f, mCache.getInstance(1, res, null)); + assertNotSame(10f, mCache.getInstance(1, res, null)); + assertEquals(5f, mCache.getInstance(1, res, getActivity().getTheme())); + assertNotSame(5f, mCache.getInstance(1, res, getActivity().getTheme())); } + @SmallTest public void testVoidConfigChange() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { TypedValue staticValue = new TypedValue(); @@ -83,11 +90,12 @@ public class ConfigurationBoundResourceCacheTest Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE; int changes = calcConfigChanges(res, newCnf); - assertEquals(staticDim, mCache.get(key, getActivity().getTheme())); + assertEquals(staticDim, mCache.getInstance(key, res, getActivity().getTheme())); mCache.onConfigurationChange(changes); - assertEquals(staticDim, mCache.get(key, getActivity().getTheme())); + assertEquals(staticDim, mCache.getInstance(key, res, getActivity().getTheme())); } + @SmallTest public void testEffectiveConfigChange() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { TypedValue changingValue = new TypedValue(); @@ -105,11 +113,12 @@ public class ConfigurationBoundResourceCacheTest Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE; int changes = calcConfigChanges(res, newCnf); - assertEquals(changingDim, mCache.get(key, getActivity().getTheme())); + assertEquals(changingDim, mCache.getInstance(key, res, getActivity().getTheme())); mCache.onConfigurationChange(changes); assertNull(mCache.get(key, getActivity().getTheme())); } + @SmallTest public void testConfigChangeMultipleResources() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { TypedValue staticValue = new TypedValue(); @@ -130,17 +139,19 @@ public class ConfigurationBoundResourceCacheTest Configuration.ORIENTATION_PORTRAIT : Configuration.ORIENTATION_LANDSCAPE; int changes = calcConfigChanges(res, newCnf); - assertEquals(staticDim, mCache.get(R.dimen.resource_cache_test_generic, - getActivity().getTheme())); - assertEquals(changingDim, mCache.get(R.dimen.resource_cache_test_orientation_dependent, + assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res, getActivity().getTheme())); + assertEquals(changingDim, + mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res, + getActivity().getTheme())); mCache.onConfigurationChange(changes); - assertEquals(staticDim, mCache.get(R.dimen.resource_cache_test_generic, + assertEquals(staticDim, mCache.getInstance(R.dimen.resource_cache_test_generic, res, getActivity().getTheme())); - assertNull(mCache.get(R.dimen.resource_cache_test_orientation_dependent, + assertNull(mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res, getActivity().getTheme())); } + @SmallTest public void testConfigChangeMultipleThemes() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { TypedValue[] staticValues = new TypedValue[]{new TypedValue(), new TypedValue()}; @@ -172,31 +183,27 @@ public class ConfigurationBoundResourceCacheTest int changes = calcConfigChanges(res, newCnf); for (int i = 0; i < 2; i++) { final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null; - assertEquals(staticDim, mCache.get(R.dimen.resource_cache_test_generic, theme)); + assertEquals(staticDim, + mCache.getInstance(R.dimen.resource_cache_test_generic, res, theme)); assertEquals(changingDim, - mCache.get(R.dimen.resource_cache_test_orientation_dependent, theme)); + mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res, + theme)); } mCache.onConfigurationChange(changes); for (int i = 0; i < 2; i++) { final Resources.Theme theme = i == 0 ? getActivity().getTheme() : null; - assertEquals(staticDim, mCache.get(R.dimen.resource_cache_test_generic, theme)); - assertNull(mCache.get(R.dimen.resource_cache_test_orientation_dependent, theme)); + assertEquals(staticDim, + mCache.getInstance(R.dimen.resource_cache_test_generic, res, theme)); + assertNull(mCache.getInstance(R.dimen.resource_cache_test_orientation_dependent, res, + theme)); } } - private int calcConfigChanges(Resources resources, Configuration configuration) - throws NoSuchMethodException, InvocationTargetException, IllegalAccessException { - if (mCalcConfigChanges == null) { - mCalcConfigChanges = Resources.class.getDeclaredMethod("calcConfigChanges", - Configuration.class); - mCalcConfigChanges.setAccessible(true); - } - return (Integer) mCalcConfigChanges.invoke(resources, configuration); - + private static int calcConfigChanges(Resources resources, Configuration configuration) { + return resources.calcConfigChanges(configuration); } - static class DummyFloatConstantState extends - ConstantState<Float> { + static class DummyFloatConstantState extends ConstantState<Float> { final Float mObj; diff --git a/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java new file mode 100644 index 000000000000..3cadbf64c7a3 --- /dev/null +++ b/core/tests/coretests/src/android/content/res/ResourcesManagerTest.java @@ -0,0 +1,222 @@ +/* + * 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.content.res; + +import android.annotation.NonNull; +import android.app.ResourcesManager; +import android.os.Binder; +import android.test.suitebuilder.annotation.SmallTest; +import android.util.DisplayMetrics; +import android.util.LocaleList; +import android.util.TypedValue; +import android.view.Display; +import junit.framework.TestCase; + +public class ResourcesManagerTest extends TestCase { + private static final String APP_ONE_RES_DIR = "app_one.apk"; + private static final String APP_ONE_RES_SPLIT_DIR = "app_one_split.apk"; + private static final String APP_TWO_RES_DIR = "app_two.apk"; + private static final String LIB_RES_DIR = "lib.apk"; + + private ResourcesManager mResourcesManager; + private DisplayMetrics mDisplayMetrics; + + @Override + protected void setUp() throws Exception { + super.setUp(); + + mDisplayMetrics = new DisplayMetrics(); + mDisplayMetrics.setToDefaults(); + + // Override defaults (which take device specific properties). + mDisplayMetrics.density = 1.0f; + mDisplayMetrics.densityDpi = DisplayMetrics.DENSITY_DEFAULT; + mDisplayMetrics.xdpi = DisplayMetrics.DENSITY_DEFAULT; + mDisplayMetrics.ydpi = DisplayMetrics.DENSITY_DEFAULT; + mDisplayMetrics.noncompatDensity = mDisplayMetrics.density; + mDisplayMetrics.noncompatDensityDpi = mDisplayMetrics.densityDpi; + mDisplayMetrics.noncompatXdpi = DisplayMetrics.DENSITY_DEFAULT; + mDisplayMetrics.noncompatYdpi = DisplayMetrics.DENSITY_DEFAULT; + + mResourcesManager = new ResourcesManager() { + @Override + protected AssetManager createAssetManager(@NonNull ResourcesKey key) { + return new AssetManager(); + } + + @Override + protected DisplayMetrics getDisplayMetricsLocked(int displayId) { + return mDisplayMetrics; + } + }; + } + + @SmallTest + public void testMultipleCallsWithIdenticalParametersCacheReference() { + Resources resources = mResourcesManager.getResources( + null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, + CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(resources); + + Resources newResources = mResourcesManager.getResources( + null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, + CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(newResources); + assertSame(resources, newResources); + } + + @SmallTest + public void testMultipleCallsWithDifferentParametersReturnDifferentReferences() { + Resources resources = mResourcesManager.getResources( + null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, + CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(resources); + + Configuration overrideConfig = new Configuration(); + overrideConfig.smallestScreenWidthDp = 200; + Resources newResources = mResourcesManager.getResources( + null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, overrideConfig, + CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(newResources); + assertNotSame(resources, newResources); + } + + @SmallTest + public void testAddingASplitCreatesANewImpl() { + Resources resources1 = mResourcesManager.getResources( + null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, + CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(resources1); + + Resources resources2 = mResourcesManager.getResources( + null, APP_ONE_RES_DIR, new String[] { APP_ONE_RES_SPLIT_DIR }, null, null, + Display.DEFAULT_DISPLAY, null, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(resources2); + + assertNotSame(resources1, resources2); + assertNotSame(resources1.getImpl(), resources2.getImpl()); + } + + @SmallTest + public void testUpdateConfigurationUpdatesAllAssetManagers() { + Resources resources1 = mResourcesManager.getResources( + null, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, + CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(resources1); + + Resources resources2 = mResourcesManager.getResources( + null, APP_TWO_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, + CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(resources2); + + Binder activity = new Binder(); + final Configuration overrideConfig = new Configuration(); + overrideConfig.orientation = Configuration.ORIENTATION_LANDSCAPE; + Resources resources3 = mResourcesManager.getResources( + activity, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, + overrideConfig, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(resources3); + + // No Resources object should be the same. + assertNotSame(resources1, resources2); + assertNotSame(resources1, resources3); + assertNotSame(resources2, resources3); + + // Each ResourcesImpl should be different. + assertNotSame(resources1.getImpl(), resources2.getImpl()); + assertNotSame(resources1.getImpl(), resources3.getImpl()); + assertNotSame(resources2.getImpl(), resources3.getImpl()); + + Configuration newConfig = new Configuration(); + newConfig.orientation = Configuration.ORIENTATION_LANDSCAPE; + mResourcesManager.applyConfigurationToResourcesLocked(newConfig, null); + + final Configuration expectedConfig = new Configuration(); + expectedConfig.setLocales(LocaleList.getAdjustedDefault()); + expectedConfig.densityDpi = mDisplayMetrics.densityDpi; + expectedConfig.orientation = Configuration.ORIENTATION_LANDSCAPE; + + assertEquals(expectedConfig, resources1.getConfiguration()); + assertEquals(expectedConfig, resources2.getConfiguration()); + assertEquals(expectedConfig, resources3.getConfiguration()); + } + + @SmallTest + public void testTwoActivitiesWithIdenticalParametersShareImpl() { + Binder activity1 = new Binder(); + Resources resources1 = mResourcesManager.getResources( + activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, + CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(resources1); + + Binder activity2 = new Binder(); + Resources resources2 = mResourcesManager.getResources( + activity2, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, + CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(resources1); + + // The references themselves should be unique. + assertNotSame(resources1, resources2); + + // The implementations should be the same. + assertSame(resources1.getImpl(), resources2.getImpl()); + + final Configuration overrideConfig = new Configuration(); + overrideConfig.orientation = Configuration.ORIENTATION_LANDSCAPE; + Resources resources3 = mResourcesManager.getResources( + activity2, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, + overrideConfig, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + + // Since we requested new resources for activity2, the resource should be the same + // as the one returned before for activity2. + assertSame(resources2, resources3); + + // But the implementation has changed. + assertNotSame(resources1.getImpl(), resources2.getImpl()); + } + + @SmallTest + public void testThemesGetUpdatedWithNewImpl() { + Binder activity1 = new Binder(); + Resources resources1 = mResourcesManager.getResources( + activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, null, + CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(resources1); + + Resources.Theme theme = resources1.newTheme(); + assertSame(resources1, theme.getResources()); + theme.applyStyle(android.R.style.Theme_NoTitleBar, false); + + TypedValue value = new TypedValue(); + assertTrue(theme.resolveAttribute(android.R.attr.windowNoTitle, value, true)); + assertEquals(TypedValue.TYPE_INT_BOOLEAN, value.type); + assertTrue(value.data != 0); + + final Configuration overrideConfig = new Configuration(); + overrideConfig.orientation = Configuration.ORIENTATION_LANDSCAPE; + Resources resources2 = mResourcesManager.getResources( + activity1, APP_ONE_RES_DIR, null, null, null, Display.DEFAULT_DISPLAY, + overrideConfig, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null); + assertNotNull(resources2); + assertSame(resources1, resources2); + assertSame(resources2, theme.getResources()); + + // Make sure we can still access the data. + assertTrue(theme.resolveAttribute(android.R.attr.windowNoTitle, value, true)); + assertEquals(TypedValue.TYPE_INT_BOOLEAN, value.type); + assertTrue(value.data != 0); + } +} 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/android/widget/TextViewActivityMouseTest.java b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java index 00df87d19b94..923b8299a60a 100644 --- a/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java +++ b/core/tests/coretests/src/android/widget/TextViewActivityMouseTest.java @@ -143,6 +143,8 @@ public class TextViewActivityMouseTest extends ActivityInstrumentationTestCase2< onView(withId(R.id.textview)).check(hasSelection("")); onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex(text.indexOf("i"))); + + // TODO: Add tests for suggestions } @SmallTest diff --git a/core/tests/coretests/src/android/widget/TextViewActivityTest.java b/core/tests/coretests/src/android/widget/TextViewActivityTest.java index 5dae4a878bf4..844eadbae692 100644 --- a/core/tests/coretests/src/android/widget/TextViewActivityTest.java +++ b/core/tests/coretests/src/android/widget/TextViewActivityTest.java @@ -44,6 +44,7 @@ import static android.support.test.espresso.matcher.ViewMatchers.withText; import com.android.frameworks.coretests.R; +import android.support.test.espresso.action.EspressoKey; import android.test.ActivityInstrumentationTestCase2; import android.test.suitebuilder.annotation.SmallTest; import android.view.KeyEvent; @@ -172,6 +173,12 @@ public class TextViewActivityTest extends ActivityInstrumentationTestCase2<TextV onView(withId(R.id.textview)).check(hasSelection("")); assertNoSelectionHandles(); onView(withId(R.id.textview)).check(hasInsertionPointerAtIndex("abc ghi.def".length())); + + // Test undo returns to the original state. + onView(withId(R.id.textview)).perform(pressKey( + (new EspressoKey.Builder()).withCtrlPressed(true).withKeyCode(KeyEvent.KEYCODE_Z) + .build())); + onView(withId(R.id.textview)).check(matches(withText(text))); } @SmallTest 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 719b274f80f9..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,9 +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, @@ -242,6 +261,8 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { subtypes.add(autoSubtype); // overridesImplicitlyEnabledSubtype == true subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype); subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2); + subtypes.add(nonAutoHandwritingEn); + subtypes.add(nonAutoHandwritingFr); final InputMethodInfo imi = createDummyInputMethodInfo( "com.android.apps.inputmethod.latin", "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT, @@ -264,6 +285,8 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { subtypes.add(nonAutoFil); subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype); subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2); + subtypes.add(nonAutoHandwritingEn); + subtypes.add(nonAutoHandwritingFr); final InputMethodInfo imi = createDummyInputMethodInfo( "com.android.apps.inputmethod.latin", "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT, @@ -271,7 +294,9 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { final ArrayList<InputMethodSubtype> result = InputMethodUtils.getImplicitlyApplicableSubtypesLocked( getResourcesForLocales(LOCALE_EN_US), imi); + assertEquals(2, result.size()); verifyEquality(nonAutoEnUS, result.get(0)); + verifyEquality(nonAutoHandwritingEn, result.get(1)); } // Make sure that a subtype whose locale is exactly equal to the specified locale is @@ -284,6 +309,8 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { subtypes.add(nonAutoJa); subtypes.add(nonAutoFil); subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype); + subtypes.add(nonAutoHandwritingEn); + subtypes.add(nonAutoHandwritingFr); final InputMethodInfo imi = createDummyInputMethodInfo( "com.android.apps.inputmethod.latin", "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT, @@ -291,8 +318,9 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { final ArrayList<InputMethodSubtype> result = InputMethodUtils.getImplicitlyApplicableSubtypesLocked( getResourcesForLocales(LOCALE_EN_GB), imi); - assertEquals(1, result.size()); + assertEquals(2, result.size()); verifyEquality(nonAutoEnGB, result.get(0)); + verifyEquality(nonAutoHandwritingEn, result.get(1)); } // If there is no automatic subtype (overridesImplicitlyEnabledSubtype:true) and @@ -306,6 +334,8 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { subtypes.add(nonAutoFil); subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype); subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2); + subtypes.add(nonAutoHandwritingEn); + subtypes.add(nonAutoHandwritingFr); final InputMethodInfo imi = createDummyInputMethodInfo( "com.android.apps.inputmethod.latin", "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT, @@ -313,8 +343,9 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { final ArrayList<InputMethodSubtype> result = InputMethodUtils.getImplicitlyApplicableSubtypesLocked( getResourcesForLocales(LOCALE_FR), imi); - assertEquals(1, result.size()); + assertEquals(2, result.size()); verifyEquality(nonAutoFrCA, result.get(0)); + verifyEquality(nonAutoHandwritingFr, result.get(1)); } // Then make sure that a subtype (locale: "fr") can be found with locale: "fr_CA". { @@ -324,6 +355,8 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { subtypes.add(nonAutoFil); subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype); subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2); + subtypes.add(nonAutoHandwritingEn); + subtypes.add(nonAutoHandwritingFr); final InputMethodInfo imi = createDummyInputMethodInfo( "com.android.apps.inputmethod.latin", "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT, @@ -331,8 +364,9 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { final ArrayList<InputMethodSubtype> result = InputMethodUtils.getImplicitlyApplicableSubtypesLocked( getResourcesForLocales(LOCALE_FR_CA), imi); - assertEquals(1, result.size()); + assertEquals(2, result.size()); verifyEquality(nonAutoFrCA, result.get(0)); + verifyEquality(nonAutoHandwritingFr, result.get(1)); } // Make sure that subtypes which have "EnabledWhenDefaultIsNotAsciiCapable" in its @@ -343,6 +377,8 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { subtypes.add(nonAutoJa); // not ASCII capable subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype); subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype2); + subtypes.add(nonAutoHandwritingEn); + subtypes.add(nonAutoHandwritingFr); final InputMethodInfo imi = createDummyInputMethodInfo( "com.android.apps.inputmethod.latin", "com.android.apps.inputmethod.latin", "DummyLatinIme", !IS_AUX, IS_DEFAULT, @@ -363,6 +399,7 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { subtypes.add(nonAutoHi); subtypes.add(nonAutoEnUS); subtypes.add(nonAutoHandwritingEn); + subtypes.add(nonAutoHandwritingFr); subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype); final InputMethodInfo imi = createDummyInputMethodInfo( "com.android.apps.inputmethod.latin", @@ -379,6 +416,7 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { subtypes.add(nonAutoEnUS); subtypes.add(nonAutoHi); subtypes.add(nonAutoHandwritingEn); + subtypes.add(nonAutoHandwritingFr); subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype); final InputMethodInfo imi = createDummyInputMethodInfo( "com.android.apps.inputmethod.latin", @@ -393,6 +431,7 @@ public class InputMethodUtilsTest extends InstrumentationTestCase { { final ArrayList<InputMethodSubtype> subtypes = new ArrayList<>(); subtypes.add(nonAutoHandwritingEn); + subtypes.add(nonAutoHandwritingFr); subtypes.add(nonAutoEnUS); subtypes.add(nonAutoHi); subtypes.add(nonAutoEnabledWhenDefaultIsNotAsciiCalableSubtype); @@ -407,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<>(); @@ -755,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); @@ -773,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/core/tests/coretests/src/com/android/internal/util/ArrayUtilsTest.java b/core/tests/coretests/src/com/android/internal/util/ArrayUtilsTest.java new file mode 100644 index 000000000000..b3897ceb6e79 --- /dev/null +++ b/core/tests/coretests/src/com/android/internal/util/ArrayUtilsTest.java @@ -0,0 +1,119 @@ +/* + * 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.internal.util; + +import android.test.suitebuilder.annotation.SmallTest; +import junit.framework.TestCase; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; + +public class ArrayUtilsTest extends TestCase { + + @SmallTest + public void testUnstableRemoveIf() throws Exception { + java.util.function.Predicate<Object> isNull = new java.util.function.Predicate<Object>() { + @Override + public boolean test(Object o) { + return o == null; + } + }; + + final Object a = new Object(); + final Object b = new Object(); + final Object c = new Object(); + + ArrayList<Object> collection = null; + assertEquals(0, ArrayUtils.unstableRemoveIf(collection, isNull)); + + collection = new ArrayList<>(); + assertEquals(0, ArrayUtils.unstableRemoveIf(collection, isNull)); + + collection = new ArrayList<>(Collections.singletonList(a)); + assertEquals(0, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(1, collection.size()); + assertTrue(collection.contains(a)); + + collection = new ArrayList<>(Collections.singletonList(null)); + assertEquals(1, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(0, collection.size()); + + collection = new ArrayList<>(Arrays.asList(a, b)); + assertEquals(0, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(2, collection.size()); + assertTrue(collection.contains(a)); + assertTrue(collection.contains(b)); + + collection = new ArrayList<>(Arrays.asList(a, null)); + assertEquals(1, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(1, collection.size()); + assertTrue(collection.contains(a)); + + collection = new ArrayList<>(Arrays.asList(null, a)); + assertEquals(1, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(1, collection.size()); + assertTrue(collection.contains(a)); + + collection = new ArrayList<>(Arrays.asList(null, null)); + assertEquals(2, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(0, collection.size()); + + collection = new ArrayList<>(Arrays.asList(a, b, c)); + assertEquals(0, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(3, collection.size()); + assertTrue(collection.contains(a)); + assertTrue(collection.contains(b)); + assertTrue(collection.contains(c)); + + collection = new ArrayList<>(Arrays.asList(a, b, null)); + assertEquals(1, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(2, collection.size()); + assertTrue(collection.contains(a)); + assertTrue(collection.contains(b)); + + collection = new ArrayList<>(Arrays.asList(a, null, b)); + assertEquals(1, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(2, collection.size()); + assertTrue(collection.contains(a)); + assertTrue(collection.contains(b)); + + collection = new ArrayList<>(Arrays.asList(null, a, b)); + assertEquals(1, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(2, collection.size()); + assertTrue(collection.contains(a)); + assertTrue(collection.contains(b)); + + collection = new ArrayList<>(Arrays.asList(a, null, null)); + assertEquals(2, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(1, collection.size()); + assertTrue(collection.contains(a)); + + collection = new ArrayList<>(Arrays.asList(null, null, a)); + assertEquals(2, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(1, collection.size()); + assertTrue(collection.contains(a)); + + collection = new ArrayList<>(Arrays.asList(null, a, null)); + assertEquals(2, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(1, collection.size()); + assertTrue(collection.contains(a)); + + collection = new ArrayList<>(Arrays.asList(null, null, null)); + assertEquals(3, ArrayUtils.unstableRemoveIf(collection, isNull)); + assertEquals(0, collection.size()); + } +} diff --git a/core/tests/systemproperties/Android.mk b/core/tests/systemproperties/Android.mk index 0c20876c6520..b51239622b5c 100644 --- a/core/tests/systemproperties/Android.mk +++ b/core/tests/systemproperties/Android.mk @@ -9,7 +9,7 @@ LOCAL_SRC_FILES := \ $(call all-java-files-under, src) LOCAL_DX_FLAGS := --core-library -LOCAL_STATIC_JAVA_LIBRARIES := core-tests android-common frameworks-core-util-lib +LOCAL_STATIC_JAVA_LIBRARIES := android-common frameworks-core-util-lib LOCAL_JAVA_LIBRARIES := android.test.runner LOCAL_PACKAGE_NAME := FrameworksCoreSystemPropertiesTests LOCAL_JAVA_LANGUAGE_VERSION := 1.8 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/data/fonts/fonts.xml b/data/fonts/fonts.xml index dc302c719af7..bcac6a10a464 100644 --- a/data/fonts/fonts.xml +++ b/data/fonts/fonts.xml @@ -88,242 +88,246 @@ </family> <!-- fallback fonts --> - <family variant="elegant"> + <family lang="und-Arab" variant="elegant"> <font weight="400" style="normal">NotoNaskhArabic-Regular.ttf</font> <font weight="700" style="normal">NotoNaskhArabic-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Arab" variant="compact"> <font weight="400" style="normal">NotoNaskhArabicUI-Regular.ttf</font> <font weight="700" style="normal">NotoNaskhArabicUI-Bold.ttf</font> </family> - <family> + <family lang="und-Ethi"> <font weight="400" style="normal">NotoSansEthiopic-Regular.ttf</font> <font weight="700" style="normal">NotoSansEthiopic-Bold.ttf</font> </family> - <family> + <family lang="und-Hebr"> <font weight="400" style="normal">NotoSansHebrew-Regular.ttf</font> <font weight="700" style="normal">NotoSansHebrew-Bold.ttf</font> </family> - <family variant="elegant"> + <family lang="und-Thai" variant="elegant"> <font weight="400" style="normal">NotoSansThai-Regular.ttf</font> <font weight="700" style="normal">NotoSansThai-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Thai" variant="compact"> <font weight="400" style="normal">NotoSansThaiUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansThaiUI-Bold.ttf</font> </family> - <family> + <family lang="und-Armn"> <font weight="400" style="normal">NotoSansArmenian-Regular.ttf</font> <font weight="700" style="normal">NotoSansArmenian-Bold.ttf</font> </family> - <family> + <!-- TODO: add Geok --> + <family lang="und-Geor"> <font weight="400" style="normal">NotoSansGeorgian-Regular.ttf</font> <font weight="700" style="normal">NotoSansGeorgian-Bold.ttf</font> </family> - <family variant="elegant"> + <family lang="und-Deva" variant="elegant"> <font weight="400" style="normal">NotoSansDevanagari-Regular.ttf</font> <font weight="700" style="normal">NotoSansDevanagari-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Deva" variant="compact"> <font weight="400" style="normal">NotoSansDevanagariUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansDevanagariUI-Bold.ttf</font> </family> - <!-- Gujarati should come after Devanagari --> - <family variant="elegant"> + + <!-- All scripts of India should come after Devanagari, due to shared + danda characters. + --> + <family lang="und-Gujr" variant="elegant"> <font weight="400" style="normal">NotoSansGujarati-Regular.ttf</font> <font weight="700" style="normal">NotoSansGujarati-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Gujr" variant="compact"> <font weight="400" style="normal">NotoSansGujaratiUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansGujaratiUI-Bold.ttf</font> </family> - <!-- Gurmukhi should come after Devanagari --> - <family variant="elegant"> + <family lang="und-Guru" variant="elegant"> <font weight="400" style="normal">NotoSansGurmukhi-Regular.ttf</font> <font weight="700" style="normal">NotoSansGurmukhi-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Guru" variant="compact"> <font weight="400" style="normal">NotoSansGurmukhiUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansGurmukhiUI-Bold.ttf</font> </family> - <family variant="elegant"> + <family lang="und-Taml" variant="elegant"> <font weight="400" style="normal">NotoSansTamil-Regular.ttf</font> <font weight="700" style="normal">NotoSansTamil-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Taml" variant="compact"> <font weight="400" style="normal">NotoSansTamilUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansTamilUI-Bold.ttf</font> </family> - <family variant="elegant"> + <family lang="und-Mlym" variant="elegant"> <font weight="400" style="normal">NotoSansMalayalam-Regular.ttf</font> <font weight="700" style="normal">NotoSansMalayalam-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Mlym" variant="compact"> <font weight="400" style="normal">NotoSansMalayalamUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansMalayalamUI-Bold.ttf</font> </family> - <family variant="elegant"> + <family lang="und-Beng" variant="elegant"> <font weight="400" style="normal">NotoSansBengali-Regular.ttf</font> <font weight="700" style="normal">NotoSansBengali-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Beng" variant="compact"> <font weight="400" style="normal">NotoSansBengaliUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansBengaliUI-Bold.ttf</font> </family> - <family variant="elegant"> + <family lang="und-Telu" variant="elegant"> <font weight="400" style="normal">NotoSansTelugu-Regular.ttf</font> <font weight="700" style="normal">NotoSansTelugu-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Telu" variant="compact"> <font weight="400" style="normal">NotoSansTeluguUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansTeluguUI-Bold.ttf</font> </family> - <family variant="elegant"> + <family lang="und-Knda" variant="elegant"> <font weight="400" style="normal">NotoSansKannada-Regular.ttf</font> <font weight="700" style="normal">NotoSansKannada-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Knda" variant="compact"> <font weight="400" style="normal">NotoSansKannadaUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansKannadaUI-Bold.ttf</font> </family> - <family variant="elegant"> + <family lang="und-Orya" variant="elegant"> <font weight="400" style="normal">NotoSansOriya-Regular.ttf</font> <font weight="700" style="normal">NotoSansOriya-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Orya" variant="compact"> <font weight="400" style="normal">NotoSansOriyaUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansOriyaUI-Bold.ttf</font> </family> - <family> + + <family lang="und-Sinh"> <font weight="400" style="normal">NotoSansSinhala-Regular.ttf</font> <font weight="700" style="normal">NotoSansSinhala-Bold.ttf</font> </family> - <family variant="elegant"> + <family lang="und-Khmr" variant="elegant"> <font weight="400" style="normal">NotoSansKhmer-Regular.ttf</font> <font weight="700" style="normal">NotoSansKhmer-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Khmr" variant="compact"> <font weight="400" style="normal">NotoSansKhmerUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansKhmerUI-Bold.ttf</font> </family> - <family variant="elegant"> + <family lang="und-Laoo" variant="elegant"> <font weight="400" style="normal">NotoSansLao-Regular.ttf</font> <font weight="700" style="normal">NotoSansLao-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Laoo" variant="compact"> <font weight="400" style="normal">NotoSansLaoUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansLaoUI-Bold.ttf</font> </family> - <family variant="elegant"> + <family lang="und-Mymr" variant="elegant"> <font weight="400" style="normal">NotoSansMyanmar-Regular.ttf</font> <font weight="700" style="normal">NotoSansMyanmar-Bold.ttf</font> </family> - <family variant="compact"> + <family lang="und-Mymr" variant="compact"> <font weight="400" style="normal">NotoSansMyanmarUI-Regular.ttf</font> <font weight="700" style="normal">NotoSansMyanmarUI-Bold.ttf</font> </family> - <family> + <family lang="und-Thaa"> <font weight="400" style="normal">NotoSansThaana-Regular.ttf</font> <font weight="700" style="normal">NotoSansThaana-Bold.ttf</font> </family> - <family> + <family lang="und-Cham"> <font weight="400" style="normal">NotoSansCham-Regular.ttf</font> <font weight="700" style="normal">NotoSansCham-Bold.ttf</font> </family> - <family> + <family lang="und-Bali"> <font weight="400" style="normal">NotoSansBalinese-Regular.ttf</font> </family> - <family> + <family lang="und-Bamu"> <font weight="400" style="normal">NotoSansBamum-Regular.ttf</font> </family> - <family> + <family lang="und-Batk"> <font weight="400" style="normal">NotoSansBatak-Regular.ttf</font> </family> - <family> + <family lang="und-Bugi"> <font weight="400" style="normal">NotoSansBuginese-Regular.ttf</font> </family> - <family> + <family lang="und-Buhd"> <font weight="400" style="normal">NotoSansBuhid-Regular.ttf</font> </family> - <family> + <family lang="und-Cans"> <font weight="400" style="normal">NotoSansCanadianAboriginal-Regular.ttf</font> </family> - <family> + <family lang="und-Cher"> <font weight="400" style="normal">NotoSansCherokee-Regular.ttf</font> </family> - <family> + <family lang="und-Copt"> <font weight="400" style="normal">NotoSansCoptic-Regular.ttf</font> </family> - <family> + <family lang="und-Glag"> <font weight="400" style="normal">NotoSansGlagolitic-Regular.ttf</font> </family> - <family> + <family lang="und-Hano"> <font weight="400" style="normal">NotoSansHanunoo-Regular.ttf</font> </family> - <family> + <family lang="und-Java"> <font weight="400" style="normal">NotoSansJavanese-Regular.ttf</font> </family> - <family> + <family lang="und-Kali"> <font weight="400" style="normal">NotoSansKayahLi-Regular.ttf</font> </family> - <family> + <family lang="und-Lepc"> <font weight="400" style="normal">NotoSansLepcha-Regular.ttf</font> </family> - <family> + <family lang="und-Limb"> <font weight="400" style="normal">NotoSansLimbu-Regular.ttf</font> </family> - <family> + <family lang="und-Lisu"> <font weight="400" style="normal">NotoSansLisu-Regular.ttf</font> </family> - <family> + <family lang="und-Mand"> <font weight="400" style="normal">NotoSansMandaic-Regular.ttf</font> </family> - <family> + <family lang="und-Mtei"> <font weight="400" style="normal">NotoSansMeeteiMayek-Regular.ttf</font> </family> - <family> + <family lang="und-Talu"> <font weight="400" style="normal">NotoSansNewTaiLue-Regular.ttf</font> </family> - <family> + <family lang="und-Nkoo"> <font weight="400" style="normal">NotoSansNKo-Regular.ttf</font> </family> - <family> + <family lang="und-Olck"> <font weight="400" style="normal">NotoSansOlChiki-Regular.ttf</font> </family> - <family> + <family lang="und-Rjng"> <font weight="400" style="normal">NotoSansRejang-Regular.ttf</font> </family> - <family> + <family lang="und-Saur"> <font weight="400" style="normal">NotoSansSaurashtra-Regular.ttf</font> </family> - <family> + <family lang="und-Sund"> <font weight="400" style="normal">NotoSansSundanese-Regular.ttf</font> </family> - <family> + <family lang="und-Sylo"> <font weight="400" style="normal">NotoSansSylotiNagri-Regular.ttf</font> </family> - <family> + <family lang="und-Syre"> <font weight="400" style="normal">NotoSansSyriacEstrangela-Regular.ttf</font> </family> - <family> + <family lang="und-Tagb"> <font weight="400" style="normal">NotoSansTagbanwa-Regular.ttf</font> </family> - <family> + <family lang="und-Lana"> <font weight="400" style="normal">NotoSansTaiTham-Regular.ttf</font> </family> - <family> + <family lang="und-Tavt"> <font weight="400" style="normal">NotoSansTaiViet-Regular.ttf</font> </family> - <family> + <family lang="und-Tibt"> <font weight="400" style="normal">NotoSansTibetan-Regular.ttf</font> </family> - <family> + <family lang="und-Tfng"> <font weight="400" style="normal">NotoSansTifinagh-Regular.ttf</font> </family> - <family> + <family lang="und-Vaii"> <font weight="400" style="normal">NotoSansVai-Regular.ttf</font> </family> - <family> + <family lang="und-Yiii"> <font weight="400" style="normal">NotoSansYi-Regular.ttf</font> </family> <family> @@ -332,6 +336,7 @@ <family lang="zh-Hans"> <font weight="400" style="normal" index="2">NotoSansCJK-Regular.ttc</font> </family> + <!-- TODO: Add Bopo --> <family lang="zh-Hant"> <font weight="400" style="normal" index="3">NotoSansCJK-Regular.ttc</font> </family> @@ -351,10 +356,10 @@ Tai Le and Mongolian are intentionally kept last, to make sure they don't override the East Asian punctuation for Chinese. --> - <family> + <family lang="und-Tale"> <font weight="400" style="normal">NotoSansTaiLe-Regular.ttf</font> </family> - <family> + <family lang="und-Mong"> <font weight="400" style="normal">NotoSansMongolian-Regular.ttf</font> </family> </familyset> diff --git a/docs/docs-documentation-redirect.html b/docs/docs-documentation-redirect.html index 98a265e87665..dbdf8b45acea 100644 --- a/docs/docs-documentation-redirect.html +++ b/docs/docs-documentation-redirect.html @@ -1,9 +1,9 @@ <html> <head> -<meta http-equiv="refresh" content="0;url=documentation.html"> +<meta http-equiv="refresh" content="0;url=reference/packages.html"> </head> <body> -<a href="documentation.html">click here if you are not redirected</a> +<a href="reference/packages.html">click here if you are not redirected</a> </body> </html> diff --git a/docs/docs-preview-index.html b/docs/docs-preview-index.html new file mode 100644 index 000000000000..e26b57c6c1eb --- /dev/null +++ b/docs/docs-preview-index.html @@ -0,0 +1,103 @@ +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" /> +<meta content="IE=edge" http-equiv="X-UA-Compatible"> +<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" /> + +<title>Android N Developer Preview</title> + +<!-- STYLESHEETS --> +<link rel="stylesheet" +href="http://fonts.googleapis.com/css?family=Roboto+Condensed"> +<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Roboto:light,regular,medium,thin,italic,mediumitalic,bold" + title="roboto"> +<link href="assets/css/default.css?v=17" rel="stylesheet" type="text/css"> +<!-- JAVASCRIPT --> +<script src="https://www.google.com/jsapi" type="text/javascript"></script> +<script src="assets/js/android_3p-bundle.js" type="text/javascript"></script> +<script type="text/javascript"> + var toRoot = "../"; + var metaTags = ["develop, getstarted, sdk, appquality, landing"]; + var devsite = false; +</script> +<script src="assets/js/docs.js?v=3" type="text/javascript"></script> +</head> + +<body> +<div id="header-wrapper"> + <div class="dac-header" id="header"> + <div class="dac-header-inner"> + <a class="dac-nav-toggle" data-dac-toggle-nav="" href="javascript:;" + title="Open navigation"> + <span class="dac-nav-hamburger"> + <span class="dac-nav-hamburger-top"></span> + <span class="dac-nav-hamburger-mid"></span> + <span class="dac-nav-hamburger-bot"></span> + </span> + </a> + <a class="dac-header-logo" href="index.html"> + <img class="dac-header-logo-image" src="assets/images/android_logo.png" + srcset="assets/images/android_logo@2x.png 2x" width="32" height="36" + alt="Android"> Developers + </a> + </div> + </div> +</div> +<nav class="dac-nav"> + <div class="dac-nav-dimmer" data-dac-toggle-nav=""></div> + <ul class="dac-nav-list" data-dac-nav=""> + <li class="dac-nav-item dac-nav-head"> + <a class="dac-nav-link dac-nav-logo" data-dac-toggle-nav="" + href="javascript:;" title="Close navigation"> + <img class="dac-logo-image" src="assets/images/android_logo.png" + srcset="assets/images/android_logo@2x.png 2x" width="32" height="36" + alt="Android"> Developers + </a> + </li> + <li class="dac-nav-item develop"> + <a class="dac-nav-link" href="reference/packages.html" + >API Reference</a> + </li> + </ul> +</nav> + +<section class="dac-expand" style="padding-top:40px;background-color:#eee"> + <div class="wrap" style="max-width:1100px;margin-top:0;height:100%"> + <div class="cols dac-hero-content" style="padding-bottom:1em;"> + <div class="col-11of16"> + + +<h1>Android N Developer Preview</h1> +<p> + Get ready for Android N! + <strong>Test your apps</strong> on Nexus devices. Support new system + behaviors to <strong>save power and memory</strong>. + Extend your apps with <strong>multi-window UI</strong>, + <strong>direct reply notifications</strong> and more. +</p> + +<h2>Get Started</h2> +<ul> + <li>View the <a href="reference/packages.html">API Reference</a></li> + <li>Read Diff Reports:</a> + <ul> + <li><a href="sdk/api_diff/n-preview-1/changes.html" + >API 23 --> Preview 1</a></li> + </ul> + </li> + <li>Downloads and additional documentation are available at the + <a href="http://developer.android.com/preview/index.html"> + Android N Developer Preview site</a></li> + <li>For information about Developer Preview 1, visit the + <a href="http://developer.android.com/preview/support.html">Support</a> + page.</li> +</ul> + + + </div> + </div> + </div> +</section> +</body> +</html> 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 ca214ab115ef..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; @@ -35,6 +36,7 @@ import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Insets; import android.graphics.Outline; +import android.graphics.PixelFormat; import android.graphics.PorterDuff; import android.graphics.Rect; import android.os.Build; @@ -229,7 +231,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | mAnimatedVectorState.getChangingConfigurations(); } @@ -259,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(); @@ -275,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); } @@ -307,7 +321,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { @Override public int getOpacity() { - return mAnimatedVectorState.mVectorDrawable.getOpacity(); + return PixelFormat.TRANSLUCENT; } @Override @@ -436,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. */ @@ -500,7 +514,7 @@ public class AnimatedVectorDrawable extends Drawable implements Animatable2 { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations; } @@ -702,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 f9208cd6c256..bcc354c5b736 100644 --- a/graphics/java/android/graphics/drawable/GradientDrawable.java +++ b/graphics/java/android/graphics/drawable/GradientDrawable.java @@ -17,8 +17,10 @@ package android.graphics.drawable; 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; @@ -51,6 +53,8 @@ import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; import java.io.IOException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * A Drawable with a color gradient for buttons, backgrounds, etc. @@ -108,6 +112,11 @@ public class GradientDrawable extends Drawable { */ public static final int RING = 3; + /** @hide */ + @IntDef({RECTANGLE, OVAL, LINE, RING}) + @Retention(RetentionPolicy.SOURCE) + public @interface Shape {} + /** * Gradient is linear (default.) */ @@ -123,6 +132,11 @@ public class GradientDrawable extends Drawable { */ public static final int SWEEP_GRADIENT = 2; + /** @hide */ + @IntDef({LINEAR_GRADIENT, RADIAL_GRADIENT, SWEEP_GRADIENT}) + @Retention(RetentionPolicy.SOURCE) + public @interface GradientType {} + /** Radius is in pixels. */ private static final int RADIUS_TYPE_PIXELS = 0; @@ -132,6 +146,11 @@ public class GradientDrawable extends Drawable { /** Radius is a fraction of the bounds size. */ private static final int RADIUS_TYPE_FRACTION_PARENT = 2; + /** @hide */ + @IntDef({RADIUS_TYPE_PIXELS, RADIUS_TYPE_FRACTION, RADIUS_TYPE_FRACTION_PARENT}) + @Retention(RetentionPolicy.SOURCE) + public @interface RadiusType {} + private static final float DEFAULT_INNER_RADIUS_RATIO = 3.0f; private static final float DEFAULT_THICKNESS_RATIO = 9.0f; @@ -404,7 +423,7 @@ public class GradientDrawable extends Drawable { * * @see #mutate() */ - public void setShape(int shape) { + public void setShape(@Shape int shape) { mRingPath = null; mPathIsDirty = true; mGradientState.setShape(shape); @@ -412,6 +431,18 @@ public class GradientDrawable extends Drawable { } /** + * Returns the type of shape used by this drawable, one of {@link #LINE}, + * {@link #OVAL}, {@link #RECTANGLE} or {@link #RING}. + * + * @return the type of shape used by this drawable + * @see #setShape(int) + */ + @Shape + public int getShape() { + return mGradientState.mShape; + } + + /** * Sets the type of gradient used by this drawable. * <p> * <strong>Note</strong>: changing this property will affect all instances @@ -424,7 +455,7 @@ public class GradientDrawable extends Drawable { * @see #mutate() * @see #getGradientType() */ - public void setGradientType(int gradient) { + public void setGradientType(@GradientType int gradient) { mGradientState.setGradientType(gradient); mGradientIsDirty = true; invalidateSelf(); @@ -438,6 +469,7 @@ public class GradientDrawable extends Drawable { * @return the type of gradient used by this drawable * @see #setGradientType(int) */ + @GradientType public int getGradientType() { return mGradientState.mGradient; } @@ -534,7 +566,7 @@ public class GradientDrawable extends Drawable { * @see #mutate() * @see #setLevel(int) * @see #getLevel() - * @see #isUseLevel() + * @see #getUseLevel() */ public void setUseLevel(boolean useLevel) { mGradientState.mUseLevel = useLevel; @@ -550,7 +582,7 @@ public class GradientDrawable extends Drawable { * {@code false} otherwise * @see #setUseLevel(boolean) */ - public boolean isUseLevel() { + public boolean getUseLevel() { return mGradientState.mUseLevel; } @@ -616,7 +648,8 @@ public class GradientDrawable extends Drawable { */ @Nullable public int[] getColors() { - return mGradientState.mGradientColors.clone(); + return mGradientState.mGradientColors == null ? + null : mGradientState.mGradientColors.clone(); } @Override @@ -848,7 +881,7 @@ public class GradientDrawable extends Drawable { * @see #mutate() * @see #getColor */ - public void setColor(ColorStateList colorStateList) { + public void setColor(@Nullable ColorStateList colorStateList) { mGradientState.setSolidColors(colorStateList); final int color; if (colorStateList == null) { @@ -870,6 +903,7 @@ public class GradientDrawable extends Drawable { * @see #setColor(int) * @see #setColor(ColorStateList) */ + @Nullable public ColorStateList getColor() { return mGradientState.mSolidColors; } @@ -925,7 +959,7 @@ public class GradientDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | mGradientState.getChangingConfigurations(); } @@ -951,12 +985,13 @@ public class GradientDrawable extends Drawable { } @Override + @Nullable public ColorFilter getColorFilter() { return mColorFilter; } @Override - public void setColorFilter(ColorFilter colorFilter) { + public void setColorFilter(@Nullable ColorFilter colorFilter) { if (colorFilter != mColorFilter) { mColorFilter = colorFilter; invalidateSelf(); @@ -964,14 +999,14 @@ public class GradientDrawable extends Drawable { } @Override - public void setTintList(ColorStateList tint) { + public void setTintList(@Nullable ColorStateList tint) { mGradientState.mTint = tint; mTintFilter = updateTintFilter(mTintFilter, tint, mGradientState.mTintMode); invalidateSelf(); } @Override - public void setTintMode(PorterDuff.Mode tintMode) { + public void setTintMode(@Nullable PorterDuff.Mode tintMode) { mGradientState.mTintMode = tintMode; mTintFilter = updateTintFilter(mTintFilter, mGradientState.mTint, tintMode); invalidateSelf(); @@ -1543,7 +1578,7 @@ public class GradientDrawable extends Drawable { final TypedValue tv = a.peekValue(R.styleable.GradientDrawableGradient_gradientRadius); if (tv != null) { final float radius; - final int radiusType; + final @RadiusType int radiusType; if (tv.type == TypedValue.TYPE_FRACTION) { radius = tv.getFraction(1.0f, 1.0f); @@ -1624,7 +1659,9 @@ public class GradientDrawable extends Drawable { return false; } - if (!isOpaque(mFillPaint.getColor())) { + // Don't check opacity if we're using a gradient, as we've already + // checked the gradient opacity in mOpaqueOverShape. + if (mGradientState.mGradientColors == null && !isOpaque(mFillPaint.getColor())) { return false; } @@ -1698,15 +1735,15 @@ public class GradientDrawable extends Drawable { } final static class GradientState extends ConstantState { - public int mChangingConfigurations; - public int mShape = RECTANGLE; - public int mGradient = LINEAR_GRADIENT; + public @Config int mChangingConfigurations; + public @Shape int mShape = RECTANGLE; + public @GradientType int mGradient = LINEAR_GRADIENT; public int mAngle = 0; public Orientation mOrientation; public ColorStateList mSolidColors; public ColorStateList mStrokeColors; - public int[] mGradientColors; - public int[] mTempColors; // no need to copy + public @ColorInt int[] mGradientColors; + public @ColorInt int[] mTempColors; // no need to copy public float[] mTempPositions; // no need to copy public float[] mPositions; public int mStrokeWidth = -1; // if >= 0 use stroking. @@ -1727,7 +1764,7 @@ public class GradientDrawable extends Drawable { float mCenterX = 0.5f; float mCenterY = 0.5f; float mGradientRadius = 0.5f; - int mGradientRadiusType = RADIUS_TYPE_PIXELS; + @RadiusType int mGradientRadiusType = RADIUS_TYPE_PIXELS; boolean mUseLevel = false; boolean mUseLevelForShape = true; @@ -1926,19 +1963,19 @@ 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) | (mTint != null ? mTint.getChangingConfigurations() : 0); } - public void setShape(int shape) { + public void setShape(@Shape int shape) { mShape = shape; computeOpacity(); } - public void setGradientType(int gradient) { + public void setGradientType(@GradientType int gradient) { mGradient = gradient; } @@ -1947,13 +1984,13 @@ public class GradientDrawable extends Drawable { mCenterY = y; } - public void setGradientColors(int[] colors) { + public void setGradientColors(@Nullable int[] colors) { mGradientColors = colors; mSolidColors = null; computeOpacity(); } - public void setSolidColors(ColorStateList colors) { + public void setSolidColors(@Nullable ColorStateList colors) { mGradientColors = null; mSolidColors = colors; computeOpacity(); @@ -1984,7 +2021,8 @@ public class GradientDrawable extends Drawable { && mRadiusArray == null; } - public void setStroke(int width, ColorStateList colors, float dashWidth, float dashGap) { + public void setStroke(int width, @Nullable ColorStateList colors, float dashWidth, + float dashGap) { mStrokeWidth = width; mStrokeColors = colors; mStrokeDashWidth = dashWidth; @@ -2012,7 +2050,7 @@ public class GradientDrawable extends Drawable { mHeight = height; } - public void setGradientRadius(float gradientRadius, int type) { + public void setGradientRadius(float gradientRadius, @RadiusType int type) { mGradientRadius = gradientRadius; mGradientRadiusType = type; } diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java index 0de4c2cffa17..51221b4a303e 100644 --- a/graphics/java/android/graphics/drawable/Icon.java +++ b/graphics/java/android/graphics/drawable/Icon.java @@ -627,6 +627,11 @@ public final class Icon implements Parcelable { return this; } + /** @hide */ + public boolean hasTint() { + return (mTintList != null) || (mTintMode != DEFAULT_TINT_MODE); + } + /** * Create an Icon pointing to an image file specified by path. * 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 9e0f1b460839..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; @@ -364,7 +365,9 @@ public class VectorDrawable extends Drawable { @Override public int getOpacity() { - return PixelFormat.TRANSLUCENT; + // We can't tell whether the drawable is fully opaque unless we examine all the pixels, + // but we could tell it is transparent if the root alpha is 0. + return getAlpha() == 0 ? PixelFormat.TRANSPARENT : PixelFormat.TRANSLUCENT; } @Override @@ -684,7 +687,7 @@ public class VectorDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return super.getChangingConfigurations() | mVectorState.getChangingConfigurations(); } @@ -712,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; @@ -821,7 +824,7 @@ public class VectorDrawable extends Drawable { } @Override - public int getChangingConfigurations() { + public @Config int getChangingConfigurations() { return mChangingConfigurations | (mTint != null ? mTint.getChangingConfigurations() : 0); } @@ -921,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; @@ -1167,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/include/androidfw/ResourceTypes.h b/include/androidfw/ResourceTypes.h index 6813c89be32f..05596f0f7986 100644 --- a/include/androidfw/ResourceTypes.h +++ b/include/androidfw/ResourceTypes.h @@ -35,6 +35,8 @@ #include <android/configuration.h> +#include <memory> + namespace android { /** @@ -1876,9 +1878,30 @@ private: struct Entry; struct Package; struct PackageGroup; - struct bag_set; typedef Vector<Type*> TypeList; + struct bag_set { + size_t numAttrs; // number in array + size_t availAttrs; // total space in array + uint32_t typeSpecFlags; + // Followed by 'numAttr' bag_entry structures. + }; + + /** + * Configuration dependent cached data. This must be cleared when the configuration is + * changed (setParameters). + */ + struct TypeCacheEntry { + TypeCacheEntry() : cachedBags(NULL) {} + + // Computed attribute bags for this type. + bag_set** cachedBags; + + // Pre-filtered list of configurations (per asset path) that match the parameters set on this + // ResTable. + Vector<std::shared_ptr<Vector<const ResTable_type*>>> filteredConfigs; + }; + status_t addInternal(const void* data, size_t size, const void* idmapData, size_t idmapDataSize, bool appAsLib, const int32_t cookie, bool copyData, bool isSystemAsset=false); @@ -1900,6 +1923,13 @@ private: mutable Mutex mLock; + // Mutex that controls access to the list of pre-filtered configurations + // to check when looking up entries. + // When iterating over a bag, the mLock mutex is locked. While mLock is locked, + // we do resource lookups. + // Mutex is not reentrant, so we must use a different lock than mLock. + mutable Mutex mFilteredConfigLock; + status_t mError; ResTable_config mParams; diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp index bf6ff11ee791..52fe9734478e 100644 --- a/libs/androidfw/ResourceTypes.cpp +++ b/libs/androidfw/ResourceTypes.cpp @@ -25,6 +25,7 @@ #include <string.h> #include <limits> +#include <memory> #include <type_traits> #include <androidfw/ByteBucketArray.h> @@ -3193,7 +3194,6 @@ struct ResTable::PackageGroup , name(_name) , id(_id) , largestTypeId(0) - , bags(NULL) , dynamicRefTable(static_cast<uint8_t>(_id), appAsLib) , isSystemAsset(_isSystemAsset) { } @@ -3220,36 +3220,41 @@ struct ResTable::PackageGroup } } + /** + * Clear all cache related data that depends on parameters/configuration. + * This includes the bag caches and filtered types. + */ void clearBagCache() { - if (bags) { + for (size_t i = 0; i < typeCacheEntries.size(); i++) { if (kDebugTableNoisy) { - printf("bags=%p\n", bags); + printf("type=%zu\n", i); } - for (size_t i = 0; i < bags->size(); i++) { + const TypeList& typeList = types[i]; + if (!typeList.isEmpty()) { + TypeCacheEntry& cacheEntry = typeCacheEntries.editItemAt(i); + + // Reset the filtered configurations. + cacheEntry.filteredConfigs.clear(); + + bag_set** typeBags = cacheEntry.cachedBags; if (kDebugTableNoisy) { - printf("type=%zu\n", i); + printf("typeBags=%p\n", typeBags); } - const TypeList& typeList = types[i]; - if (!typeList.isEmpty()) { - bag_set** typeBags = bags->get(i); + + if (typeBags) { + const size_t N = typeList[0]->entryCount; if (kDebugTableNoisy) { - printf("typeBags=%p\n", typeBags); + printf("type->entryCount=%zu\n", N); } - if (typeBags) { - const size_t N = typeList[0]->entryCount; - if (kDebugTableNoisy) { - printf("type->entryCount=%zu\n", N); - } - for (size_t j = 0; j < N; j++) { - if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF) - free(typeBags[j]); + for (size_t j = 0; j < N; j++) { + if (typeBags[j] && typeBags[j] != (bag_set*)0xFFFFFFFF) { + free(typeBags[j]); } - free(typeBags); } + free(typeBags); + cacheEntry.cachedBags = NULL; } } - delete bags; - bags = NULL; } } @@ -3277,9 +3282,11 @@ struct ResTable::PackageGroup uint8_t largestTypeId; - // Computed attribute bags, first indexed by the type and second - // by the entry in that type. - ByteBucketArray<bag_set**>* bags; + // Cached objects dependent on the parameters/configuration of this ResTable. + // Gets cleared whenever the parameters/configuration changes. + // These are stored here in a parallel structure because the data in `types` may + // be shared by other ResTable's (framework resources are shared this way). + ByteBucketArray<TypeCacheEntry> typeCacheEntries; // The table mapping dynamic references to resolved references for // this package group. @@ -3293,14 +3300,6 @@ struct ResTable::PackageGroup const bool isSystemAsset; }; -struct ResTable::bag_set -{ - size_t numAttrs; // number in array - size_t availAttrs; // total space in array - uint32_t typeSpecFlags; - // Followed by 'numAttr' bag_entry structures. -}; - ResTable::Theme::Theme(const ResTable& table) : mTable(table) , mTypeSpecFlags(0) @@ -4192,39 +4191,32 @@ ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag, } // First see if we've already computed this bag... - if (grp->bags) { - bag_set** typeSet = grp->bags->get(t); - if (typeSet) { - bag_set* set = typeSet[e]; - if (set) { - if (set != (bag_set*)0xFFFFFFFF) { - if (outTypeSpecFlags != NULL) { - *outTypeSpecFlags = set->typeSpecFlags; - } - *outBag = (bag_entry*)(set+1); - if (kDebugTableSuperNoisy) { - ALOGI("Found existing bag for: 0x%x\n", resID); - } - return set->numAttrs; + TypeCacheEntry& cacheEntry = grp->typeCacheEntries.editItemAt(t); + bag_set** typeSet = cacheEntry.cachedBags; + if (typeSet) { + bag_set* set = typeSet[e]; + if (set) { + if (set != (bag_set*)0xFFFFFFFF) { + if (outTypeSpecFlags != NULL) { + *outTypeSpecFlags = set->typeSpecFlags; } - ALOGW("Attempt to retrieve bag 0x%08x which is invalid or in a cycle.", - resID); - return BAD_INDEX; + *outBag = (bag_entry*)(set+1); + if (kDebugTableSuperNoisy) { + ALOGI("Found existing bag for: 0x%x\n", resID); + } + return set->numAttrs; } + ALOGW("Attempt to retrieve bag 0x%08x which is invalid or in a cycle.", + resID); + return BAD_INDEX; } } // Bag not found, we need to compute it! - if (!grp->bags) { - grp->bags = new ByteBucketArray<bag_set**>(); - if (!grp->bags) return NO_MEMORY; - } - - bag_set** typeSet = grp->bags->get(t); if (!typeSet) { typeSet = (bag_set**)calloc(NENTRY, sizeof(bag_set*)); if (!typeSet) return NO_MEMORY; - grp->bags->set(t, typeSet); + cacheEntry.cachedBags = typeSet; } // Mark that we are currently working on this one. @@ -4430,18 +4422,56 @@ ssize_t ResTable::getBagLocked(uint32_t resID, const bag_entry** outBag, void ResTable::setParameters(const ResTable_config* params) { - mLock.lock(); + AutoMutex _lock(mLock); + AutoMutex _lock2(mFilteredConfigLock); + if (kDebugTableGetEntry) { ALOGI("Setting parameters: %s\n", params->toString().string()); } mParams = *params; - for (size_t i=0; i<mPackageGroups.size(); i++) { + for (size_t p = 0; p < mPackageGroups.size(); p++) { + PackageGroup* packageGroup = mPackageGroups.editItemAt(p); if (kDebugTableNoisy) { - ALOGI("CLEARING BAGS FOR GROUP %zu!", i); + ALOGI("CLEARING BAGS FOR GROUP %zu!", p); + } + packageGroup->clearBagCache(); + + // Find which configurations match the set of parameters. This allows for a much + // faster lookup in getEntry() if the set of values is narrowed down. + for (size_t t = 0; t < packageGroup->types.size(); t++) { + if (packageGroup->types[t].isEmpty()) { + continue; + } + + TypeList& typeList = packageGroup->types.editItemAt(t); + + // Retrieve the cache entry for this type. + TypeCacheEntry& cacheEntry = packageGroup->typeCacheEntries.editItemAt(t); + + for (size_t ts = 0; ts < typeList.size(); ts++) { + Type* type = typeList.editItemAt(ts); + + std::shared_ptr<Vector<const ResTable_type*>> newFilteredConfigs = + std::make_shared<Vector<const ResTable_type*>>(); + + for (size_t ti = 0; ti < type->configs.size(); ti++) { + ResTable_config config; + config.copyFromDtoH(type->configs[ti]->config); + + if (config.match(mParams)) { + newFilteredConfigs->add(type->configs[ti]); + } + } + + if (kDebugTableNoisy) { + ALOGD("Updating pkg=%zu type=%zu with %zu filtered configs", + p, t, newFilteredConfigs->size()); + } + + cacheEntry.filteredConfigs.add(newFilteredConfigs); + } } - mPackageGroups[i]->clearBagCache(); } - mLock.unlock(); } void ResTable::getParameters(ResTable_config* params) const @@ -5974,9 +6004,32 @@ status_t ResTable::getEntry( specFlags = -1; } - const size_t numConfigs = typeSpec->configs.size(); + const Vector<const ResTable_type*>* candidateConfigs = &typeSpec->configs; + + std::shared_ptr<Vector<const ResTable_type*>> filteredConfigs; + if (config && memcmp(&mParams, config, sizeof(mParams)) == 0) { + // Grab the lock first so we can safely get the current filtered list. + AutoMutex _lock(mFilteredConfigLock); + + // This configuration is equal to the one we have previously cached for, + // so use the filtered configs. + + const TypeCacheEntry& cacheEntry = packageGroup->typeCacheEntries[typeIndex]; + if (i < cacheEntry.filteredConfigs.size()) { + if (cacheEntry.filteredConfigs[i]) { + // Grab a reference to the shared_ptr so it doesn't get destroyed while + // going through this list. + filteredConfigs = cacheEntry.filteredConfigs[i]; + + // Use this filtered list. + candidateConfigs = filteredConfigs.get(); + } + } + } + + const size_t numConfigs = candidateConfigs->size(); for (size_t c = 0; c < numConfigs; c++) { - const ResTable_type* const thisType = typeSpec->configs[c]; + const ResTable_type* const thisType = candidateConfigs->itemAt(c); if (thisType == NULL) { continue; } diff --git a/libs/androidfw/tests/ResTable_test.cpp b/libs/androidfw/tests/ResTable_test.cpp index dcfe91e3866d..7cd7fb5cd711 100644 --- a/libs/androidfw/tests/ResTable_test.cpp +++ b/libs/androidfw/tests/ResTable_test.cpp @@ -282,4 +282,46 @@ TEST(ResTableTest, U16StringToInt) { testU16StringToInt(u"0x1ffffffff", 0U, false, true); } +TEST(ResTableTest, ShareButDontModifyResTable) { + ResTable sharedTable; + ASSERT_EQ(NO_ERROR, sharedTable.add(basic_arsc, basic_arsc_len)); + + ResTable_config param; + memset(¶m, 0, sizeof(param)); + param.language[0] = 'v'; + param.language[1] = 's'; + sharedTable.setParameters(¶m); + + // Check that we get the default value for @integer:number1 + Res_value val; + ssize_t block = sharedTable.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG); + ASSERT_GE(block, 0); + ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); + ASSERT_EQ(uint32_t(600), val.data); + + // Create a new table that shares the entries of the shared table. + ResTable table; + ASSERT_EQ(NO_ERROR, table.add(&sharedTable, false)); + + // Set a new configuration on the new table. + memset(¶m, 0, sizeof(param)); + param.language[0] = 's'; + param.language[1] = 'v'; + param.country[0] = 'S'; + param.country[1] = 'E'; + table.setParameters(¶m); + + // Check that we get a new value in the new table. + block = table.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG); + ASSERT_GE(block, 0); + ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); + ASSERT_EQ(uint32_t(400), val.data); + + // Check that we still get the old value in the shared table. + block = sharedTable.getResource(base::R::integer::number1, &val, MAY_NOT_BE_BAG); + ASSERT_GE(block, 0); + ASSERT_EQ(Res_value::TYPE_INT_DEC, val.dataType); + ASSERT_EQ(uint32_t(600), val.data); } + +} // namespace diff --git a/libs/androidfw/tests/data/basic/R.h b/libs/androidfw/tests/data/basic/R.h index aaac74059f58..6694dd0c36e1 100644 --- a/libs/androidfw/tests/data/basic/R.h +++ b/libs/androidfw/tests/data/basic/R.h @@ -46,7 +46,7 @@ namespace string { namespace integer { enum { - number1 = 0x7f040000, // default, sv + number1 = 0x7f040000, // default, sv, vs number2 = 0x7f040001, // default test3 = 0x7f090000, // default (in feature) diff --git a/libs/androidfw/tests/data/basic/basic_arsc.h b/libs/androidfw/tests/data/basic/basic_arsc.h index 13ab4fa0d0ea..e497401bdddb 100644 --- a/libs/androidfw/tests/data/basic/basic_arsc.h +++ b/libs/androidfw/tests/data/basic/basic_arsc.h @@ -1,5 +1,5 @@ unsigned char basic_arsc[] = { - 0x02, 0x00, 0x0c, 0x00, 0x68, 0x07, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x0c, 0x00, 0x0c, 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0xbc, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, @@ -16,7 +16,7 @@ unsigned char basic_arsc[] = { 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x31, 0x00, 0x00, 0x00, 0x05, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x32, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, - 0xa0, 0x06, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, + 0x44, 0x07, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, @@ -73,68 +73,81 @@ unsigned char basic_arsc[] = { 0x41, 0x00, 0x72, 0x00, 0x72, 0x00, 0x61, 0x00, 0x79, 0x00, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x84, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x4c, 0x00, 0x8c, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, - 0x05, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x24, 0x00, 0x00, - 0x01, 0x02, 0x44, 0x00, 0x58, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x1c, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + 0x08, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x08, 0x00, 0x00, 0x10, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x24, 0x00, 0x00, 0x01, 0x02, 0x4c, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x58, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x48, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x4c, 0x00, + 0x60, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x02, + 0x00, 0x00, 0x00, 0x00, 0x4c, 0x61, 0x74, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x44, 0x00, 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x4c, 0x00, 0x78, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x6c, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x4c, 0x00, 0x74, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0xc8, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x01, - 0x00, 0x00, 0x06, 0x7f, 0x01, 0x02, 0x44, 0x00, 0x5c, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, + 0xc8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x06, 0x7f, 0x01, 0x02, 0x4c, 0x00, + 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x54, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x76, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x90, 0x01, 0x00, 0x00, - 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x44, 0x00, 0x90, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, 0x58, 0x02, 0x00, 0x00, + 0x01, 0x02, 0x4c, 0x00, 0x64, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x73, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x61, 0x74, 0x6e, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x08, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x10, + 0x90, 0x01, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x4c, 0x00, 0x98, 0x00, 0x00, 0x00, + 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x54, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -146,16 +159,17 @@ unsigned char basic_arsc[] = { 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x7f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x7f, 0x08, 0x00, 0x00, 0x10, 0x2c, 0x01, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, - 0x7c, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x48, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x4c, 0x00, + 0x84, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x50, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, - 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x02, 0x08, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, 0x09, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + 0x08, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x02, + 0x08, 0x00, 0x00, 0x10, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x02, + 0x08, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x00 }; -unsigned int basic_arsc_len = 1896; +unsigned int basic_arsc_len = 2060; diff --git a/packages/DocumentsUI/res/animator/dir_frozen.xml b/libs/androidfw/tests/data/basic/res/values-vs/values.xml index b541d137c5d9..4a5a64016e68 100644 --- a/packages/DocumentsUI/res/animator/dir_frozen.xml +++ b/libs/androidfw/tests/data/basic/res/values-vs/values.xml @@ -1,4 +1,5 @@ -<!-- Copyright (C) 2013 The Android Open Source Project +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2014 The Android Open Source Project Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -13,9 +14,6 @@ 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" /> +<resources> + <integer name="number1">600</integer> +</resources> diff --git a/libs/androidfw/tests/data/basic/split_de_fr_arsc.h b/libs/androidfw/tests/data/basic/split_de_fr_arsc.h index b742d2811487..a2aa598e5c90 100644 --- a/libs/androidfw/tests/data/basic/split_de_fr_arsc.h +++ b/libs/androidfw/tests/data/basic/split_de_fr_arsc.h @@ -1,5 +1,5 @@ unsigned char split_de_fr_arsc[] = { - 0x02, 0x00, 0x0c, 0x00, 0xe4, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x0c, 0x00, 0xf4, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, @@ -10,7 +10,7 @@ unsigned char split_de_fr_arsc[] = { 0x32, 0x00, 0x00, 0x00, 0x07, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x61, 0x00, 0x69, 0x00, 0x20, 0x00, 0x31, 0x00, 0x00, 0x00, 0x07, 0x00, 0x65, 0x00, 0x73, 0x00, 0x73, 0x00, 0x61, 0x00, 0x69, 0x00, 0x20, 0x00, - 0x32, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x5c, 0x03, 0x00, 0x00, + 0x32, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, 0x6c, 0x03, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, @@ -57,30 +57,32 @@ unsigned char split_de_fr_arsc[] = { 0x14, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, - 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x4c, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x44, 0x00, 0x70, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x66, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, - 0x03, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x4c, 0x61, 0x74, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, 0x01, 0x02, 0x4c, 0x00, + 0x78, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x58, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x66, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x4c, 0x61, 0x74, 0x6e, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, + 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; -unsigned int split_de_fr_arsc_len = 996; +unsigned int split_de_fr_arsc_len = 1012; diff --git a/libs/androidfw/tests/data/basic/split_hdpi_v4_arsc.h b/libs/androidfw/tests/data/basic/split_hdpi_v4_arsc.h index e9fb7ea47b75..0cc39154a5ec 100644 --- a/libs/androidfw/tests/data/basic/split_hdpi_v4_arsc.h +++ b/libs/androidfw/tests/data/basic/split_hdpi_v4_arsc.h @@ -1,10 +1,10 @@ unsigned char split_hdpi_v4_arsc[] = { - 0x02, 0x00, 0x0c, 0x00, 0x08, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x0c, 0x00, 0x10, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x68, 0x00, 0x64, 0x00, 0x70, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x02, 0x20, 0x01, - 0xd0, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, + 0xd8, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00, 0x61, 0x00, 0x73, 0x00, @@ -50,19 +50,20 @@ unsigned char split_hdpi_v4_arsc[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x44, 0x00, 0x60, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x4c, 0x00, 0x68, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, - 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, + 0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, + 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 }; -unsigned int split_hdpi_v4_arsc_len = 776; +unsigned int split_hdpi_v4_arsc_len = 784; diff --git a/libs/androidfw/tests/data/basic/split_xhdpi_v4_arsc.h b/libs/androidfw/tests/data/basic/split_xhdpi_v4_arsc.h index 7835f71419f2..d44ba9630aba 100644 --- a/libs/androidfw/tests/data/basic/split_xhdpi_v4_arsc.h +++ b/libs/androidfw/tests/data/basic/split_xhdpi_v4_arsc.h @@ -1,10 +1,10 @@ unsigned char split_xhdpi_v4_arsc[] = { - 0x02, 0x00, 0x0c, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x0c, 0x00, 0x14, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x78, 0x00, 0x68, 0x00, 0x64, 0x00, 0x70, 0x00, 0x69, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x20, 0x01, 0xd0, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x20, 0x01, 0xd8, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00, @@ -50,19 +50,20 @@ unsigned char split_xhdpi_v4_arsc[] = { 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x4c, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -unsigned int split_xhdpi_v4_arsc_len = 780; +unsigned int split_xhdpi_v4_arsc_len = 788; diff --git a/libs/androidfw/tests/data/basic/split_xxhdpi_v4_arsc.h b/libs/androidfw/tests/data/basic/split_xxhdpi_v4_arsc.h index f805db1b009e..2f3f682fb6e4 100644 --- a/libs/androidfw/tests/data/basic/split_xxhdpi_v4_arsc.h +++ b/libs/androidfw/tests/data/basic/split_xxhdpi_v4_arsc.h @@ -1,10 +1,10 @@ unsigned char split_xxhdpi_v4_arsc[] = { - 0x02, 0x00, 0x0c, 0x00, 0x0c, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x0c, 0x00, 0x14, 0x03, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x1c, 0x00, 0x30, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x78, 0x00, 0x78, 0x00, 0x68, 0x00, 0x64, 0x00, 0x70, 0x00, 0x69, 0x00, 0x00, 0x00, - 0x00, 0x02, 0x20, 0x01, 0xd0, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x20, 0x01, 0xd8, 0x02, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x63, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x2e, 0x00, 0x61, 0x00, 0x6e, 0x00, 0x64, 0x00, 0x72, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x64, 0x00, 0x2e, 0x00, 0x74, 0x00, 0x65, 0x00, 0x73, 0x00, 0x74, 0x00, 0x2e, 0x00, 0x62, 0x00, @@ -50,19 +50,20 @@ unsigned char split_xxhdpi_v4_arsc[] = { 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x44, 0x00, 0x60, 0x00, 0x00, 0x00, - 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, - 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x4c, 0x00, 0x68, 0x00, 0x00, 0x00, + 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x58, 0x00, 0x00, 0x00, + 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, - 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x18, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x02, 0x02, 0x10, 0x00, 0x14, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -unsigned int split_xxhdpi_v4_arsc_len = 780; +unsigned int split_xxhdpi_v4_arsc_len = 788; diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk index 9a9a89bba53f..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 \ @@ -253,6 +254,7 @@ LOCAL_SRC_FILES += \ ifeq (true, $(HWUI_NEW_OPS)) LOCAL_SRC_FILES += \ + tests/unit/BakedOpDispatcherTests.cpp \ tests/unit/BakedOpStateTests.cpp \ tests/unit/FrameBuilderTests.cpp \ tests/unit/LeakCheckTests.cpp \ @@ -304,13 +306,13 @@ LOCAL_MODULE_STEM_64 := hwuimicro64 LOCAL_CFLAGS := \ $(hwui_cflags) \ -DHWUI_NULL_GPU -LOCAL_C_INCLUDES += bionic/benchmarks/ LOCAL_WHOLE_STATIC_LIBRARIES := libhwui_static_null_gpu -LOCAL_STATIC_LIBRARIES := libbenchmark libbase +LOCAL_STATIC_LIBRARIES := libgoogle-benchmark LOCAL_SRC_FILES += \ $(hwui_test_common_src_files) \ + tests/microbench/main.cpp \ tests/microbench/DisplayListCanvasBench.cpp \ tests/microbench/LinearAllocatorBench.cpp \ tests/microbench/PathParserBench.cpp \ diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp index 98493d73776e..da5eccaf1c12 100644 --- a/libs/hwui/BakedOpRenderer.cpp +++ b/libs/hwui/BakedOpRenderer.cpp @@ -324,7 +324,7 @@ void BakedOpRenderer::prepareRender(const Rect* dirtyBounds, const ClipBase* cli } } -void BakedOpRenderer::renderGlop(const Rect* dirtyBounds, const ClipBase* clip, +void BakedOpRenderer::renderGlopImpl(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop) { prepareRender(dirtyBounds, clip); mRenderState.render(glop, mRenderTarget.orthoMatrix); diff --git a/libs/hwui/BakedOpRenderer.h b/libs/hwui/BakedOpRenderer.h index 4b652553b6b9..1b4065aa0aa6 100644 --- a/libs/hwui/BakedOpRenderer.h +++ b/libs/hwui/BakedOpRenderer.h @@ -14,8 +14,7 @@ * limitations under the License. */ -#ifndef ANDROID_HWUI_BAKED_OP_RENDERER_H -#define ANDROID_HWUI_BAKED_OP_RENDERER_H +#pragma once #include "BakedOpState.h" #include "Matrix.h" @@ -41,6 +40,7 @@ struct ClipBase; */ class BakedOpRenderer { public: + typedef void (*GlopReceiver)(BakedOpRenderer&, const Rect*, const ClipBase*, const Glop&); /** * Position agnostic shadow lighting info. Used with all shadow ops in scene. */ @@ -54,8 +54,10 @@ public: uint8_t spotShadowAlpha; }; - BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, const LightInfo& lightInfo) - : mRenderState(renderState) + BakedOpRenderer(Caches& caches, RenderState& renderState, bool opaque, + const LightInfo& lightInfo) + : mGlopReceiver(DefaultGlopReceiver) + , mRenderState(renderState) , mCaches(caches) , mOpaque(opaque) , mLightInfo(lightInfo) { @@ -81,7 +83,9 @@ public: } void renderFunctor(const FunctorOp& op, const BakedOpState& state); - void renderGlop(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop); + void renderGlop(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop) { + mGlopReceiver(*this, dirtyBounds, clip, glop); + } bool offscreenRenderTarget() { return mRenderTarget.offscreenBuffer != nullptr; } void dirtyRenderTarget(const Rect& dirtyRect); bool didDraw() const { return mHasDrawn; } @@ -95,7 +99,14 @@ public: drawRects(ltrb, 4, paint); } void drawRects(const float* rects, int count, const SkPaint* paint); +protected: + GlopReceiver mGlopReceiver; private: + static void DefaultGlopReceiver(BakedOpRenderer& renderer, const Rect* dirtyBounds, + const ClipBase* clip, const Glop& glop) { + renderer.renderGlopImpl(dirtyBounds, clip, glop); + } + void renderGlopImpl(const Rect* dirtyBounds, const ClipBase* clip, const Glop& glop); void setViewport(uint32_t width, uint32_t height); void clearColorBuffer(const Rect& clearRect); void prepareRender(const Rect* dirtyBounds, const ClipBase* clip); @@ -136,5 +147,3 @@ private: }; // namespace uirenderer }; // namespace android - -#endif // ANDROID_HWUI_BAKED_OP_RENDERER_H 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/Matrix.cpp b/libs/hwui/Matrix.cpp index deab95690d0e..709156c4098b 100644 --- a/libs/hwui/Matrix.cpp +++ b/libs/hwui/Matrix.cpp @@ -437,8 +437,16 @@ void Matrix4::mapPoint(float& x, float& y) const { y = dy * dz; } +/** + * Set the contents of the rect to be the bounding rect around each of the corners, mapped by the + * matrix. + * + * NOTE: an empty rect to an arbitrary matrix isn't guaranteed to have an empty output, since that's + * important for conservative bounds estimation (e.g. rotate45Matrix.mapRect of Rect(0, 10) should + * result in non-empty. + */ void Matrix4::mapRect(Rect& r) const { - if (isIdentity() || r.isEmpty()) return; + if (isIdentity()) return; if (isSimple()) { MUL_ADD_STORE(r.left, data[kScaleX], data[kTranslateX]); diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp index ddf0528467e0..f0c79d7b2dd7 100644 --- a/libs/hwui/RecordingCanvas.cpp +++ b/libs/hwui/RecordingCanvas.cpp @@ -24,8 +24,8 @@ namespace android { namespace uirenderer { - -static Rect sUnreasonablyLargeBounds(-10000, -10000, 10000, 10000); +#define MIL_PIX 1000000 +static Rect sUnreasonablyLargeBounds(-MIL_PIX, -MIL_PIX, MIL_PIX, MIL_PIX); static const Rect& getConservativeOpBounds(const ClipBase* clip) { // if op is clipped, that rect can be used, but otherwise just use a conservatively large rect @@ -564,15 +564,17 @@ void RecordingCanvas::drawRenderNode(RenderNode* renderNode) { getRecordedClip(), renderNode); int opIndex = addOp(op); - int childIndex = mDisplayList->addChild(op); + if (CC_LIKELY(opIndex >= 0)) { + int childIndex = mDisplayList->addChild(op); - // update the chunk's child indices - DisplayList::Chunk& chunk = mDisplayList->chunks.back(); - chunk.endChildIndex = childIndex + 1; + // update the chunk's child indices + DisplayList::Chunk& chunk = mDisplayList->chunks.back(); + chunk.endChildIndex = childIndex + 1; - if (renderNode->stagingProperties().isProjectionReceiver()) { - // use staging property, since recording on UI thread - mDisplayList->projectionReceiveIndex = opIndex; + if (renderNode->stagingProperties().isProjectionReceiver()) { + // use staging property, since recording on UI thread + mDisplayList->projectionReceiveIndex = opIndex; + } } } @@ -595,7 +597,7 @@ void RecordingCanvas::callDrawGLFunction(Functor* functor) { mDisplayList->functors.push_back(functor); auto clip = getRecordedClip(); addOp(alloc().create_trivial<FunctorOp>( - getConservativeOpBounds(clip), // TODO: explicitly define bounds + getConservativeOpBounds(clip), *(mState.currentSnapshot()->transform), clip, functor)); diff --git a/libs/hwui/Rect.h b/libs/hwui/Rect.h index d9fce9b2c824..de4fa55bb508 100644 --- a/libs/hwui/Rect.h +++ b/libs/hwui/Rect.h @@ -286,7 +286,8 @@ public: friend std::ostream& operator<<(std::ostream& os, const Rect& rect) { if (rect.isEmpty()) { - return os << "empty"; + // Print empty, but continue, since empty rects may still have useful coordinate info + os << "(empty)"; } if (rect.left == 0 && rect.top == 0) { diff --git a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp index b317c1292623..06b68d1dea8f 100644 --- a/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp +++ b/libs/hwui/tests/microbench/DisplayListCanvasBench.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include <benchmark/Benchmark.h> +#include <benchmark/benchmark.h> #include "DisplayList.h" #if HWUI_NEW_OPS @@ -23,7 +23,6 @@ #include "DisplayListCanvas.h" #endif #include "tests/common/TestUtils.h" -#include "tests/microbench/MicroBench.h" using namespace android; using namespace android::uirenderer; @@ -34,74 +33,64 @@ typedef RecordingCanvas TestCanvas; typedef DisplayListCanvas TestCanvas; #endif -BENCHMARK_NO_ARG(BM_DisplayList_alloc); -void BM_DisplayList_alloc::Run(int iters) { - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { +void BM_DisplayList_alloc(benchmark::State& benchState) { + while (benchState.KeepRunning()) { auto displayList = new DisplayList(); - MicroBench::DoNotOptimize(displayList); + benchmark::DoNotOptimize(displayList); delete displayList; } - StopBenchmarkTiming(); } +BENCHMARK(BM_DisplayList_alloc); -BENCHMARK_NO_ARG(BM_DisplayList_alloc_theoretical); -void BM_DisplayList_alloc_theoretical::Run(int iters) { - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { +void BM_DisplayList_alloc_theoretical(benchmark::State& benchState) { + while (benchState.KeepRunning()) { auto displayList = new char[sizeof(DisplayList)]; - MicroBench::DoNotOptimize(displayList); + benchmark::DoNotOptimize(displayList); delete[] displayList; } - StopBenchmarkTiming(); } +BENCHMARK(BM_DisplayList_alloc_theoretical); -BENCHMARK_NO_ARG(BM_DisplayListCanvas_record_empty); -void BM_DisplayListCanvas_record_empty::Run(int iters) { +void BM_DisplayListCanvas_record_empty(benchmark::State& benchState) { TestCanvas canvas(100, 100); delete canvas.finishRecording(); - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { + while (benchState.KeepRunning()) { canvas.resetRecording(100, 100); - MicroBench::DoNotOptimize(&canvas); + benchmark::DoNotOptimize(&canvas); delete canvas.finishRecording(); } - StopBenchmarkTiming(); } +BENCHMARK(BM_DisplayListCanvas_record_empty); -BENCHMARK_NO_ARG(BM_DisplayListCanvas_record_saverestore); -void BM_DisplayListCanvas_record_saverestore::Run(int iters) { +void BM_DisplayListCanvas_record_saverestore(benchmark::State& benchState) { TestCanvas canvas(100, 100); delete canvas.finishRecording(); - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { + while (benchState.KeepRunning()) { canvas.resetRecording(100, 100); canvas.save(SaveFlags::MatrixClip); canvas.save(SaveFlags::MatrixClip); - MicroBench::DoNotOptimize(&canvas); + benchmark::DoNotOptimize(&canvas); canvas.restore(); canvas.restore(); delete canvas.finishRecording(); } - StopBenchmarkTiming(); } +BENCHMARK(BM_DisplayListCanvas_record_saverestore); -BENCHMARK_NO_ARG(BM_DisplayListCanvas_record_translate); -void BM_DisplayListCanvas_record_translate::Run(int iters) { +void BM_DisplayListCanvas_record_translate(benchmark::State& benchState) { TestCanvas canvas(100, 100); delete canvas.finishRecording(); - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { + while (benchState.KeepRunning()) { canvas.resetRecording(100, 100); canvas.scale(10, 10); - MicroBench::DoNotOptimize(&canvas); + benchmark::DoNotOptimize(&canvas); delete canvas.finishRecording(); } - StopBenchmarkTiming(); } +BENCHMARK(BM_DisplayListCanvas_record_translate); /** * Simulate a simple view drawing a background, overlapped by an image. @@ -109,16 +98,14 @@ void BM_DisplayListCanvas_record_translate::Run(int iters) { * Note that the recording commands are intentionally not perfectly efficient, as the * View system frequently produces unneeded save/restores. */ -BENCHMARK_NO_ARG(BM_DisplayListCanvas_record_simpleBitmapView); -void BM_DisplayListCanvas_record_simpleBitmapView::Run(int iters) { +void BM_DisplayListCanvas_record_simpleBitmapView(benchmark::State& benchState) { TestCanvas canvas(100, 100); delete canvas.finishRecording(); SkPaint rectPaint; SkBitmap iconBitmap = TestUtils::createSkBitmap(80, 80); - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { + while (benchState.KeepRunning()) { canvas.resetRecording(100, 100); { canvas.save(SaveFlags::MatrixClip); @@ -131,11 +118,11 @@ void BM_DisplayListCanvas_record_simpleBitmapView::Run(int iters) { canvas.drawBitmap(iconBitmap, 0, 0, nullptr); canvas.restore(); } - MicroBench::DoNotOptimize(&canvas); + benchmark::DoNotOptimize(&canvas); delete canvas.finishRecording(); } - StopBenchmarkTiming(); } +BENCHMARK(BM_DisplayListCanvas_record_simpleBitmapView); class NullClient: public CanvasStateClient { void onViewportInitialized() override {} @@ -143,48 +130,42 @@ class NullClient: public CanvasStateClient { GLuint getTargetFbo() const override { return 0; } }; -BENCHMARK_NO_ARG(BM_CanvasState_saverestore); -void BM_CanvasState_saverestore::Run(int iters) { +void BM_CanvasState_saverestore(benchmark::State& benchState) { NullClient client; CanvasState state(client); state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3()); - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { + while (benchState.KeepRunning()) { state.save(SaveFlags::MatrixClip); state.save(SaveFlags::MatrixClip); - MicroBench::DoNotOptimize(&state); + benchmark::DoNotOptimize(&state); state.restore(); state.restore(); } - StopBenchmarkTiming(); } +BENCHMARK(BM_CanvasState_saverestore); -BENCHMARK_NO_ARG(BM_CanvasState_init); -void BM_CanvasState_init::Run(int iters) { +void BM_CanvasState_init(benchmark::State& benchState) { NullClient client; CanvasState state(client); state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3()); - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { + while (benchState.KeepRunning()) { state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3()); - MicroBench::DoNotOptimize(&state); + benchmark::DoNotOptimize(&state); } - StopBenchmarkTiming(); } +BENCHMARK(BM_CanvasState_init); -BENCHMARK_NO_ARG(BM_CanvasState_translate); -void BM_CanvasState_translate::Run(int iters) { +void BM_CanvasState_translate(benchmark::State& benchState) { NullClient client; CanvasState state(client); state.initializeSaveStack(100, 100, 0, 0, 100, 100, Vector3()); - StartBenchmarkTiming(); - for (int i = 0; i < iters; ++i) { + while (benchState.KeepRunning()) { state.translate(5, 5, 0); - MicroBench::DoNotOptimize(&state); + benchmark::DoNotOptimize(&state); state.translate(-5, -5, 0); } - StopBenchmarkTiming(); } +BENCHMARK(BM_CanvasState_translate); diff --git a/libs/hwui/tests/microbench/FrameBuilderBench.cpp b/libs/hwui/tests/microbench/FrameBuilderBench.cpp index 7845eb4fa8e2..7816f0fbf864 100644 --- a/libs/hwui/tests/microbench/FrameBuilderBench.cpp +++ b/libs/hwui/tests/microbench/FrameBuilderBench.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include <benchmark/Benchmark.h> +#include <benchmark/benchmark.h> #include "BakedOpState.h" #include "BakedOpDispatcher.h" @@ -27,7 +27,6 @@ #include "tests/common/TestScene.h" #include "tests/common/TestUtils.h" #include "Vector.h" -#include "tests/microbench/MicroBench.h" #include <vector> @@ -62,38 +61,34 @@ static std::vector<sp<RenderNode>> createTestNodeList() { return vec; } -BENCHMARK_NO_ARG(BM_FrameBuilder_defer); -void BM_FrameBuilder_defer::Run(int iters) { +void BM_FrameBuilder_defer(benchmark::State& state) { auto nodes = createTestNodeList(); - StartBenchmarkTiming(); - for (int i = 0; i < iters; i++) { + while (state.KeepRunning()) { FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200, nodes, sLightGeometry, nullptr); - MicroBench::DoNotOptimize(&frameBuilder); + benchmark::DoNotOptimize(&frameBuilder); } - StopBenchmarkTiming(); } +BENCHMARK(BM_FrameBuilder_defer); -BENCHMARK_NO_ARG(BM_FrameBuilder_deferAndRender); -void BM_FrameBuilder_deferAndRender::Run(int iters) { - TestUtils::runOnRenderThread([this, iters](RenderThread& thread) { +void BM_FrameBuilder_deferAndRender(benchmark::State& state) { + TestUtils::runOnRenderThread([&state](RenderThread& thread) { auto nodes = createTestNodeList(); RenderState& renderState = thread.renderState(); Caches& caches = Caches::getInstance(); - StartBenchmarkTiming(); - for (int i = 0; i < iters; i++) { + while (state.KeepRunning()) { FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(100, 200), 100, 200, nodes, sLightGeometry, nullptr); BakedOpRenderer renderer(caches, renderState, true, sLightInfo); frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); - MicroBench::DoNotOptimize(&renderer); + benchmark::DoNotOptimize(&renderer); } - StopBenchmarkTiming(); }); } +BENCHMARK(BM_FrameBuilder_deferAndRender); static std::vector<sp<RenderNode>> getSyncedSceneNodes(const char* sceneName) { gDisplay = getBuiltInDisplay(); // switch to real display if present @@ -113,47 +108,41 @@ static std::vector<sp<RenderNode>> getSyncedSceneNodes(const char* sceneName) { return nodes; } -static void benchDeferScene(testing::Benchmark& benchmark, int iters, const char* sceneName) { +static auto SCENES = { + "listview", +}; + +void BM_FrameBuilder_defer_scene(benchmark::State& state) { + const char* sceneName = *(SCENES.begin() + state.range_x()); + state.SetLabel(sceneName); auto nodes = getSyncedSceneNodes(sceneName); - benchmark.StartBenchmarkTiming(); - for (int i = 0; i < iters; i++) { + while (state.KeepRunning()) { FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h, nodes, sLightGeometry, nullptr); - MicroBench::DoNotOptimize(&frameBuilder); + benchmark::DoNotOptimize(&frameBuilder); } - benchmark.StopBenchmarkTiming(); } +BENCHMARK(BM_FrameBuilder_defer_scene)->DenseRange(0, SCENES.size() - 1); -static void benchDeferAndRenderScene(testing::Benchmark& benchmark, - int iters, const char* sceneName) { - TestUtils::runOnRenderThread([&benchmark, iters, sceneName](RenderThread& thread) { +void BM_FrameBuilder_deferAndRender_scene(benchmark::State& state) { + TestUtils::runOnRenderThread([&state](RenderThread& thread) { + const char* sceneName = *(SCENES.begin() + state.range_x()); + state.SetLabel(sceneName); auto nodes = getSyncedSceneNodes(sceneName); RenderState& renderState = thread.renderState(); Caches& caches = Caches::getInstance(); - benchmark.StartBenchmarkTiming(); - for (int i = 0; i < iters; i++) { + while (state.KeepRunning()) { FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(gDisplay.w, gDisplay.h), gDisplay.w, gDisplay.h, nodes, sLightGeometry, nullptr); BakedOpRenderer renderer(caches, renderState, true, sLightInfo); frameBuilder.replayBakedOps<BakedOpDispatcher>(renderer); - MicroBench::DoNotOptimize(&renderer); + benchmark::DoNotOptimize(&renderer); } - benchmark.StopBenchmarkTiming(); }); } - -BENCHMARK_NO_ARG(BM_FrameBuilder_listview_defer); -void BM_FrameBuilder_listview_defer::Run(int iters) { - benchDeferScene(*this, iters, "listview"); -} - -BENCHMARK_NO_ARG(BM_FrameBuilder_listview_deferAndRender); -void BM_FrameBuilder_listview_deferAndRender::Run(int iters) { - benchDeferAndRenderScene(*this, iters, "listview"); -} - +BENCHMARK(BM_FrameBuilder_deferAndRender_scene)->DenseRange(0, SCENES.size() - 1); diff --git a/libs/hwui/tests/microbench/LinearAllocatorBench.cpp b/libs/hwui/tests/microbench/LinearAllocatorBench.cpp index 28513e438fe1..3c0a6c5ae8ac 100644 --- a/libs/hwui/tests/microbench/LinearAllocatorBench.cpp +++ b/libs/hwui/tests/microbench/LinearAllocatorBench.cpp @@ -14,9 +14,8 @@ * limitations under the License. */ -#include <benchmark/Benchmark.h> +#include <benchmark/benchmark.h> -#include "tests/microbench/MicroBench.h" #include "utils/LinearAllocator.h" #include <vector> @@ -24,30 +23,26 @@ using namespace android; using namespace android::uirenderer; -BENCHMARK_NO_ARG(BM_LinearStdAllocator_vectorBaseline); -void BM_LinearStdAllocator_vectorBaseline::Run(int iters) { - StartBenchmarkTiming(); - for (int i = 0; i < iters; i++) { +static void BM_LinearStdAllocator_vectorBaseline(benchmark::State& state) { + while (state.KeepRunning()) { std::vector<char> v; for (int j = 0; j < 200; j++) { v.push_back(j); } - MicroBench::DoNotOptimize(&v); + benchmark::DoNotOptimize(&v); } - StopBenchmarkTiming(); } +BENCHMARK(BM_LinearStdAllocator_vectorBaseline); -BENCHMARK_NO_ARG(BM_LinearStdAllocator_vector); -void BM_LinearStdAllocator_vector::Run(int iters) { - StartBenchmarkTiming(); - for (int i = 0; i < iters; i++) { +static void BM_LinearStdAllocator_vector(benchmark::State& state) { + while (state.KeepRunning()) { LinearAllocator la; LinearStdAllocator<void*> stdAllocator(la); std::vector<char, LinearStdAllocator<char> > v(stdAllocator); for (int j = 0; j < 200; j++) { v.push_back(j); } - MicroBench::DoNotOptimize(&v); + benchmark::DoNotOptimize(&v); } - StopBenchmarkTiming(); } +BENCHMARK(BM_LinearStdAllocator_vector); diff --git a/libs/hwui/tests/microbench/PathParserBench.cpp b/libs/hwui/tests/microbench/PathParserBench.cpp index bd742c6ededf..4186539d74ee 100644 --- a/libs/hwui/tests/microbench/PathParserBench.cpp +++ b/libs/hwui/tests/microbench/PathParserBench.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include <benchmark/Benchmark.h> +#include <benchmark/benchmark.h> #include "PathParser.h" #include "VectorDrawable.h" @@ -26,26 +26,26 @@ using namespace android::uirenderer; static const char* sPathString = "M 1 1 m 2 2, l 3 3 L 3 3 H 4 h4 V5 v5, Q6 6 6 6 q 6 6 6 6t 7 7 T 7 7 C 8 8 8 8 8 8 c 8 8 8 8 8 8 S 9 9 9 9 s 9 9 9 9 A 10 10 0 1 1 10 10 a 10 10 0 1 1 10 10"; -BENCHMARK_NO_ARG(BM_PathParser_parseStringPathForSkPath); -void BM_PathParser_parseStringPathForSkPath::Run(int iter) { +void BM_PathParser_parseStringPathForSkPath(benchmark::State& state) { SkPath skPath; size_t length = strlen(sPathString); PathParser::ParseResult result; - StartBenchmarkTiming(); - for (int i = 0; i < iter; i++) { + while (state.KeepRunning()) { PathParser::parseStringForSkPath(&skPath, &result, sPathString, length); + benchmark::DoNotOptimize(&result); + benchmark::DoNotOptimize(&skPath); } - StopBenchmarkTiming(); } +BENCHMARK(BM_PathParser_parseStringPathForSkPath); -BENCHMARK_NO_ARG(BM_PathParser_parseStringPathForPathData); -void BM_PathParser_parseStringPathForPathData::Run(int iter) { +void BM_PathParser_parseStringPathForPathData(benchmark::State& state) { size_t length = strlen(sPathString); PathData outData; PathParser::ParseResult result; - StartBenchmarkTiming(); - for (int i = 0; i < iter; i++) { + while (state.KeepRunning()) { PathParser::getPathDataFromString(&outData, &result, sPathString, length); + benchmark::DoNotOptimize(&result); + benchmark::DoNotOptimize(&outData); } - StopBenchmarkTiming(); } +BENCHMARK(BM_PathParser_parseStringPathForPathData); diff --git a/libs/hwui/tests/microbench/ShadowBench.cpp b/libs/hwui/tests/microbench/ShadowBench.cpp index 98ec4d9b8f9d..a0fc6e8f9f53 100644 --- a/libs/hwui/tests/microbench/ShadowBench.cpp +++ b/libs/hwui/tests/microbench/ShadowBench.cpp @@ -14,14 +14,13 @@ * limitations under the License. */ -#include <benchmark/Benchmark.h> +#include <benchmark/benchmark.h> #include "Matrix.h" #include "Rect.h" #include "Vector.h" #include "VertexBuffer.h" #include "TessellationCache.h" -#include "tests/microbench/MicroBench.h" #include <SkPath.h> @@ -78,39 +77,35 @@ static inline void tessellateShadows(ShadowTestData& testData, bool opaque, testData.lightRadius, *ambient, *spot); } -BENCHMARK_NO_ARG(BM_TessellateShadows_roundrect_opaque); -void BM_TessellateShadows_roundrect_opaque::Run(int iters) { +void BM_TessellateShadows_roundrect_opaque(benchmark::State& state) { ShadowTestData shadowData; createShadowTestData(&shadowData); SkPath path; path.addRoundRect(SkRect::MakeWH(100, 100), 5, 5); - StartBenchmarkTiming(); - for (int i = 0; i < iters; i++) { + while (state.KeepRunning()) { VertexBuffer ambient; VertexBuffer spot; tessellateShadows(shadowData, true, path, &ambient, &spot); - MicroBench::DoNotOptimize(&ambient); - MicroBench::DoNotOptimize(&spot); + benchmark::DoNotOptimize(&ambient); + benchmark::DoNotOptimize(&spot); } - StopBenchmarkTiming(); } +BENCHMARK(BM_TessellateShadows_roundrect_opaque); -BENCHMARK_NO_ARG(BM_TessellateShadows_roundrect_translucent); -void BM_TessellateShadows_roundrect_translucent::Run(int iters) { +void BM_TessellateShadows_roundrect_translucent(benchmark::State& state) { ShadowTestData shadowData; createShadowTestData(&shadowData); SkPath path; path.reset(); path.addRoundRect(SkRect::MakeLTRB(0, 0, 100, 100), 5, 5); - StartBenchmarkTiming(); - for (int i = 0; i < iters; i++) { + while (state.KeepRunning()) { std::unique_ptr<VertexBuffer> ambient(new VertexBuffer); std::unique_ptr<VertexBuffer> spot(new VertexBuffer); tessellateShadows(shadowData, false, path, ambient.get(), spot.get()); - MicroBench::DoNotOptimize(ambient.get()); - MicroBench::DoNotOptimize(spot.get()); + benchmark::DoNotOptimize(ambient.get()); + benchmark::DoNotOptimize(spot.get()); } - StopBenchmarkTiming(); } +BENCHMARK(BM_TessellateShadows_roundrect_translucent); diff --git a/libs/hwui/tests/microbench/TaskManagerBench.cpp b/libs/hwui/tests/microbench/TaskManagerBench.cpp index 0ea30e4757fb..c6b9f3bca55f 100644 --- a/libs/hwui/tests/microbench/TaskManagerBench.cpp +++ b/libs/hwui/tests/microbench/TaskManagerBench.cpp @@ -14,12 +14,11 @@ * limitations under the License. */ -#include <benchmark/Benchmark.h> +#include <benchmark/benchmark.h> #include "thread/Task.h" #include "thread/TaskManager.h" #include "thread/TaskProcessor.h" -#include "tests/microbench/MicroBench.h" #include <vector> @@ -39,55 +38,51 @@ public: } }; -BENCHMARK_NO_ARG(BM_TaskManager_allocateTask); -void BM_TaskManager_allocateTask::Run(int iters) { +void BM_TaskManager_allocateTask(benchmark::State& state) { std::vector<sp<TrivialTask> > tasks; - tasks.reserve(iters); + tasks.reserve(state.max_iterations); - StartBenchmarkTiming(); - for (int i = 0; i < iters; i++) { + while (state.KeepRunning()) { tasks.emplace_back(new TrivialTask); - MicroBench::DoNotOptimize(tasks.back()); + benchmark::DoNotOptimize(tasks.back()); } - StopBenchmarkTiming(); } +BENCHMARK(BM_TaskManager_allocateTask); -BENCHMARK_NO_ARG(BM_TaskManager_enqueueTask); -void BM_TaskManager_enqueueTask::Run(int iters) { +void BM_TaskManager_enqueueTask(benchmark::State& state) { TaskManager taskManager; sp<TrivialProcessor> processor(new TrivialProcessor(&taskManager)); std::vector<sp<TrivialTask> > tasks; - tasks.reserve(iters); + tasks.reserve(state.max_iterations); - StartBenchmarkTiming(); - for (int i = 0; i < iters; i++) { + while (state.KeepRunning()) { tasks.emplace_back(new TrivialTask); - MicroBench::DoNotOptimize(tasks.back()); + benchmark::DoNotOptimize(tasks.back()); processor->add(tasks.back()); } - StopBenchmarkTiming(); for (sp<TrivialTask>& task : tasks) { task->getResult(); } } +BENCHMARK(BM_TaskManager_enqueueTask); -BENCHMARK_NO_ARG(BM_TaskManager_enqueueRunDeleteTask); -void BM_TaskManager_enqueueRunDeleteTask::Run(int iters) { +void BM_TaskManager_enqueueRunDeleteTask(benchmark::State& state) { TaskManager taskManager; sp<TrivialProcessor> processor(new TrivialProcessor(&taskManager)); std::vector<sp<TrivialTask> > tasks; - tasks.reserve(iters); + tasks.reserve(state.max_iterations); - StartBenchmarkTiming(); - for (int i = 0; i < iters; i++) { + while (state.KeepRunning()) { tasks.emplace_back(new TrivialTask); - MicroBench::DoNotOptimize(tasks.back()); + benchmark::DoNotOptimize(tasks.back()); processor->add(tasks.back()); } + state.ResumeTiming(); for (sp<TrivialTask>& task : tasks) { - MicroBench::DoNotOptimize(task->getResult()); + benchmark::DoNotOptimize(task->getResult()); } tasks.clear(); - StopBenchmarkTiming(); + state.PauseTiming(); } +BENCHMARK(BM_TaskManager_enqueueRunDeleteTask); diff --git a/libs/hwui/tests/microbench/main.cpp b/libs/hwui/tests/microbench/main.cpp new file mode 100644 index 000000000000..a0157bc4f9ef --- /dev/null +++ b/libs/hwui/tests/microbench/main.cpp @@ -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. + */ + +#include <benchmark/benchmark.h> + +BENCHMARK_MAIN(); diff --git a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp new file mode 100644 index 000000000000..654ddc6a28e5 --- /dev/null +++ b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp @@ -0,0 +1,109 @@ +/* + * 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 <RecordedOp.h> +#include <BakedOpDispatcher.h> +#include <BakedOpRenderer.h> +#include <tests/common/TestUtils.h> + +using namespace android::uirenderer; + +static BakedOpRenderer::LightInfo sLightInfo; +static Rect sBaseClip(100, 100); + +class ValidatingBakedOpRenderer : public BakedOpRenderer { +public: + ValidatingBakedOpRenderer(RenderState& renderState, std::function<void(const Glop& glop)> validator) + : BakedOpRenderer(Caches::getInstance(), renderState, true, sLightInfo) + , mValidator(validator) { + mGlopReceiver = ValidatingGlopReceiver; + } +private: + static void ValidatingGlopReceiver(BakedOpRenderer& renderer, const Rect* dirtyBounds, + const ClipBase* clip, const Glop& glop) { + + auto vbor = reinterpret_cast<ValidatingBakedOpRenderer*>(&renderer); + vbor->mValidator(glop); + } + std::function<void(const Glop& glop)> mValidator; +}; + +typedef void (*BakedOpReceiver)(BakedOpRenderer&, const BakedOpState&); + +static void testUnmergedGlopDispatch(renderthread::RenderThread& renderThread, RecordedOp* op, + std::function<void(const Glop& glop)> glopVerifier) { + // Create op, and wrap with basic state. + LinearAllocator allocator; + auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), sBaseClip); + auto state = BakedOpState::tryConstruct(allocator, *snapshot, *op); + ASSERT_NE(nullptr, state); + + int glopCount = 0; + auto glopReceiver = [&glopVerifier, &glopCount] (const Glop& glop) { + ASSERT_EQ(glopCount++, 0) << "Only one Glop expected"; + glopVerifier(glop); + }; + ValidatingBakedOpRenderer renderer(renderThread.renderState(), glopReceiver); + + // Dispatch based on op type created, similar to Frame/LayerBuilder dispatch behavior +#define X(Type) \ + [](BakedOpRenderer& renderer, const BakedOpState& state) { \ + BakedOpDispatcher::on##Type(renderer, static_cast<const Type&>(*(state.op)), state); \ + }, + static BakedOpReceiver unmergedReceivers[] = BUILD_RENDERABLE_OP_LUT(X); +#undef X + unmergedReceivers[op->opId](renderer, *state); + ASSERT_EQ(1, glopCount) << "Exactly one Glop expected"; +} + +RENDERTHREAD_TEST(BakedOpDispatcher, onArc_position) { + SkPaint strokePaint; + strokePaint.setStyle(SkPaint::kStroke_Style); + strokePaint.setStrokeWidth(4); + ArcOp op(Rect(10, 15, 20, 25), Matrix4::identity(), nullptr, &strokePaint, 0, 270, true); + testUnmergedGlopDispatch(renderThread, &op, [] (const Glop& glop) { + // validate glop produced by renderPathTexture (so texture, unit quad) + auto texture = glop.fill.texture.texture; + ASSERT_NE(nullptr, texture); + float expectedOffset = floor(4 * 1.5f + 0.5f); + EXPECT_EQ(expectedOffset, reinterpret_cast<PathTexture*>(texture)->offset) + << "Should see conservative offset from PathCache::computeBounds"; + Rect expectedBounds(10, 15, 20, 25); + expectedBounds.outset(expectedOffset); + EXPECT_EQ(expectedBounds, glop.bounds) << "bounds outset by stroke 'offset'"; + Matrix4 expectedModelView; + expectedModelView.loadTranslate(10 - expectedOffset, 15 - expectedOffset, 0); + expectedModelView.scale(10 + 2 * expectedOffset, 10 + 2 * expectedOffset, 1); + EXPECT_EQ(expectedModelView, glop.transform.modelView) + << "X and Y offsets, and scale both applied to model view"; + }); +} + +RENDERTHREAD_TEST(BakedOpDispatcher, onLayerOp_bufferless) { + SkPaint layerPaint; + layerPaint.setAlpha(128); + OffscreenBuffer* buffer = nullptr; // no providing a buffer, should hit rect fallback case + LayerOp op(Rect(10, 10), Matrix4::identity(), nullptr, &layerPaint, &buffer); + testUnmergedGlopDispatch(renderThread, &op, [&renderThread] (const Glop& glop) { + // rect glop is dispatched with paint props applied + EXPECT_EQ(renderThread.renderState().meshState().getUnitQuadVBO(), + glop.mesh.vertices.bufferObject) << "Unit quad should be drawn"; + EXPECT_EQ(nullptr, glop.fill.texture.texture) << "Should be no texture when layer is null"; + EXPECT_FLOAT_EQ(128 / 255.0f, glop.fill.color.a) << "Rect quad should use op alpha"; + }); +} diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp index 4c56a22b09b7..f147fd4be80e 100644 --- a/libs/hwui/tests/unit/FrameBuilderTests.cpp +++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp @@ -349,6 +349,29 @@ RENDERTHREAD_TEST(FrameBuilder, textureLayer) { EXPECT_EQ(1, renderer.getIndex()); } +TEST(FrameBuilder, functor_reject) { + class FunctorTestRenderer : public TestRendererBase { + public: + void onFunctorOp(const FunctorOp& op, const BakedOpState& state) override { + EXPECT_EQ(0, mIndex++); + } + }; + Functor noopFunctor; + + // 1 million pixel tall view, scrolled down 80% + auto scrolledFunctorView = TestUtils::createNode(0, 0, 400, 1000000, + [&noopFunctor](RenderProperties& props, RecordingCanvas& canvas) { + canvas.translate(0, -800000); + canvas.callDrawGLFunction(&noopFunctor); + }); + + FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200, + TestUtils::createSyncedNodeList(scrolledFunctorView), sLightGeometry, nullptr); + FunctorTestRenderer renderer; + frameBuilder.replayBakedOps<TestDispatcher>(renderer); + EXPECT_EQ(1, renderer.getIndex()) << "Functor should not be rejected"; +} + TEST(FrameBuilder, renderNode) { class RenderNodeTestRenderer : public TestRendererBase { public: @@ -391,6 +414,7 @@ TEST(FrameBuilder, renderNode) { TestUtils::createSyncedNodeList(parent), sLightGeometry, nullptr); RenderNodeTestRenderer renderer; frameBuilder.replayBakedOps<TestDispatcher>(renderer); + EXPECT_EQ(2, renderer.getIndex()); } TEST(FrameBuilder, clipped) { 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/libs/hwui/tests/unit/LinearAllocatorTests.cpp b/libs/hwui/tests/unit/LinearAllocatorTests.cpp index 402a09c55e8f..ffcbf128fc3a 100644 --- a/libs/hwui/tests/unit/LinearAllocatorTests.cpp +++ b/libs/hwui/tests/unit/LinearAllocatorTests.cpp @@ -113,3 +113,21 @@ TEST(LinearStdAllocator, simpleAllocate) { EXPECT_GT(lastLocation + 20, &v[0]); } + +TEST(LsaVector, dtorCheck) { + LinearAllocator allocator; + LinearStdAllocator<void*> stdAllocator(allocator); + + for (int size : {1, 2, 3, 500}) { + int destroyed = 0; + { + LsaVector<std::unique_ptr<TestUtils::SignalingDtor> > vector(stdAllocator); + for (int i = 0; i < size; i++) { + vector.emplace_back(new TestUtils::SignalingDtor(&destroyed)); + } + EXPECT_EQ(0, destroyed); + EXPECT_EQ(size, (int) vector.size()); + } + EXPECT_EQ(size, destroyed); + } +} diff --git a/libs/hwui/tests/unit/MatrixTests.cpp b/libs/hwui/tests/unit/MatrixTests.cpp index da2263788c25..eddab878a49d 100644 --- a/libs/hwui/tests/unit/MatrixTests.cpp +++ b/libs/hwui/tests/unit/MatrixTests.cpp @@ -21,15 +21,30 @@ using namespace android::uirenderer; -TEST(Matrix, mapRect) { +TEST(Matrix, mapRect_emptyScaleSkew) { // Skew, so we don't hit identity/translate/simple fast paths - Matrix4 matrix; - matrix.skew(0.1f, 0.1f); + Matrix4 scaleMatrix; + scaleMatrix.loadScale(10, 10, 1); + scaleMatrix.skew(0.1f, 0.1f); // non-zero empty rect, so sorting x/y would make rect non-empty - Rect empty(100, 100, -100, -100); + Rect empty(15, 20, 15, 100); ASSERT_TRUE(empty.isEmpty()); - matrix.mapRect(empty); - EXPECT_TRUE(empty.isEmpty()) - << "Empty rect should always remain empty, regardless of mapping."; + scaleMatrix.mapRect(empty); + EXPECT_EQ(Rect(170, 215, 250, 1015), empty); + EXPECT_FALSE(empty.isEmpty()) + << "Empty 'line' rect doesn't remain empty when skewed."; +} + +TEST(Matrix, mapRect_emptyRotate) { + // Skew, so we don't hit identity/translate/simple fast paths + Matrix4 skewMatrix; + skewMatrix.loadRotate(45); + + // non-zero empty rect, so sorting x/y would make rect non-empty + Rect lineRect(0, 100); + ASSERT_TRUE(lineRect.isEmpty()); + skewMatrix.mapRect(lineRect); + EXPECT_FALSE(lineRect.isEmpty()) + << "Empty 'line' rect doesn't remain empty when rotated."; } diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp index d35b1f94583d..c3165bbe9c1f 100644 --- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp +++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp @@ -451,6 +451,21 @@ TEST(RecordingCanvas, saveLayer_rotateClipped) { EXPECT_EQ(3, count); } +TEST(RecordingCanvas, drawRenderNode_rejection) { + auto child = TestUtils::createNode(50, 50, 150, 150, + [](RenderProperties& props, RecordingCanvas& canvas) { + SkPaint paint; + paint.setColor(SK_ColorWHITE); + canvas.drawRect(0, 0, 100, 100, paint); + }); + + auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [&child](RecordingCanvas& canvas) { + canvas.clipRect(0, 0, 0, 0, SkRegion::kIntersect_Op); // empty clip, reject node + canvas.drawRenderNode(child.get()); // shouldn't crash when rejecting node... + }); + ASSERT_TRUE(dl->isEmpty()); +} + TEST(RecordingCanvas, drawRenderNode_projection) { sp<RenderNode> background = TestUtils::createNode(50, 50, 150, 150, [](RenderProperties& props, RecordingCanvas& canvas) { diff --git a/location/java/android/location/GnssClock.java b/location/java/android/location/GnssClock.java index 6a7801e37f30..2af479066c7b 100644 --- a/location/java/android/location/GnssClock.java +++ b/location/java/android/location/GnssClock.java @@ -16,6 +16,7 @@ package android.location; +import android.annotation.TestApi; import android.os.Parcel; import android.os.Parcelable; @@ -48,13 +49,19 @@ public final class GnssClock implements Parcelable { private double mDriftUncertaintyNanosPerSecond; private int mHardwareClockDiscontinuityCount; - GnssClock() { + /** + * @hide + */ + @TestApi + public GnssClock() { initialize(); } /** * Sets all contents to the values stored in the provided object. + * @hide */ + @TestApi public void set(GnssClock clock) { mFlags = clock.mFlags; mLeapSecond = clock.mLeapSecond; @@ -70,7 +77,9 @@ public final class GnssClock implements Parcelable { /** * Resets all the contents to its original state. + * @hide */ + @TestApi public void reset() { initialize(); } @@ -95,7 +104,9 @@ public final class GnssClock implements Parcelable { /** * Sets the leap second associated with the clock's time. + * @hide */ + @TestApi public void setLeapSecond(int leapSecond) { setFlag(HAS_LEAP_SECOND); mLeapSecond = leapSecond; @@ -103,7 +114,9 @@ public final class GnssClock implements Parcelable { /** * Resets the leap second associated with the clock's time. + * @hide */ + @TestApi public void resetLeapSecond() { resetFlag(HAS_LEAP_SECOND); mLeapSecond = Integer.MIN_VALUE; @@ -129,7 +142,9 @@ public final class GnssClock implements Parcelable { /** * Sets the GNSS receiver internal clock in nanoseconds. + * @hide */ + @TestApi public void setTimeNanos(long timeNanos) { mTimeNanos = timeNanos; } @@ -153,7 +168,9 @@ public final class GnssClock implements Parcelable { /** * Sets the clock's Time Uncertainty (1-Sigma) in nanoseconds. + * @hide */ + @TestApi public void setTimeUncertaintyNanos(double timeUncertaintyNanos) { setFlag(HAS_TIME_UNCERTAINTY); mTimeUncertaintyNanos = timeUncertaintyNanos; @@ -161,7 +178,9 @@ public final class GnssClock implements Parcelable { /** * Resets the clock's Time Uncertainty (1-Sigma) in nanoseconds. + * @hide */ + @TestApi public void resetTimeUncertaintyNanos() { resetFlag(HAS_TIME_UNCERTAINTY); mTimeUncertaintyNanos = Double.NaN; @@ -193,7 +212,9 @@ public final class GnssClock implements Parcelable { /** * Sets the full bias in nanoseconds. + * @hide */ + @TestApi public void setFullBiasNanos(long value) { setFlag(HAS_FULL_BIAS); mFullBiasNanos = value; @@ -201,7 +222,9 @@ public final class GnssClock implements Parcelable { /** * Resets the full bias in nanoseconds. + * @hide */ + @TestApi public void resetFullBiasNanos() { resetFlag(HAS_FULL_BIAS); mFullBiasNanos = Long.MIN_VALUE; @@ -226,7 +249,9 @@ public final class GnssClock implements Parcelable { /** * Sets the sub-nanosecond bias. + * @hide */ + @TestApi public void setBiasNanos(double biasNanos) { setFlag(HAS_BIAS); mBiasNanos = biasNanos; @@ -234,7 +259,9 @@ public final class GnssClock implements Parcelable { /** * Resets the clock's Bias in nanoseconds. + * @hide */ + @TestApi public void resetBiasNanos() { resetFlag(HAS_BIAS); mBiasNanos = Double.NaN; @@ -258,7 +285,9 @@ public final class GnssClock implements Parcelable { /** * Sets the clock's Bias Uncertainty (1-Sigma) in nanoseconds. + * @hide */ + @TestApi public void setBiasUncertaintyNanos(double biasUncertaintyNanos) { setFlag(HAS_BIAS_UNCERTAINTY); mBiasUncertaintyNanos = biasUncertaintyNanos; @@ -266,7 +295,9 @@ public final class GnssClock implements Parcelable { /** * Resets the clock's Bias Uncertainty (1-Sigma) in nanoseconds. + * @hide */ + @TestApi public void resetBiasUncertaintyNanos() { resetFlag(HAS_BIAS_UNCERTAINTY); mBiasUncertaintyNanos = Double.NaN; @@ -292,7 +323,9 @@ public final class GnssClock implements Parcelable { /** * Sets the clock's Drift in nanoseconds per second. + * @hide */ + @TestApi public void setDriftNanosPerSecond(double driftNanosPerSecond) { setFlag(HAS_DRIFT); mDriftNanosPerSecond = driftNanosPerSecond; @@ -300,7 +333,9 @@ public final class GnssClock implements Parcelable { /** * Resets the clock's Drift in nanoseconds per second. + * @hide */ + @TestApi public void resetDriftNanosPerSecond() { resetFlag(HAS_DRIFT); mDriftNanosPerSecond = Double.NaN; @@ -324,7 +359,9 @@ public final class GnssClock implements Parcelable { /** * Sets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second. + * @hide */ + @TestApi public void setDriftUncertaintyNanosPerSecond(double driftUncertaintyNanosPerSecond) { setFlag(HAS_DRIFT_UNCERTAINTY); mDriftUncertaintyNanosPerSecond = driftUncertaintyNanosPerSecond; @@ -339,14 +376,18 @@ public final class GnssClock implements Parcelable { /** * Sets count of last hardware clock discontinuity. + * @hide */ + @TestApi public void setHardwareClockDiscontinuityCount(int value) { mHardwareClockDiscontinuityCount = value; } /** * Resets the clock's Drift Uncertainty (1-Sigma) in nanoseconds per second. + * @hide */ + @TestApi public void resetDriftUncertaintyNanosPerSecond() { resetFlag(HAS_DRIFT_UNCERTAINTY); mDriftUncertaintyNanosPerSecond = Double.NaN; diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java index 367c52fcf611..11fecfb7d201 100644 --- a/location/java/android/location/GnssMeasurement.java +++ b/location/java/android/location/GnssMeasurement.java @@ -16,6 +16,7 @@ package android.location; +import android.annotation.TestApi; import android.annotation.IntDef; import android.os.Parcel; import android.os.Parcelable; @@ -46,6 +47,7 @@ public final class GnssMeasurement implements Parcelable { private double mCarrierPhaseUncertainty; private int mMultipathIndicator; private double mSnrInDb; + private boolean mPseudorangeRateCorrected; // The following enumerations must be in sync with the values declared in gps.h @@ -55,7 +57,6 @@ public final class GnssMeasurement implements Parcelable { private static final int HAS_CARRIER_CYCLES = (1<<10); private static final int HAS_CARRIER_PHASE = (1<<11); private static final int HAS_CARRIER_PHASE_UNCERTAINTY = (1<<12); - private static final int HAS_UNCORRECTED_PSEUDORANGE_RATE = (1<<18); /** The status of multipath. */ @Retention(RetentionPolicy.SOURCE) @@ -141,13 +142,19 @@ public final class GnssMeasurement implements Parcelable { // End enumerations in sync with gps.h - GnssMeasurement() { + /** + * @hide + */ + @TestApi + public GnssMeasurement() { initialize(); } /** * Sets all contents to the values stored in the provided object. + * @hide */ + @TestApi public void set(GnssMeasurement measurement) { mFlags = measurement.mFlags; mSvid = measurement.mSvid; @@ -174,7 +181,9 @@ public final class GnssMeasurement implements Parcelable { /** * Resets all the contents to its original state. + * @hide */ + @TestApi public void reset() { initialize(); } @@ -189,7 +198,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the Pseud-random number (PRN). + * @hide */ + @TestApi public void setSvid(int value) { mSvid = value; } @@ -204,7 +215,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the constellation type. + * @hide */ + @TestApi public void setConstellationType(@GnssStatus.ConstellationType int value) { mConstellationType = value; } @@ -227,7 +240,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the time offset at which the measurement was taken in nanoseconds. + * @hide */ + @TestApi public void setTimeOffsetNanos(double value) { mTimeOffsetNanos = value; } @@ -244,7 +259,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the sync state. + * @hide */ + @TestApi public void setState(int value) { mState = value; } @@ -353,7 +370,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the received GNSS time in nanoseconds. + * @hide */ + @TestApi public void setReceivedSvTimeNanos(long value) { mReceivedSvTimeNanos = value; } @@ -367,7 +386,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the received GNSS time uncertainty (1-Sigma) in nanoseconds. + * @hide */ + @TestApi public void setReceivedSvTimeUncertaintyNanos(long value) { mReceivedSvTimeUncertaintyNanos = value; } @@ -384,7 +405,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the carrier-to-noise density in dB-Hz. + * @hide */ + @TestApi public void setCn0DbHz(double value) { mCn0DbHz = value; } @@ -409,7 +432,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the pseudorange rate at the timestamp in m/s. + * @hide */ + @TestApi public void setPseudorangeRateMetersPerSecond(double value) { mPseudorangeRateMetersPerSecond = value; } @@ -421,7 +446,16 @@ public final class GnssMeasurement implements Parcelable { * value, {@code false} if it contains an uncorrected value. */ public boolean isPseudorangeRateCorrected() { - return !isFlagSet(HAS_UNCORRECTED_PSEUDORANGE_RATE); + return mPseudorangeRateCorrected; + } + + /** + * Sets whether the pseudorange corrected. + * @hide + */ + @TestApi + public void setPseudorangeRateCorrected(boolean value) { + mPseudorangeRateCorrected = value; } /** @@ -434,7 +468,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the pseudorange's rate uncertainty (1-Sigma) in m/s. + * @hide */ + @TestApi public void setPseudorangeRateUncertaintyMetersPerSecond(double value) { mPseudorangeRateUncertaintyMetersPerSecond = value; } @@ -450,7 +486,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the 'Accumulated Delta Range' state. + * @hide */ + @TestApi public void setAccumulatedDeltaRangeState(int value) { mAccumulatedDeltaRangeState = value; } @@ -500,7 +538,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the accumulated delta range in meters. + * @hide */ + @TestApi public void setAccumulatedDeltaRangeMeters(double value) { mAccumulatedDeltaRangeMeters = value; } @@ -519,7 +559,10 @@ public final class GnssMeasurement implements Parcelable { * Sets the accumulated delta range's uncertainty (1-sigma) in meters. * * The status of the value is represented by {@link #getAccumulatedDeltaRangeState()}. + * + * @hide */ + @TestApi public void setAccumulatedDeltaRangeUncertaintyMeters(double value) { mAccumulatedDeltaRangeUncertaintyMeters = value; } @@ -543,7 +586,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the Carrier frequency (L1 or L2) in Hz. + * @hide */ + @TestApi public void setCarrierFrequencyHz(float carrierFrequencyHz) { setFlag(HAS_CARRIER_FREQUENCY); mCarrierFrequencyHz = carrierFrequencyHz; @@ -551,7 +596,9 @@ public final class GnssMeasurement implements Parcelable { /** * Resets the Carrier frequency (L1 or L2) in Hz. + * @hide */ + @TestApi public void resetCarrierFrequencyHz() { resetFlag(HAS_CARRIER_FREQUENCY); mCarrierFrequencyHz = Float.NaN; @@ -576,7 +623,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the number of full carrier cycles between the satellite and the receiver. + * @hide */ + @TestApi public void setCarrierCycles(long value) { setFlag(HAS_CARRIER_CYCLES); mCarrierCycles = value; @@ -584,7 +633,9 @@ public final class GnssMeasurement implements Parcelable { /** * Resets the number of full carrier cycles between the satellite and the receiver. + * @hide */ + @TestApi public void resetCarrierCycles() { resetFlag(HAS_CARRIER_CYCLES); mCarrierCycles = Long.MIN_VALUE; @@ -613,7 +664,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the RF phase detected by the receiver. + * @hide */ + @TestApi public void setCarrierPhase(double value) { setFlag(HAS_CARRIER_PHASE); mCarrierPhase = value; @@ -621,7 +674,9 @@ public final class GnssMeasurement implements Parcelable { /** * Resets the RF phase detected by the receiver. + * @hide */ + @TestApi public void resetCarrierPhase() { resetFlag(HAS_CARRIER_PHASE); mCarrierPhase = Double.NaN; @@ -646,7 +701,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the Carrier-phase's uncertainty (1-Sigma) in cycles. + * @hide */ + @TestApi public void setCarrierPhaseUncertainty(double value) { setFlag(HAS_CARRIER_PHASE_UNCERTAINTY); mCarrierPhaseUncertainty = value; @@ -654,7 +711,9 @@ public final class GnssMeasurement implements Parcelable { /** * Resets the Carrier-phase's uncertainty (1-Sigma) in cycles. + * @hide */ + @TestApi public void resetCarrierPhaseUncertainty() { resetFlag(HAS_CARRIER_PHASE_UNCERTAINTY); mCarrierPhaseUncertainty = Double.NaN; @@ -670,7 +729,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the 'multi-path' indicator. + * @hide */ + @TestApi public void setMultipathIndicator(@MultipathIndicator int value) { mMultipathIndicator = value; } @@ -710,7 +771,9 @@ public final class GnssMeasurement implements Parcelable { /** * Sets the Signal-to-noise ratio (SNR) in dB. + * @hide */ + @TestApi public void setSnrInDb(double snrInDb) { setFlag(HAS_SNR); mSnrInDb = snrInDb; @@ -718,7 +781,9 @@ public final class GnssMeasurement implements Parcelable { /** * Resets the Signal-to-noise ratio (SNR) in dB. + * @hide */ + @TestApi public void resetSnrInDb() { resetFlag(HAS_SNR); mSnrInDb = Double.NaN; @@ -748,6 +813,7 @@ public final class GnssMeasurement implements Parcelable { gnssMeasurement.mCarrierPhaseUncertainty = parcel.readDouble(); gnssMeasurement.mMultipathIndicator = parcel.readInt(); gnssMeasurement.mSnrInDb = parcel.readDouble(); + gnssMeasurement.mPseudorangeRateCorrected = (parcel.readByte() != 0); return gnssMeasurement; } @@ -779,6 +845,7 @@ public final class GnssMeasurement implements Parcelable { parcel.writeDouble(mCarrierPhaseUncertainty); parcel.writeInt(mMultipathIndicator); parcel.writeDouble(mSnrInDb); + parcel.writeByte((byte) (mPseudorangeRateCorrected ? 1 : 0)); } @Override @@ -876,6 +943,7 @@ public final class GnssMeasurement implements Parcelable { resetCarrierPhaseUncertainty(); setMultipathIndicator(MULTIPATH_INDICATOR_UNKNOWN); resetSnrInDb(); + setPseudorangeRateCorrected(false); } private void setFlag(int flag) { diff --git a/location/java/android/location/GnssNavigationMessage.java b/location/java/android/location/GnssNavigationMessage.java index c0608e005a5c..ac255c8e823f 100644 --- a/location/java/android/location/GnssNavigationMessage.java +++ b/location/java/android/location/GnssNavigationMessage.java @@ -16,6 +16,7 @@ package android.location; +import android.annotation.TestApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.os.Parcel; @@ -86,13 +87,19 @@ public final class GnssNavigationMessage implements Parcelable { private byte[] mData; private int mStatus; - GnssNavigationMessage() { + /** + * @hide + */ + @TestApi + public GnssNavigationMessage() { initialize(); } /** * Sets all contents to the values stored in the provided object. + * @hide */ + @TestApi public void set(GnssNavigationMessage navigationMessage) { mType = navigationMessage.mType; mSvid = navigationMessage.mSvid; @@ -104,7 +111,9 @@ public final class GnssNavigationMessage implements Parcelable { /** * Resets all the contents to its original state. + * @hide */ + @TestApi public void reset() { initialize(); } @@ -119,7 +128,9 @@ public final class GnssNavigationMessage implements Parcelable { /** * Sets the type of the navigation message. + * @hide */ + @TestApi public void setType(@GnssNavigationMessageType int value) { mType = value; } @@ -165,7 +176,9 @@ public final class GnssNavigationMessage implements Parcelable { /** * Sets the Pseud-random number. + * @hide */ + @TestApi public void setSvid(int value) { mSvid = value; } @@ -182,7 +195,9 @@ public final class GnssNavigationMessage implements Parcelable { /** * Sets the Message Identifier. + * @hide */ + @TestApi public void setMessageId(int value) { mMessageId = value; } @@ -199,7 +214,9 @@ public final class GnssNavigationMessage implements Parcelable { /** * Sets the Sub-message identifier. + * @hide */ + @TestApi public void setSubmessageId(int value) { mSubmessageId = value; } @@ -215,7 +232,9 @@ public final class GnssNavigationMessage implements Parcelable { /** * Sets the data associated with the Navigation Message. + * @hide */ + @TestApi public void setData(byte[] value) { if (value == null) { throw new InvalidParameterException("Data must be a non-null array"); @@ -233,7 +252,9 @@ public final class GnssNavigationMessage implements Parcelable { /** * Sets the status of the navigation message. + * @hide */ + @TestApi public void setStatus(int value) { mStatus = value; } diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java index 1a387be21183..ce12e76b6588 100644 --- a/media/java/android/media/ExifInterface.java +++ b/media/java/android/media/ExifInterface.java @@ -16,14 +16,16 @@ package android.media; +import android.annotation.NonNull; +import android.content.res.AssetManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; import android.util.Log; -import android.util.Pair; +import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.DataOutputStream; @@ -44,6 +46,7 @@ import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Map; +import java.util.Set; import java.util.TimeZone; import java.util.regex.Pattern; @@ -62,89 +65,273 @@ public class ExifInterface { private static final boolean DEBUG = false; // The Exif tag names + /** Type is String. */ + public static final String TAG_ARTIST = "Artist"; /** Type is int. */ - public static final String TAG_ORIENTATION = "Orientation"; + public static final String TAG_BITS_PER_SAMPLE = "BitsPerSample"; + /** Type is int. */ + public static final String TAG_COMPRESSION = "Compression"; + /** Type is String. */ + public static final String TAG_COPYRIGHT = "Copyright"; /** Type is String. */ public static final String TAG_DATETIME = "DateTime"; /** Type is String. */ + public static final String TAG_IMAGE_DESCRIPTION = "ImageDescription"; + /** Type is int. */ + public static final String TAG_IMAGE_LENGTH = "ImageLength"; + /** Type is int. */ + public static final String TAG_IMAGE_WIDTH = "ImageWidth"; + /** Type is int. */ + public static final String TAG_JPEG_INTERCHANGE_FORMAT = "JPEGInterchangeFormat"; + /** Type is int. */ + public static final String TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = "JPEGInterchangeFormatLength"; + /** Type is String. */ public static final String TAG_MAKE = "Make"; /** Type is String. */ public static final String TAG_MODEL = "Model"; /** Type is int. */ - public static final String TAG_FLASH = "Flash"; + public static final String TAG_ORIENTATION = "Orientation"; /** Type is int. */ - public static final String TAG_IMAGE_WIDTH = "ImageWidth"; + public static final String TAG_PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation"; /** Type is int. */ - public static final String TAG_IMAGE_LENGTH = "ImageLength"; - /** String. Format is "num1/denom1,num2/denom2,num3/denom3". */ - public static final String TAG_GPS_LATITUDE = "GPSLatitude"; - /** String. Format is "num1/denom1,num2/denom2,num3/denom3". */ - public static final String TAG_GPS_LONGITUDE = "GPSLongitude"; + public static final String TAG_PLANAR_CONFIGURATION = "PlanarConfiguration"; + /** Type is rational. */ + public static final String TAG_PRIMARY_CHROMATICITIES = "PrimaryChromaticities"; + /** Type is rational. */ + public static final String TAG_REFERENCE_BLACK_WHITE = "ReferenceBlackWhite"; + /** Type is int. */ + public static final String TAG_RESOLUTION_UNIT = "ResolutionUnit"; + /** Type is int. */ + public static final String TAG_ROWS_PER_STRIP = "RowsPerStrip"; + /** Type is int. */ + public static final String TAG_SAMPLES_PER_PIXEL = "SamplesPerPixel"; /** Type is String. */ - public static final String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef"; + public static final String TAG_SOFTWARE = "Software"; + /** Type is int. */ + public static final String TAG_STRIP_BYTE_COUNTS = "StripByteCounts"; + /** Type is int. */ + public static final String TAG_STRIP_OFFSETS = "StripOffsets"; + /** Type is int. */ + public static final String TAG_TRANSFER_FUNCTION = "TransferFunction"; + /** Type is rational. */ + public static final String TAG_WHITE_POINT = "WhitePoint"; + /** Type is rational. */ + public static final String TAG_X_RESOLUTION = "XResolution"; + /** Type is rational. */ + public static final String TAG_Y_CB_CR_COEFFICIENTS = "YCbCrCoefficients"; + /** Type is int. */ + public static final String TAG_Y_CB_CR_POSITIONING = "YCbCrPositioning"; + /** Type is int. */ + public static final String TAG_Y_CB_CR_SUB_SAMPLING = "YCbCrSubSampling"; + /** Type is rational. */ + public static final String TAG_Y_RESOLUTION = "YResolution"; + /** Type is rational. */ + public static final String TAG_APERTURE_VALUE = "ApertureValue"; + /** Type is rational. */ + public static final String TAG_BRIGHTNESS_VALUE = "BrightnessValue"; /** Type is String. */ - public static final String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef"; + public static final String TAG_CFA_PATTERN = "CFAPattern"; + /** Type is int. */ + public static final String TAG_COLOR_SPACE = "ColorSpace"; + /** Type is String. */ + public static final String TAG_COMPONENTS_CONFIGURATION = "ComponentsConfiguration"; + /** Type is rational. */ + public static final String TAG_COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel"; + /** Type is int. */ + public static final String TAG_CONTRAST = "Contrast"; + /** Type is int. */ + public static final String TAG_CUSTOM_RENDERED = "CustomRendered"; + /** Type is String. */ + public static final String TAG_DATETIME_DIGITIZED = "DateTimeDigitized"; + /** Type is String. */ + public static final String TAG_DATETIME_ORIGINAL = "DateTimeOriginal"; /** Type is String. */ + public static final String TAG_DEVICE_SETTING_DESCRIPTION = "DeviceSettingDescription"; + /** Type is double. */ + public static final String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio"; + /** Type is String. */ + public static final String TAG_EXIF_VERSION = "ExifVersion"; + /** Type is double. */ + public static final String TAG_EXPOSURE_BIAS_VALUE = "ExposureBiasValue"; + /** Type is rational. */ + public static final String TAG_EXPOSURE_INDEX = "ExposureIndex"; + /** Type is int. */ + public static final String TAG_EXPOSURE_MODE = "ExposureMode"; + /** Type is int. */ + public static final String TAG_EXPOSURE_PROGRAM = "ExposureProgram"; + /** Type is double. */ public static final String TAG_EXPOSURE_TIME = "ExposureTime"; /** Type is String. */ + public static final String TAG_F_NUMBER = "FNumber"; + /** Type is String. */ public static final String TAG_APERTURE = "FNumber"; /** Type is String. */ + public static final String TAG_FILE_SOURCE = "FileSource"; + /** Type is int. */ + public static final String TAG_FLASH = "Flash"; + /** Type is rational. */ + public static final String TAG_FLASH_ENERGY = "FlashEnergy"; + /** Type is String. */ + public static final String TAG_FLASHPIX_VERSION = "FlashpixVersion"; + /** Type is rational. */ + public static final String TAG_FOCAL_LENGTH = "FocalLength"; + /** Type is int. */ + public static final String TAG_FOCAL_LENGTH_IN_35MM_FILM = "FocalLengthIn35mmFilm"; + /** Type is int. */ + public static final String TAG_FOCAL_PLANE_RESOLUTION_UNIT = "FocalPlaneResolutionUnit"; + /** Type is rational. */ + public static final String TAG_FOCAL_PLANE_X_RESOLUTION = "FocalPlaneXResolution"; + /** Type is rational. */ + public static final String TAG_FOCAL_PLANE_Y_RESOLUTION = "FocalPlaneYResolution"; + /** Type is rational. */ + public static final String TAG_GAIN_CONTROL = "GainControl"; + /** Type is String. */ + public static final String TAG_ISO_SPEED_RATINGS = "ISOSpeedRatings"; + /** Type is String. */ public static final String TAG_ISO = "ISOSpeedRatings"; /** Type is String. */ - public static final String TAG_DATETIME_DIGITIZED = "DateTimeDigitized"; + public static final String TAG_IMAGE_UNIQUE_ID = "ImageUniqueID"; + /** Type is int. */ + public static final String TAG_LIGHT_SOURCE = "LightSource"; + /** Type is String. */ + public static final String TAG_MAKER_NOTE = "MakerNote"; + /** Type is rational. */ + public static final String TAG_MAX_APERTURE_VALUE = "MaxApertureValue"; + /** Type is int. */ + public static final String TAG_METERING_MODE = "MeteringMode"; + /** Type is String. */ + public static final String TAG_OECF = "OECF"; + /** Type is int. */ + public static final String TAG_PIXEL_X_DIMENSION = "PixelXDimension"; + /** Type is int. */ + public static final String TAG_PIXEL_Y_DIMENSION = "PixelYDimension"; + /** Type is String. */ + public static final String TAG_RELATED_SOUND_FILE = "RelatedSoundFile"; + /** Type is int. */ + public static final String TAG_SATURATION = "Saturation"; + /** Type is int. */ + public static final String TAG_SCENE_CAPTURE_TYPE = "SceneCaptureType"; + /** Type is String. */ + public static final String TAG_SCENE_TYPE = "SceneType"; + /** Type is int. */ + public static final String TAG_SENSING_METHOD = "SensingMethod"; + /** Type is int. */ + public static final String TAG_SHARPNESS = "Sharpness"; + /** Type is rational. */ + public static final String TAG_SHUTTER_SPEED_VALUE = "ShutterSpeedValue"; + /** Type is String. */ + public static final String TAG_SPATIAL_FREQUENCY_RESPONSE = "SpatialFrequencyResponse"; + /** Type is String. */ + public static final String TAG_SPECTRAL_SENSITIVITY = "SpectralSensitivity"; /** Type is int. */ public static final String TAG_SUBSEC_TIME = "SubSecTime"; + /** Type is int. @hide */ + public static final String TAG_SUBSECTIME = "SubSecTime"; /** Type is int. */ - public static final String TAG_SUBSEC_TIME_ORIG = "SubSecTimeOriginal"; + public static final String TAG_SUBSEC_TIME_DIGITIZED = "SubSecTimeDigitized"; /** Type is int. */ public static final String TAG_SUBSEC_TIME_DIG = "SubSecTimeDigitized"; - - /** - * @hide - */ - public static final String TAG_SUBSECTIME = "SubSecTime"; - + /** Type is int. */ + public static final String TAG_SUBSEC_TIME_ORIG = "SubSecTimeOriginal"; + /** Type is int. */ + public static final String TAG_SUBSEC_TIME_ORIGINAL = "SubSecTimeOriginal"; + /** Type is int. */ + public static final String TAG_SUBJECT_AREA = "SubjectArea"; + /** Type is double. */ + public static final String TAG_SUBJECT_DISTANCE = "SubjectDistance"; + /** Type is int. */ + public static final String TAG_SUBJECT_DISTANCE_RANGE = "SubjectDistanceRange"; + /** Type is int. */ + public static final String TAG_SUBJECT_LOCATION = "SubjectLocation"; + /** Type is String. */ + public static final String TAG_USER_COMMENT = "UserComment"; + /** Type is int. */ + public static final String TAG_WHITE_BALANCE = "WhiteBalance"; /** * The altitude (in meters) based on the reference in TAG_GPS_ALTITUDE_REF. * Type is rational. */ public static final String TAG_GPS_ALTITUDE = "GPSAltitude"; - /** * 0 if the altitude is above sea level. 1 if the altitude is below sea * level. Type is int. */ public static final String TAG_GPS_ALTITUDE_REF = "GPSAltitudeRef"; - /** Type is String. */ - public static final String TAG_GPS_TIMESTAMP = "GPSTimeStamp"; + public static final String TAG_GPS_AREA_INFORMATION = "GPSAreaInformation"; + /** Type is rational. */ + public static final String TAG_GPS_DOP = "GPSDOP"; /** Type is String. */ public static final String TAG_GPS_DATESTAMP = "GPSDateStamp"; + /** Type is rational. */ + public static final String TAG_GPS_DEST_BEARING = "GPSDestBearing"; + /** Type is String. */ + public static final String TAG_GPS_DEST_BEARING_REF = "GPSDestBearingRef"; + /** Type is rational. */ + public static final String TAG_GPS_DEST_DISTANCE = "GPSDestDistance"; + /** Type is String. */ + public static final String TAG_GPS_DEST_DISTANCE_REF = "GPSDestDistanceRef"; + /** Type is rational. */ + public static final String TAG_GPS_DEST_LATITUDE = "GPSDestLatitude"; + /** Type is String. */ + public static final String TAG_GPS_DEST_LATITUDE_REF = "GPSDestLatitudeRef"; + /** Type is rational. */ + public static final String TAG_GPS_DEST_LONGITUDE = "GPSDestLongitude"; + /** Type is String. */ + public static final String TAG_GPS_DEST_LONGITUDE_REF = "GPSDestLongitudeRef"; /** Type is int. */ - public static final String TAG_WHITE_BALANCE = "WhiteBalance"; + public static final String TAG_GPS_DIFFERENTIAL = "GPSDifferential"; /** Type is rational. */ - public static final String TAG_FOCAL_LENGTH = "FocalLength"; + public static final String TAG_GPS_IMG_DIRECTION = "GPSImgDirection"; + /** Type is String. */ + public static final String TAG_GPS_IMG_DIRECTION_REF = "GPSImgDirectionRef"; + /** String. Format is "num1/denom1,num2/denom2,num3/denom3". */ + public static final String TAG_GPS_LATITUDE = "GPSLatitude"; + /** Type is String. */ + public static final String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef"; + /** String. Format is "num1/denom1,num2/denom2,num3/denom3". */ + public static final String TAG_GPS_LONGITUDE = "GPSLongitude"; + /** Type is String. */ + public static final String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef"; + /** Type is String. */ + public static final String TAG_GPS_MAP_DATUM = "GPSMapDatum"; + /** Type is String. */ + public static final String TAG_GPS_MEASURE_MODE = "GPSMeasureMode"; /** Type is String. Name of GPS processing method used for location finding. */ public static final String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod"; - /** Type is double. */ - public static final String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio"; - /** Type is double. */ - public static final String TAG_SUBJECT_DISTANCE = "SubjectDistance"; - /** Type is double. */ - public static final String TAG_EXPOSURE_BIAS_VALUE = "ExposureBiasValue"; - /** Type is int. */ - public static final String TAG_LIGHT_SOURCE = "LightSource"; - /** Type is int. */ - public static final String TAG_METERING_MODE = "MeteringMode"; + /** Type is String. */ + public static final String TAG_GPS_SATELLITES = "GPSSatellites"; + /** Type is rational. */ + public static final String TAG_GPS_SPEED = "GPSSpeed"; + /** Type is String. */ + public static final String TAG_GPS_SPEED_REF = "GPSSpeedRef"; + /** Type is String. */ + public static final String TAG_GPS_STATUS = "GPSStatus"; + /** Type is String. */ + public static final String TAG_GPS_TIMESTAMP = "GPSTimeStamp"; + /** Type is rational. */ + public static final String TAG_GPS_TRACK = "GPSTrack"; + /** Type is String. */ + public static final String TAG_GPS_TRACK_REF = "GPSTrackRef"; + /** Type is String. */ + public static final String TAG_GPS_VERSION_ID = "GPSVersionID"; + /** Type is String. */ + public static final String TAG_INTEROPERABILITY_INDEX = "InteroperabilityIndex"; /** Type is int. */ - public static final String TAG_EXPOSURE_PROGRAM = "ExposureProgram"; + public static final String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength"; /** Type is int. */ - public static final String TAG_EXPOSURE_MODE = "ExposureMode"; + public static final String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth"; + + // Private tags used for pointing the other IFD offset. The types of the following tags are int. + private static final String TAG_EXIF_IFD_POINTER = "ExifIFDPointer"; + private static final String TAG_GPS_INFO_IFD_POINTER = "GPSInfoIFDPointer"; + private static final String TAG_INTEROPERABILITY_IFD_POINTER = "InteroperabilityIFDPointer"; // Private tags used for thumbnail information. private static final String TAG_HAS_THUMBNAIL = "hasThumbnail"; private static final String TAG_THUMBNAIL_OFFSET = "thumbnailOffset"; private static final String TAG_THUMBNAIL_LENGTH = "thumbnailLength"; + private static final String TAG_THUMBNAIL_DATA = "thumbnailData"; // Constants used for the Orientation Exif tag. public static final int ORIENTATION_UNDEFINED = 0; @@ -163,6 +350,9 @@ public class ExifInterface { public static final int WHITEBALANCE_AUTO = 0; public static final int WHITEBALANCE_MANUAL = 1; + private static final byte[] JPEG_SIGNATURE = new byte[] {(byte) 0xff, (byte) 0xd8, (byte) 0xff}; + private static final int JPEG_SIGNATURE_SIZE = 3; + private static SimpleDateFormat sFormatter; // See Exchangeable image file format for digital still cameras: Exif version 2.2. @@ -208,171 +398,171 @@ public class ExifInterface { // Primary image IFD TIFF tags (See JEITA CP-3451 Table 14. page 54). private static final ExifTag[] IFD_TIFF_TAGS = new ExifTag[] { - new ExifTag("ImageWidth", 256), - new ExifTag("ImageLength", 257), - new ExifTag("BitsPerSample", 258), - new ExifTag("Compression", 259), - new ExifTag("PhotometricInterpretation", 262), - new ExifTag("ImageDescription", 270), - new ExifTag("Make", 271), - new ExifTag("Model", 272), - new ExifTag("StripOffsets", 273), - new ExifTag("Orientation", 274), - new ExifTag("SamplesPerPixel", 277), - new ExifTag("RowsPerStrip", 278), - new ExifTag("StripByteCounts", 279), - new ExifTag("XResolution", 282), - new ExifTag("YResolution", 283), - new ExifTag("PlanarConfiguration", 284), - new ExifTag("ResolutionUnit", 296), - new ExifTag("TransferFunction", 301), - new ExifTag("Software", 305), - new ExifTag("DateTime", 306), - new ExifTag("Artist", 315), - new ExifTag("WhitePoint", 318), - new ExifTag("PrimaryChromaticities", 319), - new ExifTag("JPEGInterchangeFormat", 513), - new ExifTag("JPEGInterchangeFormatLength", 514), - new ExifTag("YCbCrCoefficients", 529), - new ExifTag("YCbCrSubSampling", 530), - new ExifTag("YCbCrPositioning", 531), - new ExifTag("ReferenceBlackWhite", 532), - new ExifTag("Copyright", 33432), - new ExifTag("ExifIFDPointer", 34665), - new ExifTag("GPSInfoIFDPointer", 34853), + new ExifTag(TAG_IMAGE_WIDTH, 256), + new ExifTag(TAG_IMAGE_LENGTH, 257), + new ExifTag(TAG_BITS_PER_SAMPLE, 258), + new ExifTag(TAG_COMPRESSION, 259), + new ExifTag(TAG_PHOTOMETRIC_INTERPRETATION, 262), + new ExifTag(TAG_IMAGE_DESCRIPTION, 270), + new ExifTag(TAG_MAKE, 271), + new ExifTag(TAG_MODEL, 272), + new ExifTag(TAG_STRIP_OFFSETS, 273), + new ExifTag(TAG_ORIENTATION, 274), + new ExifTag(TAG_SAMPLES_PER_PIXEL, 277), + new ExifTag(TAG_ROWS_PER_STRIP, 278), + new ExifTag(TAG_STRIP_BYTE_COUNTS, 279), + new ExifTag(TAG_X_RESOLUTION, 282), + new ExifTag(TAG_Y_RESOLUTION, 283), + new ExifTag(TAG_PLANAR_CONFIGURATION, 284), + new ExifTag(TAG_RESOLUTION_UNIT, 296), + new ExifTag(TAG_TRANSFER_FUNCTION, 301), + new ExifTag(TAG_SOFTWARE, 305), + new ExifTag(TAG_DATETIME, 306), + new ExifTag(TAG_ARTIST, 315), + new ExifTag(TAG_WHITE_POINT, 318), + new ExifTag(TAG_PRIMARY_CHROMATICITIES, 319), + new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT, 513), + new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, 514), + new ExifTag(TAG_Y_CB_CR_COEFFICIENTS, 529), + new ExifTag(TAG_Y_CB_CR_SUB_SAMPLING, 530), + new ExifTag(TAG_Y_CB_CR_POSITIONING, 531), + new ExifTag(TAG_REFERENCE_BLACK_WHITE, 532), + new ExifTag(TAG_COPYRIGHT, 33432), + new ExifTag(TAG_EXIF_IFD_POINTER, 34665), + new ExifTag(TAG_GPS_INFO_IFD_POINTER, 34853), }; // Primary image IFD Exif Private tags (See JEITA CP-3451 Table 15. page 55). private static final ExifTag[] IFD_EXIF_TAGS = new ExifTag[] { - new ExifTag("ExposureTime", 33434), - new ExifTag("FNumber", 33437), - new ExifTag("ExposureProgram", 34850), - new ExifTag("SpectralSensitivity", 34852), - new ExifTag("ISOSpeedRatings", 34855), - new ExifTag("OECF", 34856), - new ExifTag("ExifVersion", 36864), - new ExifTag("DateTimeOriginal", 36867), - new ExifTag("DateTimeDigitized", 36868), - new ExifTag("ComponentsConfiguration", 37121), - new ExifTag("CompressedBitsPerPixel", 37122), - new ExifTag("ShutterSpeedValue", 37377), - new ExifTag("ApertureValue", 37378), - new ExifTag("BrightnessValue", 37379), - new ExifTag("ExposureBiasValue", 37380), - new ExifTag("MaxApertureValue", 37381), - new ExifTag("SubjectDistance", 37382), - new ExifTag("MeteringMode", 37383), - new ExifTag("LightSource", 37384), - new ExifTag("Flash", 37385), - new ExifTag("FocalLength", 37386), - new ExifTag("SubjectArea", 37396), - new ExifTag("MakerNote", 37500), - new ExifTag("UserComment", 37510), - new ExifTag("SubSecTime", 37520), - new ExifTag("SubSecTimeOriginal", 37521), - new ExifTag("SubSecTimeDigitized", 37522), - new ExifTag("FlashpixVersion", 40960), - new ExifTag("ColorSpace", 40961), - new ExifTag("PixelXDimension", 40962), - new ExifTag("PixelYDimension", 40963), - new ExifTag("RelatedSoundFile", 40964), - new ExifTag("InteroperabilityIFDPointer", 40965), - new ExifTag("FlashEnergy", 41483), - new ExifTag("SpatialFrequencyResponse", 41484), - new ExifTag("FocalPlaneXResolution", 41486), - new ExifTag("FocalPlaneYResolution", 41487), - new ExifTag("FocalPlaneResolutionUnit", 41488), - new ExifTag("SubjectLocation", 41492), - new ExifTag("ExposureIndex", 41493), - new ExifTag("SensingMethod", 41495), - new ExifTag("FileSource", 41728), - new ExifTag("SceneType", 41729), - new ExifTag("CFAPattern", 41730), - new ExifTag("CustomRendered", 41985), - new ExifTag("ExposureMode", 41986), - new ExifTag("WhiteBalance", 41987), - new ExifTag("DigitalZoomRatio", 41988), - new ExifTag("FocalLengthIn35mmFilm", 41989), - new ExifTag("SceneCaptureType", 41990), - new ExifTag("GainControl", 41991), - new ExifTag("Contrast", 41992), - new ExifTag("Saturation", 41993), - new ExifTag("Sharpness", 41994), - new ExifTag("DeviceSettingDescription", 41995), - new ExifTag("SubjectDistanceRange", 41996), - new ExifTag("ImageUniqueID", 42016), + new ExifTag(TAG_EXPOSURE_TIME, 33434), + new ExifTag(TAG_F_NUMBER, 33437), + new ExifTag(TAG_EXPOSURE_PROGRAM, 34850), + new ExifTag(TAG_SPECTRAL_SENSITIVITY, 34852), + new ExifTag(TAG_ISO, 34855), + new ExifTag(TAG_OECF, 34856), + new ExifTag(TAG_EXIF_VERSION, 36864), + new ExifTag(TAG_DATETIME_ORIGINAL, 36867), + new ExifTag(TAG_DATETIME_DIGITIZED, 36868), + new ExifTag(TAG_COMPONENTS_CONFIGURATION, 37121), + new ExifTag(TAG_COMPRESSED_BITS_PER_PIXEL, 37122), + new ExifTag(TAG_SHUTTER_SPEED_VALUE, 37377), + new ExifTag(TAG_APERTURE_VALUE, 37378), + new ExifTag(TAG_BRIGHTNESS_VALUE, 37379), + new ExifTag(TAG_EXPOSURE_BIAS_VALUE, 37380), + new ExifTag(TAG_MAX_APERTURE_VALUE, 37381), + new ExifTag(TAG_SUBJECT_DISTANCE, 37382), + new ExifTag(TAG_METERING_MODE, 37383), + new ExifTag(TAG_LIGHT_SOURCE, 37384), + new ExifTag(TAG_FLASH, 37385), + new ExifTag(TAG_FOCAL_LENGTH, 37386), + new ExifTag(TAG_SUBJECT_AREA, 37396), + new ExifTag(TAG_MAKER_NOTE, 37500), + new ExifTag(TAG_USER_COMMENT, 37510), + new ExifTag(TAG_SUBSEC_TIME, 37520), + new ExifTag(TAG_SUBSEC_TIME_ORIG, 37521), + new ExifTag(TAG_SUBSEC_TIME_DIG, 37522), + new ExifTag(TAG_FLASHPIX_VERSION, 40960), + new ExifTag(TAG_COLOR_SPACE, 40961), + new ExifTag(TAG_PIXEL_X_DIMENSION, 40962), + new ExifTag(TAG_PIXEL_Y_DIMENSION, 40963), + new ExifTag(TAG_RELATED_SOUND_FILE, 40964), + new ExifTag(TAG_INTEROPERABILITY_IFD_POINTER, 40965), + new ExifTag(TAG_FLASH_ENERGY, 41483), + new ExifTag(TAG_SPATIAL_FREQUENCY_RESPONSE, 41484), + new ExifTag(TAG_FOCAL_PLANE_X_RESOLUTION, 41486), + new ExifTag(TAG_FOCAL_PLANE_Y_RESOLUTION, 41487), + new ExifTag(TAG_FOCAL_PLANE_RESOLUTION_UNIT, 41488), + new ExifTag(TAG_SUBJECT_LOCATION, 41492), + new ExifTag(TAG_EXPOSURE_INDEX, 41493), + new ExifTag(TAG_SENSING_METHOD, 41495), + new ExifTag(TAG_FILE_SOURCE, 41728), + new ExifTag(TAG_SCENE_TYPE, 41729), + new ExifTag(TAG_CFA_PATTERN, 41730), + new ExifTag(TAG_CUSTOM_RENDERED, 41985), + new ExifTag(TAG_EXPOSURE_MODE, 41986), + new ExifTag(TAG_WHITE_BALANCE, 41987), + new ExifTag(TAG_DIGITAL_ZOOM_RATIO, 41988), + new ExifTag(TAG_FOCAL_LENGTH_IN_35MM_FILM, 41989), + new ExifTag(TAG_SCENE_CAPTURE_TYPE, 41990), + new ExifTag(TAG_GAIN_CONTROL, 41991), + new ExifTag(TAG_CONTRAST, 41992), + new ExifTag(TAG_SATURATION, 41993), + new ExifTag(TAG_SHARPNESS, 41994), + new ExifTag(TAG_DEVICE_SETTING_DESCRIPTION, 41995), + new ExifTag(TAG_SUBJECT_DISTANCE_RANGE, 41996), + new ExifTag(TAG_IMAGE_UNIQUE_ID, 42016), }; // Primary image IFD GPS Info tags (See JEITA CP-3451 Table 16. page 56). private static final ExifTag[] IFD_GPS_TAGS = new ExifTag[] { - new ExifTag("GPSVersionID", 0), - new ExifTag("GPSLatitudeRef", 1), - new ExifTag("GPSLatitude", 2), - new ExifTag("GPSLongitudeRef", 3), - new ExifTag("GPSLongitude", 4), - new ExifTag("GPSAltitudeRef", 5), - new ExifTag("GPSAltitude", 6), - new ExifTag("GPSTimeStamp", 7), - new ExifTag("GPSSatellites", 8), - new ExifTag("GPSStatus", 9), - new ExifTag("GPSMeasureMode", 10), - new ExifTag("GPSDOP", 11), - new ExifTag("GPSSpeedRef", 12), - new ExifTag("GPSSpeed", 13), - new ExifTag("GPSTrackRef", 14), - new ExifTag("GPSTrack", 15), - new ExifTag("GPSImgDirectionRef", 16), - new ExifTag("GPSImgDirection", 17), - new ExifTag("GPSMapDatum", 18), - new ExifTag("GPSDestLatitudeRef", 19), - new ExifTag("GPSDestLatitude", 20), - new ExifTag("GPSDestLongitudeRef", 21), - new ExifTag("GPSDestLongitude", 22), - new ExifTag("GPSDestBearingRef", 23), - new ExifTag("GPSDestBearing", 24), - new ExifTag("GPSDestDistanceRef", 25), - new ExifTag("GPSDestDistance", 26), - new ExifTag("GPSProcessingMethod", 27), - new ExifTag("GPSAreaInformation", 28), - new ExifTag("GPSDateStamp", 29), - new ExifTag("GPSDifferential", 30), + new ExifTag(TAG_GPS_VERSION_ID, 0), + new ExifTag(TAG_GPS_LATITUDE_REF, 1), + new ExifTag(TAG_GPS_LATITUDE, 2), + new ExifTag(TAG_GPS_LONGITUDE_REF, 3), + new ExifTag(TAG_GPS_LONGITUDE, 4), + new ExifTag(TAG_GPS_ALTITUDE_REF, 5), + new ExifTag(TAG_GPS_ALTITUDE, 6), + new ExifTag(TAG_GPS_TIMESTAMP, 7), + new ExifTag(TAG_GPS_SATELLITES, 8), + new ExifTag(TAG_GPS_STATUS, 9), + new ExifTag(TAG_GPS_MEASURE_MODE, 10), + new ExifTag(TAG_GPS_DOP, 11), + new ExifTag(TAG_GPS_SPEED_REF, 12), + new ExifTag(TAG_GPS_SPEED, 13), + new ExifTag(TAG_GPS_TRACK_REF, 14), + new ExifTag(TAG_GPS_TRACK, 15), + new ExifTag(TAG_GPS_IMG_DIRECTION_REF, 16), + new ExifTag(TAG_GPS_IMG_DIRECTION, 17), + new ExifTag(TAG_GPS_MAP_DATUM, 18), + new ExifTag(TAG_GPS_DEST_LATITUDE_REF, 19), + new ExifTag(TAG_GPS_DEST_LATITUDE, 20), + new ExifTag(TAG_GPS_DEST_LONGITUDE_REF, 21), + new ExifTag(TAG_GPS_DEST_LONGITUDE, 22), + new ExifTag(TAG_GPS_DEST_BEARING_REF, 23), + new ExifTag(TAG_GPS_DEST_BEARING, 24), + new ExifTag(TAG_GPS_DEST_DISTANCE_REF, 25), + new ExifTag(TAG_GPS_DEST_DISTANCE, 26), + new ExifTag(TAG_GPS_PROCESSING_METHOD, 27), + new ExifTag(TAG_GPS_AREA_INFORMATION, 28), + new ExifTag(TAG_GPS_DATESTAMP, 29), + new ExifTag(TAG_GPS_DIFFERENTIAL, 30), }; // Primary image IFD Interoperability tag (See JEITA CP-3451 Table 17. page 56). private static final ExifTag[] IFD_INTEROPERABILITY_TAGS = new ExifTag[] { - new ExifTag("InteroperabilityIndex", 1), + new ExifTag(TAG_INTEROPERABILITY_INDEX, 1), }; // IFD Thumbnail tags (See JEITA CP-3451 Table 18. page 57). private static final ExifTag[] IFD_THUMBNAIL_TAGS = new ExifTag[] { - new ExifTag("ThumbnailImageWidth", 256), - new ExifTag("ThumbnailImageLength", 257), - new ExifTag("BitsPerSample", 258), - new ExifTag("Compression", 259), - new ExifTag("PhotometricInterpretation", 262), - new ExifTag("ImageDescription", 270), - new ExifTag("Make", 271), - new ExifTag("Model", 272), - new ExifTag("StripOffsets", 273), - new ExifTag("Orientation", 274), - new ExifTag("SamplesPerPixel", 277), - new ExifTag("RowsPerStrip", 278), - new ExifTag("StripByteCounts", 279), - new ExifTag("XResolution", 282), - new ExifTag("YResolution", 283), - new ExifTag("PlanarConfiguration", 284), - new ExifTag("ResolutionUnit", 296), - new ExifTag("TransferFunction", 301), - new ExifTag("Software", 305), - new ExifTag("DateTime", 306), - new ExifTag("Artist", 315), - new ExifTag("WhitePoint", 318), - new ExifTag("PrimaryChromaticities", 319), - new ExifTag("JPEGInterchangeFormat", 513), - new ExifTag("JPEGInterchangeFormatLength", 514), - new ExifTag("YCbCrCoefficients", 529), - new ExifTag("YCbCrSubSampling", 530), - new ExifTag("YCbCrPositioning", 531), - new ExifTag("ReferenceBlackWhite", 532), - new ExifTag("Copyright", 33432), - new ExifTag("ExifIFDPointer", 34665), - new ExifTag("GPSInfoIFDPointer", 34853), + new ExifTag(TAG_THUMBNAIL_IMAGE_WIDTH, 256), + new ExifTag(TAG_THUMBNAIL_IMAGE_LENGTH, 257), + new ExifTag(TAG_BITS_PER_SAMPLE, 258), + new ExifTag(TAG_COMPRESSION, 259), + new ExifTag(TAG_PHOTOMETRIC_INTERPRETATION, 262), + new ExifTag(TAG_IMAGE_DESCRIPTION, 270), + new ExifTag(TAG_MAKE, 271), + new ExifTag(TAG_MODEL, 272), + new ExifTag(TAG_STRIP_OFFSETS, 273), + new ExifTag(TAG_ORIENTATION, 274), + new ExifTag(TAG_SAMPLES_PER_PIXEL, 277), + new ExifTag(TAG_ROWS_PER_STRIP, 278), + new ExifTag(TAG_STRIP_BYTE_COUNTS, 279), + new ExifTag(TAG_X_RESOLUTION, 282), + new ExifTag(TAG_Y_RESOLUTION, 283), + new ExifTag(TAG_PLANAR_CONFIGURATION, 284), + new ExifTag(TAG_RESOLUTION_UNIT, 296), + new ExifTag(TAG_TRANSFER_FUNCTION, 301), + new ExifTag(TAG_SOFTWARE, 305), + new ExifTag(TAG_DATETIME, 306), + new ExifTag(TAG_ARTIST, 315), + new ExifTag(TAG_WHITE_POINT, 318), + new ExifTag(TAG_PRIMARY_CHROMATICITIES, 319), + new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT, 513), + new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, 514), + new ExifTag(TAG_Y_CB_CR_COEFFICIENTS, 529), + new ExifTag(TAG_Y_CB_CR_SUB_SAMPLING, 530), + new ExifTag(TAG_Y_CB_CR_POSITIONING, 531), + new ExifTag(TAG_REFERENCE_BLACK_WHITE, 532), + new ExifTag(TAG_COPYRIGHT, 33432), + new ExifTag(TAG_EXIF_IFD_POINTER, 34665), + new ExifTag(TAG_GPS_INFO_IFD_POINTER, 34853), }; // See JEITA CP-3451 Figure 5. page 9. @@ -391,9 +581,9 @@ public class ExifInterface { }; // List of tags for pointing to the other image file directory offset. private static final ExifTag[] IFD_POINTER_TAGS = new ExifTag[] { - new ExifTag("ExifIFDPointer", 34665), - new ExifTag("GPSInfoPointer", 34853), - new ExifTag("InteroperabilityIFDPointer", 40965), + new ExifTag(TAG_EXIF_IFD_POINTER, 34665), + new ExifTag(TAG_GPS_INFO_IFD_POINTER, 34853), + new ExifTag(TAG_INTEROPERABILITY_IFD_POINTER, 40965), }; // List of indices of the indicated tag groups according to the IFD_POINTER_TAGS private static final int[] IFD_POINTER_TAG_HINTS = new int[] { @@ -401,15 +591,14 @@ public class ExifInterface { }; // Tags for indicating the thumbnail offset and length private static final ExifTag JPEG_INTERCHANGE_FORMAT_TAG = - new ExifTag("JPEGInterchangeFormat", 513); + new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT, 513); private static final ExifTag JPEG_INTERCHANGE_FORMAT_LENGTH_TAG = - new ExifTag("JPEGInterchangeFormatLength", 514); + new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, 514); // Mappings from tag number to tag name and each item represents one IFD tag group. private static final HashMap[] sExifTagMapsForReading = new HashMap[EXIF_TAGS.length]; - // Mapping from tag name to tag number and the corresponding tag group. - private static final HashMap<String, Pair<Integer, Integer>> sExifTagMapForWriting - = new HashMap<>(); + // Mappings from tag name to tag number and each item represents one IFD tag group. + private static final HashMap[] sExifTagMapsForWriting = new HashMap[EXIF_TAGS.length]; // See JPEG File Interchange Format Version 1.02. // The following values are defined for handling JPEG streams. In this implementation, we are @@ -443,35 +632,26 @@ public class ExifInterface { static { System.loadLibrary("media_jni"); - initRawNative(); + nativeInitRaw(); sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss"); sFormatter.setTimeZone(TimeZone.getTimeZone("UTC")); // Build up the hash tables to look up Exif tags for reading Exif tags. for (int hint = 0; hint < EXIF_TAGS.length; ++hint) { sExifTagMapsForReading[hint] = new HashMap(); + sExifTagMapsForWriting[hint] = new HashMap(); for (ExifTag tag : EXIF_TAGS[hint]) { sExifTagMapsForReading[hint].put(tag.number, tag.name); - } - } - - // Build up the hash tables to look up Exif tags for writing Exif tags. - // There are some tags that have the same tag name in the different group. For that tags, - // Primary image TIFF IFD and Exif private IFD have a higher priority to map than the other - // tag groups. For the same tags, it writes one tag in the only one IFD group, which has the - // higher priority group. - for (int hint = EXIF_TAGS.length - 1; hint >= 0; --hint) { - for (ExifTag tag : EXIF_TAGS[hint]) { - sExifTagMapForWriting.put(tag.name, new Pair<>(tag.number, hint)); + sExifTagMapsForWriting[hint].put(tag.name, tag.number); } } } private final String mFilename; - private final FileDescriptor mFileDescriptor; - private final InputStream mInputStream; + private final FileDescriptor mSeekableFileDescriptor; + private final AssetManager.AssetInputStream mAssetInputStream; private boolean mIsRaw; - private final HashMap<String, String> mAttributes = new HashMap<>(); + private final HashMap[] mAttributes = new HashMap[EXIF_TAGS.length]; private boolean mHasThumbnail; // The following values used for indicating a thumbnail position. private int mThumbnailOffset; @@ -488,23 +668,33 @@ public class ExifInterface { if (filename == null) { throw new IllegalArgumentException("filename cannot be null"); } + FileInputStream in = new FileInputStream(filename); + mAssetInputStream = null; mFilename = filename; - mFileDescriptor = null; - mInputStream = new FileInputStream(filename); - loadAttributes(); + if (isSeekableFD(in.getFD())) { + mSeekableFileDescriptor = in.getFD(); + } else { + mSeekableFileDescriptor = null; + } + loadAttributes(in); } /** - * Reads Exif tags from the specified image file descriptor. + * Reads Exif tags from the specified image file descriptor. Attribute mutation is supported + * for seekable file descriptors only. */ public ExifInterface(FileDescriptor fileDescriptor) throws IOException { if (fileDescriptor == null) { throw new IllegalArgumentException("parcelFileDescriptor cannot be null"); } + mAssetInputStream = null; mFilename = null; - mFileDescriptor = fileDescriptor; - mInputStream = new FileInputStream(fileDescriptor); - loadAttributes(); + if (isSeekableFD(fileDescriptor)) { + mSeekableFileDescriptor = fileDescriptor; + } else { + mSeekableFileDescriptor = null; + } + loadAttributes(new FileInputStream(fileDescriptor)); } /** @@ -516,9 +706,18 @@ public class ExifInterface { throw new IllegalArgumentException("inputStream cannot be null"); } mFilename = null; - mFileDescriptor = null; - mInputStream = inputStream; - loadAttributes(); + if (inputStream instanceof AssetManager.AssetInputStream) { + mAssetInputStream = (AssetManager.AssetInputStream) inputStream; + mSeekableFileDescriptor = null; + } else if (inputStream instanceof FileInputStream + && isSeekableFD(((FileInputStream) inputStream).getFD())) { + mAssetInputStream = null; + mSeekableFileDescriptor = ((FileInputStream) inputStream).getFD(); + } else { + mAssetInputStream = null; + mSeekableFileDescriptor = null; + } + loadAttributes(inputStream); } /** @@ -528,7 +727,15 @@ public class ExifInterface { * @param tag the name of the tag. */ public String getAttribute(String tag) { - return mAttributes.get(tag); + // Retrieves all tag groups. The value from primary image tag group has a higher priority + // than the value from the thumbnail tag group if there are more than one candidates. + for (int i = 0; i < EXIF_TAGS.length; ++i) { + Object value = mAttributes[i].get(tag); + if (value != null) { + return (String) value; + } + } + return null; } /** @@ -540,11 +747,11 @@ public class ExifInterface { * @param defaultValue the value to return if the tag is not available. */ public int getAttributeInt(String tag, int defaultValue) { - String value = mAttributes.get(tag); + String value = getAttribute(tag); if (value == null) return defaultValue; try { return Integer.valueOf(value); - } catch (NumberFormatException ex) { + } catch (NumberFormatException e) { return defaultValue; } } @@ -558,7 +765,7 @@ public class ExifInterface { * @param defaultValue the value to return if the tag is not available. */ public double getAttributeDouble(String tag, double defaultValue) { - String value = mAttributes.get(tag); + String value = getAttribute(tag); if (value == null) return defaultValue; try { int index = value.indexOf("/"); @@ -567,7 +774,7 @@ public class ExifInterface { if (denom == 0) return defaultValue; double num = Double.parseDouble(value.substring(0, index)); return num / denom; - } catch (NumberFormatException ex) { + } catch (NumberFormatException e) { return defaultValue; } } @@ -579,92 +786,114 @@ public class ExifInterface { * @param value the value of the tag. */ public void setAttribute(String tag, String value) { - if (value == null) { - mAttributes.remove(tag); - return; + for (int i = 0 ; i < EXIF_TAGS.length; ++i) { + if (sExifTagMapsForWriting[i].containsKey(tag)) { + mAttributes[i].put(tag, value); + } } - mAttributes.put(tag, value); } /** - * Initialize mAttributes with the attributes from the file mFilename. - * - * mAttributes is a HashMap which stores the Exif attributes of the file. - * The key is the standard tag name and the value is the tag's value: e.g. - * Model -> Nikon. Numeric values are stored as strings. - * - * This function also initialize mHasThumbnail to indicate whether the - * file has a thumbnail inside. + * This function decides which parser to read the image data according to the given input stream + * type and the content of the input stream. In each case, it reads the first three bytes to + * determine whether the image data format is JPEG or not. */ - private void loadAttributes() throws IOException { - FileInputStream in = null; - try { - if (mFilename != null) { - in = new FileInputStream(mFilename); + private void loadAttributes(@NonNull InputStream in) throws IOException { + // Initialize mAttributes. + for (int i = 0; i < EXIF_TAGS.length; ++i) { + mAttributes[i] = new HashMap(); + } + + // Process RAW input stream + if (mAssetInputStream != null) { + long asset = mAssetInputStream.getNativeAsset(); + if (handleRawResult(nativeGetRawAttributesFromAsset(asset))) { + return; } - if (mFileDescriptor != null) { - in = new FileInputStream(mFileDescriptor); + } else if (mSeekableFileDescriptor != null) { + if (handleRawResult(nativeGetRawAttributesFromFileDescriptor( + mSeekableFileDescriptor))) { + return; } - if (in != null) { - // First test whether a given file is a one of RAW format or not. - HashMap map = getRawAttributesNative(Os.dup(in.getFD())); - mIsRaw = map != null; - if (mIsRaw) { - for (Object obj : map.entrySet()) { - Map.Entry entry = (Map.Entry) obj; - String attrName = (String) entry.getKey(); - String attrValue = (String) entry.getValue(); - - switch (attrName) { - case TAG_HAS_THUMBNAIL: - mHasThumbnail = attrValue.equalsIgnoreCase("true"); - break; - case TAG_THUMBNAIL_OFFSET: - mThumbnailOffset = Integer.parseInt(attrValue); - break; - case TAG_THUMBNAIL_LENGTH: - mThumbnailLength = Integer.parseInt(attrValue); - break; - default: - mAttributes.put(attrName, attrValue); - break; - } - } - - if (DEBUG) { - printAttributes(); - } - return; - } + } else { + in = new BufferedInputStream(in, JPEG_SIGNATURE_SIZE); + if (!isJpegInputStream((BufferedInputStream) in) && handleRawResult( + nativeGetRawAttributesFromInputStream(in))) { + return; } - } catch (ErrnoException e) { - e.rethrowAsIOException(); - } finally { - IoUtils.closeQuietly(in); } - try { - if (mFileDescriptor != null) { - Os.lseek(mFileDescriptor, 0, OsConstants.SEEK_SET); - } + // Process JPEG input stream + getJpegAttributes(in); - getJpegAttributes(mInputStream); - } catch (ErrnoException e) { - e.rethrowAsIOException(); - } finally { - IoUtils.closeQuietly(mInputStream); + if (DEBUG) { + printAttributes(); + } + } + + private static boolean isJpegInputStream(BufferedInputStream in) throws IOException { + in.mark(JPEG_SIGNATURE_SIZE); + byte[] signatureBytes = new byte[JPEG_SIGNATURE_SIZE]; + if (in.read(signatureBytes) != JPEG_SIGNATURE_SIZE) { + throw new EOFException(); + } + boolean isJpeg = Arrays.equals(JPEG_SIGNATURE, signatureBytes); + in.reset(); + return isJpeg; + } + + private boolean handleRawResult(HashMap map) { + if (map == null) { + return false; + } + + // Mark for disabling the save feature. + mIsRaw = true; + + for (Map.Entry entry : (Set<Map.Entry>) map.entrySet()) { + String attrName = (String) entry.getKey(); + + switch (attrName) { + case TAG_HAS_THUMBNAIL: + mHasThumbnail = ((String) entry.getValue()).equalsIgnoreCase("true"); + break; + case TAG_THUMBNAIL_OFFSET: + mThumbnailOffset = Integer.parseInt((String) entry.getValue()); + break; + case TAG_THUMBNAIL_LENGTH: + mThumbnailLength = Integer.parseInt((String) entry.getValue()); + break; + case TAG_THUMBNAIL_DATA: + mThumbnailBytes = (byte[]) entry.getValue(); + break; + default: + setAttribute(attrName, (String) entry.getValue()); + break; + } } if (DEBUG) { printAttributes(); } + return true; + } + + private static boolean isSeekableFD(FileDescriptor fd) throws IOException { + try { + Os.lseek(fd, 0, OsConstants.SEEK_CUR); + return true; + } catch (ErrnoException e) { + return false; + } } // Prints out attributes for debugging. private void printAttributes() { - Log.d(TAG, "The size of tags: " + mAttributes.size()); - for (Map.Entry<String, String> entry : mAttributes.entrySet()) { - Log.d(TAG, "tagName: " + entry.getKey() + ", tagValue: " + entry.getValue()); + for (int i = 0; i < mAttributes.length; ++i) { + Log.d(TAG, "The size of tag group[" + i + "]: " + mAttributes[i].size()); + for (Map.Entry entry : (Set<Map.Entry>) mAttributes[i].entrySet()) { + Log.d(TAG, "tagName: " + entry.getKey() + ", tagValue: " + entry.getValue()); + } } } @@ -679,9 +908,9 @@ public class ExifInterface { throw new UnsupportedOperationException( "ExifInterface does not support saving attributes on RAW formats."); } - if (mFileDescriptor == null && mFilename == null) { + if (mSeekableFileDescriptor == null && mFilename == null) { throw new UnsupportedOperationException( - "ExifInterface does not support saving attributes for input streams."); + "ExifInterface does not support saving attributes for the current input."); } // Keep the thumbnail in memory @@ -698,11 +927,10 @@ public class ExifInterface { if (!originalFile.renameTo(tempFile)) { throw new IOException("Could'nt rename to " + tempFile.getAbsolutePath()); } - } - if (mFileDescriptor != null) { + } else if (mSeekableFileDescriptor != null) { tempFile = File.createTempFile("temp", "jpg"); - Os.lseek(mFileDescriptor, 0, OsConstants.SEEK_SET); - in = new FileInputStream(mFileDescriptor); + Os.lseek(mSeekableFileDescriptor, 0, OsConstants.SEEK_SET); + in = new FileInputStream(mSeekableFileDescriptor); out = new FileOutputStream(tempFile); Streams.copy(in, out); } @@ -720,10 +948,9 @@ public class ExifInterface { in = new FileInputStream(tempFile); if (mFilename != null) { out = new FileOutputStream(mFilename); - } - if (mFileDescriptor != null) { - Os.lseek(mFileDescriptor, 0, OsConstants.SEEK_SET); - out = new FileOutputStream(mFileDescriptor); + } else if (mSeekableFileDescriptor != null) { + Os.lseek(mSeekableFileDescriptor, 0, OsConstants.SEEK_SET); + out = new FileOutputStream(mSeekableFileDescriptor); } saveJpegAttributes(in, out); } catch (ErrnoException e) { @@ -760,13 +987,15 @@ public class ExifInterface { // Read the thumbnail. FileInputStream in = null; - try { - if (mFileDescriptor != null) { - Os.lseek(mFileDescriptor, 0, OsConstants.SEEK_SET); - in = new FileInputStream(mFileDescriptor); - } - if (mFilename != null) { + try { + if (mAssetInputStream != null) { + return nativeGetThumbnailFromAsset( + mAssetInputStream.getNativeAsset(), mThumbnailOffset, mThumbnailLength); + } else if (mFilename != null) { in = new FileInputStream(mFilename); + } else if (mSeekableFileDescriptor != null) { + Os.lseek(mSeekableFileDescriptor, 0, OsConstants.SEEK_SET); + in = new FileInputStream(mSeekableFileDescriptor); } if (in == null) { // Should not be reached this. @@ -809,10 +1038,10 @@ public class ExifInterface { * Exif tags are not available. */ public boolean getLatLong(float output[]) { - String latValue = mAttributes.get(TAG_GPS_LATITUDE); - String latRef = mAttributes.get(TAG_GPS_LATITUDE_REF); - String lngValue = mAttributes.get(TAG_GPS_LONGITUDE); - String lngRef = mAttributes.get(TAG_GPS_LONGITUDE_REF); + String latValue = getAttribute(TAG_GPS_LATITUDE); + String latRef = getAttribute(TAG_GPS_LATITUDE_REF); + String lngValue = getAttribute(TAG_GPS_LONGITUDE); + String lngRef = getAttribute(TAG_GPS_LONGITUDE_REF); if (latValue != null && latRef != null && lngValue != null && lngRef != null) { try { @@ -850,7 +1079,7 @@ public class ExifInterface { * @hide */ public long getDateTime() { - String dateTimeString = mAttributes.get(TAG_DATETIME); + String dateTimeString = getAttribute(TAG_DATETIME); if (dateTimeString == null || !sNonZeroTimePattern.matcher(dateTimeString).matches()) return -1; @@ -862,7 +1091,7 @@ public class ExifInterface { if (datetime == null) return -1; long msecs = datetime.getTime(); - String subSecs = mAttributes.get(TAG_SUBSECTIME); + String subSecs = getAttribute(TAG_SUBSECTIME); if (subSecs != null) { try { long sub = Long.valueOf(subSecs); @@ -875,7 +1104,7 @@ public class ExifInterface { } } return msecs; - } catch (IllegalArgumentException ex) { + } catch (IllegalArgumentException e) { return -1; } } @@ -886,8 +1115,8 @@ public class ExifInterface { * @hide */ public long getGpsDateTime() { - String date = mAttributes.get(TAG_GPS_DATESTAMP); - String time = mAttributes.get(TAG_GPS_TIMESTAMP); + String date = getAttribute(TAG_GPS_DATESTAMP); + String time = getAttribute(TAG_GPS_TIMESTAMP); if (date == null || time == null || (!sNonZeroTimePattern.matcher(date).matches() && !sNonZeroTimePattern.matcher(time).matches())) return -1; @@ -899,7 +1128,7 @@ public class ExifInterface { Date datetime = sFormatter.parse(dateTimeString, pos); if (datetime == null) return -1; return datetime.getTime(); - } catch (IllegalArgumentException ex) { + } catch (IllegalArgumentException e) { return -1; } } @@ -1007,8 +1236,7 @@ public class ExifInterface { if (dataInputStream.read(bytes) != length) { throw new IOException("Invalid exif"); } - mAttributes.put("UserComment", - new String(bytes, Charset.forName("US-ASCII"))); + setAttribute("UserComment", new String(bytes, Charset.forName("US-ASCII"))); break; } @@ -1026,10 +1254,9 @@ public class ExifInterface { case MARKER_SOF14: case MARKER_SOF15: { dataInputStream.skipBytes(1); - mAttributes.put("ImageLength", - String.valueOf(dataInputStream.readUnsignedShort())); - mAttributes.put("ImageWidth", + setAttribute("ImageLength", String.valueOf(dataInputStream.readUnsignedShort())); + setAttribute("ImageWidth", String.valueOf(dataInputStream.readUnsignedShort())); length -= 5; break; } @@ -1166,38 +1393,44 @@ public class ExifInterface { readImageFileDirectory(dataInputStream, IFD_TIFF_HINT); // Process thumbnail. - try { - int jpegInterchangeFormat = Integer.parseInt( - mAttributes.get(JPEG_INTERCHANGE_FORMAT_TAG.name)); - int jpegInterchangeFormatLength = Integer.parseInt( - mAttributes.get(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name)); - // The following code limits the size of thumbnail size not to overflow EXIF data area. - jpegInterchangeFormatLength = Math.min(jpegInterchangeFormat - + jpegInterchangeFormatLength, exifOffsetFromBeginning + exifBytes.length) - - jpegInterchangeFormat; - if (jpegInterchangeFormat > 0 && jpegInterchangeFormatLength > 0) { - mHasThumbnail = true; - mThumbnailOffset = exifOffsetFromBeginning + jpegInterchangeFormat; - mThumbnailLength = jpegInterchangeFormatLength; - - // Do not store a thumbnail in memory if the given input can be re-read. - if (mFileDescriptor == null && mFilename == null) { - byte[] thumbnailBytes = new byte[jpegInterchangeFormatLength]; - dataInputStream.seek(jpegInterchangeFormat); - dataInputStream.readFully(thumbnailBytes); - mThumbnailBytes = thumbnailBytes; - - if (DEBUG) { - Bitmap bitmap = BitmapFactory.decodeByteArray( - thumbnailBytes, 0, thumbnailBytes.length); - Log.d(TAG, "Thumbnail offset: " + mThumbnailOffset + ", length: " - + mThumbnailLength + ", width: " + bitmap.getWidth() + ", height: " - + bitmap.getHeight()); + String jpegInterchangeFormatString = getAttribute(JPEG_INTERCHANGE_FORMAT_TAG.name); + String jpegInterchangeFormatLengthString = + getAttribute(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name); + if (jpegInterchangeFormatString != null && jpegInterchangeFormatLengthString != null) { + try { + int jpegInterchangeFormat = Integer.parseInt(jpegInterchangeFormatString); + int jpegInterchangeFormatLength = Integer + .parseInt(jpegInterchangeFormatLengthString); + // The following code limits the size of thumbnail size not to overflow EXIF data area. + jpegInterchangeFormatLength = Math.min(jpegInterchangeFormat + + jpegInterchangeFormatLength, exifOffsetFromBeginning + exifBytes.length) + - jpegInterchangeFormat; + if (jpegInterchangeFormat > 0 && jpegInterchangeFormatLength > 0) { + mHasThumbnail = true; + mThumbnailOffset = exifOffsetFromBeginning + jpegInterchangeFormat; + mThumbnailLength = jpegInterchangeFormatLength; + + if (mFilename == null && mAssetInputStream == null + && mSeekableFileDescriptor == null) { + // Save the thumbnail in memory if the input doesn't support reading again. + byte[] thumbnailBytes = new byte[jpegInterchangeFormatLength]; + dataInputStream.seek(jpegInterchangeFormat); + dataInputStream.readFully(thumbnailBytes); + mThumbnailBytes = thumbnailBytes; + + if (DEBUG) { + Bitmap bitmap = BitmapFactory.decodeByteArray( + thumbnailBytes, 0, thumbnailBytes.length); + Log.d(TAG, "Thumbnail offset: " + mThumbnailOffset + ", length: " + + mThumbnailLength + ", width: " + bitmap.getWidth() + + ", height: " + + bitmap.getHeight()); + } } } + } catch (NumberFormatException e) { + // Ignored the corrupted image. } - } catch (NumberFormatException e) { - // Ignored the corrupted image. } // For compatibility, keep data formats as follows. @@ -1208,7 +1441,7 @@ public class ExifInterface { convertToRational(TAG_FOCAL_LENGTH); convertToDouble(TAG_DIGITAL_ZOOM_RATIO); convertToDouble(TAG_EXPOSURE_TIME); - convertToDouble(TAG_APERTURE); + convertToDouble(TAG_F_NUMBER); convertToDouble(TAG_SUBJECT_DISTANCE); convertToInt(TAG_ISO); convertToDouble(TAG_EXPOSURE_BIAS_VALUE); @@ -1224,29 +1457,29 @@ public class ExifInterface { convertToTimetamp(TAG_GPS_TIMESTAMP); // The value of DATETIME tag has the same value of DATETIME_ORIGINAL tag. - String valueOfDateTimeOriginal = mAttributes.get("DateTimeOriginal"); + String valueOfDateTimeOriginal = getAttribute("DateTimeOriginal"); if (valueOfDateTimeOriginal != null) { - mAttributes.put(TAG_DATETIME, valueOfDateTimeOriginal); + setAttribute(TAG_DATETIME, valueOfDateTimeOriginal); } // Add the default value. - if (!mAttributes.containsKey(TAG_IMAGE_WIDTH)) { - mAttributes.put(TAG_IMAGE_WIDTH, "0"); + if (getAttribute(TAG_IMAGE_WIDTH) == null) { + setAttribute(TAG_IMAGE_WIDTH, "0"); } - if (!mAttributes.containsKey(TAG_IMAGE_LENGTH)) { - mAttributes.put(TAG_IMAGE_LENGTH, "0"); + if (getAttribute(TAG_IMAGE_LENGTH) == null) { + setAttribute(TAG_IMAGE_LENGTH, "0"); } - if (!mAttributes.containsKey(TAG_ORIENTATION)) { - mAttributes.put(TAG_ORIENTATION, "0"); + if (getAttribute(TAG_ORIENTATION) == null) { + setAttribute(TAG_ORIENTATION, "0"); } - if (!mAttributes.containsKey(TAG_LIGHT_SOURCE)) { - mAttributes.put(TAG_LIGHT_SOURCE, "0"); + if (getAttribute(TAG_LIGHT_SOURCE) == null) { + setAttribute(TAG_LIGHT_SOURCE, "0"); } } // Converts the tag value to timestamp; Otherwise deletes the given tag. private void convertToTimetamp(String tagName) { - String entryValue = mAttributes.get(tagName); + String entryValue = getAttribute(tagName); if (entryValue == null) return; int dataFormat = getDataFormatOfExifEntryValue(entryValue); String[] components = entryValue.split(","); @@ -1266,16 +1499,16 @@ public class ExifInterface { int value = numerator / denominator; stringBuilder.append(String.format("%02d", value)); } - mAttributes.put(tagName, stringBuilder.toString()); + setAttribute(tagName, stringBuilder.toString()); } else if (dataFormat != IFD_FORMAT_STRING) { - mAttributes.remove(tagName); + setAttribute(tagName, null); } } // Checks the tag value of a given tag formatted in double type; Otherwise try to convert it to // double type or delete it. private void convertToDouble(String tagName) { - String entryValue = mAttributes.get(tagName); + String entryValue = getAttribute(tagName); if (entryValue == null) return; int dataFormat = getDataFormatOfExifEntryValue(entryValue); switch (dataFormat) { @@ -1295,21 +1528,21 @@ public class ExifInterface { } stringBuilder.append((double) numerator / denominator); } - mAttributes.put(tagName, stringBuilder.toString()); + setAttribute(tagName, stringBuilder.toString()); break; } case IFD_FORMAT_DOUBLE: // Keep it as is. break; default: - mAttributes.remove(tagName); + setAttribute(tagName, null); break; } } // Checks the tag value of a given tag formatted in int type; Otherwise deletes the tag value. private void convertToRational(String tagName) { - String entryValue = mAttributes.get(tagName); + String entryValue = getAttribute(tagName); if (entryValue == null) return; int dataFormat = getDataFormatOfExifEntryValue(entryValue); switch (dataFormat) { @@ -1324,25 +1557,25 @@ public class ExifInterface { double doubleValue = Double.parseDouble(component); stringBuilder.append((int) (doubleValue * 10000.0)).append("/").append(10000); } - mAttributes.put(tagName, stringBuilder.toString()); + setAttribute(tagName, stringBuilder.toString()); break; } case IFD_FORMAT_SRATIONAL: // Keep it as is. break; default: - mAttributes.remove(tagName); + setAttribute(tagName, null); break; } } // Checks the tag value of a given tag formatted in int type; Otherwise deletes the tag value. private void convertToInt(String tagName) { - String entryValue = mAttributes.get(tagName); + String entryValue = getAttribute(tagName); if (entryValue == null) return; int dataFormat = getDataFormatOfExifEntryValue(entryValue); if (dataFormat != IFD_FORMAT_SLONG) { - mAttributes.remove(tagName); + setAttribute(tagName, null); } } @@ -1431,7 +1664,7 @@ public class ExifInterface { String entryValue = readExifEntryValue( dataInputStream, dataFormat, numberOfComponents); if (entryValue != null) { - mAttributes.put(tagName, entryValue); + setAttribute(tagName, entryValue); } } else { StringBuilder entryValueBuilder = new StringBuilder(); @@ -1442,7 +1675,7 @@ public class ExifInterface { entryValueBuilder.append(readExifEntryValue( dataInputStream, dataFormat, numberOfComponents)); } - mAttributes.put(tagName, entryValueBuilder.toString()); + setAttribute(tagName, entryValueBuilder.toString()); } if (dataInputStream.peek() != nextEntryOffset) { @@ -1517,8 +1750,6 @@ public class ExifInterface { StringBuilder stringBuilder = new StringBuilder(); while (true) { int ch = bytes[index]; - if (ch < 0) - throw new EOFException(); if (ch == 0) break; if (ch >= 32) @@ -1554,49 +1785,46 @@ public class ExifInterface { int[] ifdOffsets = new int[EXIF_TAGS.length]; int[] ifdDataSizes = new int[EXIF_TAGS.length]; - // Maps to store tags per IFD tag group - HashMap[] ifdTags = new HashMap[EXIF_TAGS.length]; - for (int i = 0; i < EXIF_TAGS.length; ++i) { - ifdTags[i] = new HashMap(); - } - // Remove IFD pointer tags (we'll re-add it later.) for (ExifTag tag : IFD_POINTER_TAGS) { - mAttributes.remove(tag.name); - } - - // Assign tags to the corresponding group - for (Map.Entry<String, String> entry : mAttributes.entrySet()) { - Pair<Integer, Integer> pair = sExifTagMapForWriting.get(entry.getKey()); - if (pair != null) { - int tagNumber = pair.first; - int hint = pair.second; - ifdTags[hint].put(tagNumber, entry.getValue()); - } + setAttribute(tag.name, null); } // Add IFD pointer tags. The next offset of primary image TIFF IFD will have thumbnail IFD // offset when there is one or more tags in the thumbnail IFD. - if (!ifdTags[IFD_INTEROPERABILITY_HINT].isEmpty()) { - ifdTags[IFD_EXIF_HINT].put(IFD_POINTER_TAGS[2].number, "0"); + if (!mAttributes[IFD_INTEROPERABILITY_HINT].isEmpty()) { + mAttributes[IFD_EXIF_HINT].put(IFD_POINTER_TAGS[2].name, "0"); } - if (!ifdTags[IFD_EXIF_HINT].isEmpty()) { - ifdTags[IFD_TIFF_HINT].put(IFD_POINTER_TAGS[0].number, "0"); + if (!mAttributes[IFD_EXIF_HINT].isEmpty()) { + mAttributes[IFD_TIFF_HINT].put(IFD_POINTER_TAGS[0].name, "0"); } - if (!ifdTags[IFD_GPS_HINT].isEmpty()) { - ifdTags[IFD_TIFF_HINT].put(IFD_POINTER_TAGS[1].number, "0"); + if (!mAttributes[IFD_GPS_HINT].isEmpty()) { + mAttributes[IFD_TIFF_HINT].put(IFD_POINTER_TAGS[1].name, "0"); } + // Remove old thumbnail data + setAttribute(JPEG_INTERCHANGE_FORMAT_TAG.name, null); + setAttribute(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name, null); if (mHasThumbnail) { - ifdTags[IFD_TIFF_HINT].put(JPEG_INTERCHANGE_FORMAT_TAG.number, "0"); - ifdTags[IFD_TIFF_HINT].put(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.number, + mAttributes[IFD_TIFF_HINT].put(JPEG_INTERCHANGE_FORMAT_TAG.name, "0"); + mAttributes[IFD_TIFF_HINT].put(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name, String.valueOf(mThumbnailLength)); } + // Remove null value tags. + for (int hint = 0; hint < EXIF_TAGS.length; ++hint) { + for (Object obj : mAttributes[hint].entrySet().toArray()) { + Map.Entry entry = (Map.Entry) obj; + if (entry.getValue() == null) { + mAttributes[hint].remove(entry.getKey()); + } + } + } + // Calculate IFD group data area sizes. IFD group data area is assigned to save the entry // value which has a bigger size than 4 bytes. for (int i = 0; i < 5; ++i) { int sum = 0; - for (Object entry : ifdTags[i].entrySet()) { + for (Map.Entry entry : (Set<Map.Entry>) mAttributes[i].entrySet()) { String entryValue = (String) ((Map.Entry) entry).getValue(); int dataFormat = getDataFormatOfExifEntryValue(entryValue); int size = getSizeOfExifEntryValue(dataFormat, entryValue); @@ -1610,16 +1838,16 @@ public class ExifInterface { // Calculate IFD offsets. int position = 8; for (int hint = 0; hint < EXIF_TAGS.length; ++hint) { - if (!ifdTags[hint].isEmpty()) { + if (!mAttributes[hint].isEmpty()) { ifdOffsets[hint] = position; - position += 2 + ifdTags[hint].size() * 12 + 4 + ifdDataSizes[hint]; + position += 2 + mAttributes[hint].size() * 12 + 4 + ifdDataSizes[hint]; } } if (mHasThumbnail) { int thumbnailOffset = position; - ifdTags[IFD_TIFF_HINT].put(JPEG_INTERCHANGE_FORMAT_TAG.number, + mAttributes[IFD_TIFF_HINT].put(JPEG_INTERCHANGE_FORMAT_TAG.name, String.valueOf(thumbnailOffset)); - ifdTags[IFD_TIFF_HINT].put(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.number, + mAttributes[IFD_TIFF_HINT].put(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name, String.valueOf(mThumbnailLength)); mThumbnailOffset = exifOffsetFromBeginning + thumbnailOffset; position += mThumbnailLength; @@ -1631,21 +1859,21 @@ public class ExifInterface { Log.d(TAG, "totalSize length: " + totalSize); for (int i = 0; i < 5; ++i) { Log.d(TAG, String.format("index: %d, offsets: %d, tag count: %d, data sizes: %d", - i, ifdOffsets[i], ifdTags[i].size(), ifdDataSizes[i])); + i, ifdOffsets[i], mAttributes[i].size(), ifdDataSizes[i])); } } // Update IFD pointer tags with the calculated offsets. - if (!ifdTags[IFD_EXIF_HINT].isEmpty()) { - ifdTags[IFD_TIFF_HINT].put(IFD_POINTER_TAGS[0].number, + if (!mAttributes[IFD_EXIF_HINT].isEmpty()) { + mAttributes[IFD_TIFF_HINT].put(IFD_POINTER_TAGS[0].name, String.valueOf(ifdOffsets[IFD_EXIF_HINT])); } - if (!ifdTags[IFD_GPS_HINT].isEmpty()) { - ifdTags[IFD_TIFF_HINT].put(IFD_POINTER_TAGS[1].number, + if (!mAttributes[IFD_GPS_HINT].isEmpty()) { + mAttributes[IFD_TIFF_HINT].put(IFD_POINTER_TAGS[1].name, String.valueOf(ifdOffsets[IFD_GPS_HINT])); } - if (!ifdTags[IFD_INTEROPERABILITY_HINT].isEmpty()) { - ifdTags[IFD_EXIF_HINT].put(IFD_POINTER_TAGS[2].number, + if (!mAttributes[IFD_INTEROPERABILITY_HINT].isEmpty()) { + mAttributes[IFD_EXIF_HINT].put(IFD_POINTER_TAGS[2].name, String.valueOf(ifdOffsets[IFD_INTEROPERABILITY_HINT])); } @@ -1658,16 +1886,16 @@ public class ExifInterface { // Write IFD groups. See JEITA CP-3451C Figure 7. page 12. for (int hint = 0; hint < EXIF_TAGS.length; ++hint) { - if (!ifdTags[hint].isEmpty()) { + if (!mAttributes[hint].isEmpty()) { // See JEITA CP-3451C 4.6.2 IFD structure. page 13. // Write entry count - dataOutputStream.writeUnsignedShort(ifdTags[hint].size()); + dataOutputStream.writeUnsignedShort(mAttributes[hint].size()); // Write entry info - int dataOffset = ifdOffsets[hint] + 2 + ifdTags[hint].size() * 12 + 4; - for (Object obj : ifdTags[hint].entrySet()) { - Map.Entry entry = (Map.Entry) obj; - int tagNumber = (int) entry.getKey(); + int dataOffset = ifdOffsets[hint] + 2 + mAttributes[hint].size() * 12 + 4; + for (Map.Entry entry : (Set<Map.Entry>) mAttributes[hint].entrySet()) { + // Convert tag name to tag number. + int tagNumber = (int) sExifTagMapsForWriting[hint].get(entry.getKey()); String entryValue = (String) entry.getValue(); int dataFormat = getDataFormatOfExifEntryValue(entryValue); @@ -1695,15 +1923,14 @@ public class ExifInterface { // Write the next offset. It writes the offset of thumbnail IFD if there is one or // more tags in the thumbnail IFD when the current IFD is the primary image TIFF // IFD; Otherwise 0. - if (hint == 0 && !ifdTags[IFD_THUMBNAIL_HINT].isEmpty()) { + if (hint == 0 && !mAttributes[IFD_THUMBNAIL_HINT].isEmpty()) { dataOutputStream.writeUnsignedInt(ifdOffsets[IFD_THUMBNAIL_HINT]); } else { dataOutputStream.writeUnsignedInt(0); } // Write values of data field exceeding 4 bytes after the next offset. - for (Object obj : ifdTags[hint].entrySet()) { - Map.Entry entry = (Map.Entry) obj; + for (Map.Entry entry : (Set<Map.Entry>) mAttributes[hint].entrySet()) { String entryValue = (String) entry.getValue(); int dataFormat = getDataFormatOfExifEntryValue(entryValue); @@ -1988,6 +2215,10 @@ public class ExifInterface { } // JNI methods for RAW formats. - private static native void initRawNative(); - private static native HashMap getRawAttributesNative(FileDescriptor fileDescriptor); + private static native void nativeInitRaw(); + private static native byte[] nativeGetThumbnailFromAsset( + long asset, int thumbnailOffset, int thumbnailLength); + private static native HashMap nativeGetRawAttributesFromAsset(long asset); + private static native HashMap nativeGetRawAttributesFromFileDescriptor(FileDescriptor fd); + private static native HashMap nativeGetRawAttributesFromInputStream(InputStream in); } diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java index a0e2481d4fdc..26061e450e83 100644 --- a/media/java/android/media/MediaFormat.java +++ b/media/java/android/media/MediaFormat.java @@ -16,6 +16,10 @@ package android.media; +import android.annotation.IntDef; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; @@ -606,6 +610,16 @@ public final class MediaFormat { /** BT.2020 color chromacity coordinates with KR = 0.2627, KB = 0.0593. */ public static final int COLOR_STANDARD_BT2020 = 6; + /** @hide */ + @IntDef({ + COLOR_STANDARD_BT709, + COLOR_STANDARD_BT601_PAL, + COLOR_STANDARD_BT601_NTSC, + COLOR_STANDARD_BT2020, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ColorStandard {} + /** * An optional key describing the opto-electronic transfer function used * for the video content. @@ -628,6 +642,16 @@ public final class MediaFormat { /** ARIB STD-B67 hybrid-log-gamma transfer function. This is used by some HDR video content. */ public static final int COLOR_TRANSFER_HLG = 7; + /** @hide */ + @IntDef({ + COLOR_TRANSFER_LINEAR, + COLOR_TRANSFER_SDR_VIDEO, + COLOR_TRANSFER_ST2084, + COLOR_TRANSFER_HLG, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ColorTransfer {} + /** * An optional key describing the range of the component values of the video content. * @@ -644,6 +668,26 @@ public final class MediaFormat { /** Full range. Y, Cr and Cb component values range from 0 to 255 for 8-bit content. */ public static final int COLOR_RANGE_FULL = 1; + /** @hide */ + @IntDef({ + COLOR_RANGE_LIMITED, + COLOR_RANGE_FULL, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ColorRange {} + + /** + * An optional key describing the static metadata of HDR (high-dynamic-range) video content. + * + * The associated value is a ByteBuffer. This buffer contains the raw contents of the + * Static Metadata Descriptor (including the descriptor ID) of an HDMI Dynamic Range and + * Mastering InfoFrame as defined by CTA-861.3. This key must be provided to video decoders + * for HDR video content unless this information is contained in the bitstream and the video + * decoder supports an HDR-capable profile. This key must be provided to video encoders for + * HDR video content. + */ + public static final String KEY_HDR_STATIC_INFO = "hdr-static-info"; + /** * A key describing a unique ID for the content of a media track. * diff --git a/media/java/android/media/RingtoneManager.java b/media/java/android/media/RingtoneManager.java index 4977391ed5c0..86ebae111029 100644 --- a/media/java/android/media/RingtoneManager.java +++ b/media/java/android/media/RingtoneManager.java @@ -16,10 +16,6 @@ package android.media; -import com.android.internal.database.SortCursor; - -import libcore.io.Streams; - import android.annotation.SdkConstant; import android.annotation.SdkConstant.SdkConstantType; import android.app.Activity; @@ -32,12 +28,15 @@ import android.net.Uri; import android.os.Environment; import android.os.ParcelFileDescriptor; import android.os.Process; -import android.os.RemoteException; import android.provider.MediaStore; import android.provider.Settings; import android.provider.Settings.System; import android.util.Log; +import com.android.internal.database.SortCursor; + +import libcore.io.Streams; + import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -644,7 +643,8 @@ public class RingtoneManager { public static Uri getActualDefaultRingtoneUri(Context context, int type) { String setting = getSettingForType(type); if (setting == null) return null; - final String uriString = Settings.System.getString(context.getContentResolver(), setting); + final String uriString = Settings.System.getStringForUser(context.getContentResolver(), + setting, context.getUserId()); return uriString != null ? Uri.parse(uriString) : null; } @@ -663,8 +663,8 @@ public class RingtoneManager { String setting = getSettingForType(type); if (setting == null) return; - Settings.System.putString(resolver, setting, - ringtoneUri != null ? ringtoneUri.toString() : null); + Settings.System.putStringForUser(resolver, setting, + ringtoneUri != null ? ringtoneUri.toString() : null, context.getUserId()); // Stream selected ringtone into cache so it's available for playback // when CE storage is still locked 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/media/java/android/media/browse/MediaBrowser.java b/media/java/android/media/browse/MediaBrowser.java index 364215534d62..fe2796caf700 100644 --- a/media/java/android/media/browse/MediaBrowser.java +++ b/media/java/android/media/browse/MediaBrowser.java @@ -365,7 +365,7 @@ public final class MediaBrowser { if (options == null) { throw new IllegalArgumentException("options are null"); } - subscribeInternal(parentId, options, callback); + subscribeInternal(parentId, new Bundle(options), callback); } /** @@ -1116,7 +1116,7 @@ public final class MediaBrowser { } } mCallbacks.add(callback); - mOptionsList.add(options == null ? null : new Bundle(options)); + mOptionsList.add(options); } public boolean removeCallback(Bundle options) { diff --git a/media/jni/android_media_ExifInterface.cpp b/media/jni/android_media_ExifInterface.cpp index f7481af776b9..418a3f2c906c 100644 --- a/media/jni/android_media_ExifInterface.cpp +++ b/media/jni/android_media_ExifInterface.cpp @@ -19,12 +19,15 @@ #include "android_media_Utils.h" +#include "android/graphics/CreateJavaOutputStreamAdaptor.h" #include "src/piex_types.h" #include "src/piex.h" #include <jni.h> #include <JNIHelp.h> +#include <androidfw/Asset.h> #include <android_runtime/AndroidRuntime.h> +#include <android/graphics/Utils.h> #include <nativehelper/ScopedLocalRef.h> #include <utils/Log.h> @@ -35,6 +38,9 @@ using namespace android; +static const char kJpegSignatureChars[] = {(char)0xff, (char)0xd8, (char)0xff}; +static const int kJpegSignatureSize = 3; + #define FIND_CLASS(var, className) \ var = env->FindClass(className); \ LOG_FATAL_IF(! var, "Unable to find class " className); @@ -82,18 +88,48 @@ static void ExifInterface_initRaw(JNIEnv *env) { "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"); } -static jobject ExifInterface_getRawMetadata( - JNIEnv* env, jclass /* clazz */, jobject jfileDescriptor) { - int fd = jniGetFDFromFileDescriptor(env, jfileDescriptor); - if (fd < 0) { - ALOGI("Invalid file descriptor"); +static bool is_asset_stream(const SkStream& stream) { + return stream.hasLength() && stream.hasPosition(); +} + +static jobject ExifInterface_getThumbnailFromAsset( + JNIEnv* env, jclass /* clazz */, jlong jasset, jint jthumbnailOffset, + jint jthumbnailLength) { + Asset* asset = reinterpret_cast<Asset*>(jasset); + std::unique_ptr<AssetStreamAdaptor> stream(new AssetStreamAdaptor(asset)); + + std::unique_ptr<jbyte[]> thumbnailData(new jbyte[(int)jthumbnailLength]); + if (thumbnailData.get() == NULL) { + ALOGI("No memory to get thumbnail"); return NULL; } + // Do not know the current offset. So rewind it. + stream->rewind(); + + // Read thumbnail. + stream->skip((int)jthumbnailOffset); + stream->read((void*)thumbnailData.get(), (int)jthumbnailLength); + + // Copy to the byte array. + jbyteArray byteArray = env->NewByteArray(jthumbnailLength); + env->SetByteArrayRegion(byteArray, 0, jthumbnailLength, thumbnailData.get()); + return byteArray; +} + +static jobject getRawAttributes(JNIEnv* env, SkStream* stream, bool returnThumbnail) { + std::unique_ptr<SkStream> streamDeleter(stream); + + std::unique_ptr<::piex::StreamInterface> piexStream; + if (is_asset_stream(*stream)) { + piexStream.reset(new AssetStream(streamDeleter.release())); + } else { + piexStream.reset(new BufferedStream(streamDeleter.release())); + } + piex::PreviewImageData image_data; - std::unique_ptr<FileStream> stream(new FileStream(fd)); - if (!GetExifFromRawImage(stream.get(), String8("[file descriptor]"), image_data)) { + if (!GetExifFromRawImage(piexStream.get(), String8("[piex stream]"), image_data)) { ALOGI("Raw image not detected"); return NULL; } @@ -253,7 +289,117 @@ static jobject ExifInterface_getRawMetadata( } } - return KeyedVectorToHashMap(env, map); + jobject hashMap = KeyedVectorToHashMap(env, map); + + if (returnThumbnail) { + std::unique_ptr<jbyte[]> thumbnailData(new jbyte[image_data.thumbnail.length]); + if (thumbnailData.get() == NULL) { + ALOGE("No memory to parse a thumbnail"); + return NULL; + } + jbyteArray jthumbnailByteArray = env->NewByteArray(image_data.thumbnail.length); + if (jthumbnailByteArray == NULL) { + ALOGE("No memory to parse a thumbnail"); + return NULL; + } + piexStream.get()->GetData(image_data.thumbnail.offset, image_data.thumbnail.length, + (uint8_t*)thumbnailData.get()); + env->SetByteArrayRegion( + jthumbnailByteArray, 0, image_data.thumbnail.length, thumbnailData.get()); + jstring jkey = env->NewStringUTF(String8("thumbnailData")); + env->CallObjectMethod(hashMap, gFields.hashMap.put, jkey, jthumbnailByteArray); + env->DeleteLocalRef(jkey); + env->DeleteLocalRef(jthumbnailByteArray); + } + return hashMap; +} + +static jobject ExifInterface_getRawAttributesFromAsset( + JNIEnv* env, jclass /* clazz */, jlong jasset) { + std::unique_ptr<char[]> jpegSignature(new char[kJpegSignatureSize]); + if (jpegSignature.get() == NULL) { + ALOGE("No enough memory to parse"); + return NULL; + } + + Asset* asset = reinterpret_cast<Asset*>(jasset); + std::unique_ptr<AssetStreamAdaptor> stream(new AssetStreamAdaptor(asset)); + + if (stream.get()->read(jpegSignature.get(), kJpegSignatureSize) != kJpegSignatureSize) { + // Rewind the stream. + stream.get()->rewind(); + + ALOGI("Corrupted image."); + return NULL; + } + + // Rewind the stream. + stream.get()->rewind(); + + if (memcmp(jpegSignature.get(), kJpegSignatureChars, kJpegSignatureSize) == 0) { + ALOGI("Should be a JPEG stream."); + return NULL; + } + + // Try to parse from the given stream. + jobject result = getRawAttributes(env, stream.get(), false); + + // Rewind the stream for the chance to read JPEG. + if (result == NULL) { + stream.get()->rewind(); + } + return result; +} + +static jobject ExifInterface_getRawAttributesFromFileDescriptor( + JNIEnv* env, jclass /* clazz */, jobject jfileDescriptor) { + std::unique_ptr<char[]> jpegSignature(new char[kJpegSignatureSize]); + if (jpegSignature.get() == NULL) { + ALOGE("No enough memory to parse"); + return NULL; + } + + int fd = jniGetFDFromFileDescriptor(env, jfileDescriptor); + if (fd < 0) { + ALOGI("Invalid file descriptor"); + return NULL; + } + + // Restore the file descriptor's offset on exiting this function. + AutoFDSeek autoRestore(fd); + + int dupFd = dup(fd); + + FILE* file = fdopen(dupFd, "r"); + if (file == NULL) { + ALOGI("Failed to open the file descriptor"); + return NULL; + } + + if (fgets(jpegSignature.get(), kJpegSignatureSize, file) == NULL) { + ALOGI("Corrupted image."); + return NULL; + } + + if (memcmp(jpegSignature.get(), kJpegSignatureChars, kJpegSignatureSize) == 0) { + ALOGI("Should be a JPEG stream."); + return NULL; + } + + // Rewind the file descriptor. + fseek(file, 0L, SEEK_SET); + + std::unique_ptr<SkFILEStream> fileStream(new SkFILEStream(file, + SkFILEStream::kCallerPasses_Ownership)); + return getRawAttributes(env, fileStream.get(), false); +} + +static jobject ExifInterface_getRawAttributesFromInputStream( + JNIEnv* env, jclass /* clazz */, jobject jinputStream) { + jbyteArray byteArray = env->NewByteArray(8*1024); + ScopedLocalRef<jbyteArray> scoper(env, byteArray); + std::unique_ptr<SkStream> stream(CreateJavaInputStreamAdaptor(env, jinputStream, scoper.get())); + return getRawAttributes(env, stream.get(), true); } } // extern "C" @@ -261,9 +407,14 @@ static jobject ExifInterface_getRawMetadata( // ---------------------------------------------------------------------------- static JNINativeMethod gMethods[] = { - { "initRawNative", "()V", (void *)ExifInterface_initRaw }, - { "getRawAttributesNative", "(Ljava/io/FileDescriptor;)Ljava/util/HashMap;", - (void*)ExifInterface_getRawMetadata }, + { "nativeInitRaw", "()V", (void *)ExifInterface_initRaw }, + { "nativeGetThumbnailFromAsset", "(JII)[B", (void *)ExifInterface_getThumbnailFromAsset }, + { "nativeGetRawAttributesFromAsset", "(J)Ljava/util/HashMap;", + (void*)ExifInterface_getRawAttributesFromAsset }, + { "nativeGetRawAttributesFromFileDescriptor", "(Ljava/io/FileDescriptor;)Ljava/util/HashMap;", + (void*)ExifInterface_getRawAttributesFromFileDescriptor }, + { "nativeGetRawAttributesFromInputStream", "(Ljava/io/InputStream;)Ljava/util/HashMap;", + (void*)ExifInterface_getRawAttributesFromInputStream }, }; int register_android_media_ExifInterface(JNIEnv *env) { diff --git a/media/jni/android_media_Utils.cpp b/media/jni/android_media_Utils.cpp index f4296617d734..527e6c2210d6 100644 --- a/media/jni/android_media_Utils.cpp +++ b/media/jni/android_media_Utils.cpp @@ -30,30 +30,78 @@ namespace android { +AssetStream::AssetStream(SkStream* stream) + : mStream(stream) { +} + +AssetStream::~AssetStream() { +} + +piex::Error AssetStream::GetData( + const size_t offset, const size_t length, std::uint8_t* data) { + // Seek first. + if (mPosition != offset) { + if (!mStream->seek(offset)) { + return piex::Error::kFail; + } + } + + // Read bytes. + size_t size = mStream->read((void*)data, length); + mPosition += size; + + return size == length ? piex::Error::kOk : piex::Error::kFail; +} + +BufferedStream::BufferedStream(SkStream* stream) + : mStream(stream) { +} + +BufferedStream::~BufferedStream() { +} + +piex::Error BufferedStream::GetData( + const size_t offset, const size_t length, std::uint8_t* data) { + // Seek first. + if (offset + length > mStreamBuffer.bytesWritten()) { + size_t sizeToRead = offset + length - mStreamBuffer.bytesWritten(); + if (sizeToRead <= kMinSizeToRead) { + sizeToRead = kMinSizeToRead; + } + void* tempBuffer = malloc(sizeToRead); + if (tempBuffer != NULL) { + size_t bytesRead = mStream->read(tempBuffer, sizeToRead); + if (bytesRead != sizeToRead) { + free(tempBuffer); + return piex::Error::kFail; + } + mStreamBuffer.write(tempBuffer, bytesRead); + free(tempBuffer); + } + } + + // Read bytes. + if (mStreamBuffer.read((void*)data, offset, length)) { + return piex::Error::kOk; + } else { + return piex::Error::kFail; + } +} + FileStream::FileStream(const int fd) - : mPosition(0), - mSize(0) { + : mPosition(0) { mFile = fdopen(fd, "r"); if (mFile == NULL) { return; } - // Get the size. - fseek(mFile, 0l, SEEK_END); - mSize = ftell(mFile); - fseek(mFile, 0l, SEEK_SET); } FileStream::FileStream(const String8 filename) - : mPosition(0), - mSize(0) { + : mPosition(0) { mFile = fopen(filename.string(), "r"); if (mFile == NULL) { return; } - // Get the size. - fseek(mFile, 0l, SEEK_END); - mSize = ftell(mFile); - fseek(mFile, 0l, SEEK_SET); } FileStream::~FileStream() { @@ -79,7 +127,7 @@ piex::Error FileStream::GetData( mPosition += size; // Handle errors. - if (ferror(mFile) || (size == 0 && feof(mFile))) { + if (ferror(mFile)) { ALOGV("GetData read failed: (offset: %zu, length: %zu)", offset, length); return piex::Error::kFail; } @@ -90,21 +138,12 @@ bool FileStream::exists() const { return mFile != NULL; } -size_t FileStream::size() const { - return mSize; -} - bool GetExifFromRawImage( - FileStream* stream, const String8& filename, piex::PreviewImageData& image_data) { + piex::StreamInterface* stream, const String8& filename, + piex::PreviewImageData& image_data) { // Reset the PreviewImageData to its default. image_data = piex::PreviewImageData(); - if (!stream->exists()) { - // File is not exists. - ALOGV("File is not exists: %s", filename.string()); - return false; - } - if (!piex::IsRaw(stream)) { // Format not supported. ALOGV("Format not supported: %s", filename.string()); @@ -119,12 +158,6 @@ bool GetExifFromRawImage( return false; } - if (image_data.thumbnail_offset + image_data.thumbnail_length > stream->size()) { - // Corrupted image. - ALOGV("Corrupted file: %s", filename.string()); - return false; - } - return true; } diff --git a/media/jni/android_media_Utils.h b/media/jni/android_media_Utils.h index 3791ec933cd9..8184f943ce23 100644 --- a/media/jni/android_media_Utils.h +++ b/media/jni/android_media_Utils.h @@ -21,20 +21,62 @@ #include "src/piex.h" #include <android_runtime/AndroidRuntime.h> +#include <camera3.h> +#include <gui/CpuConsumer.h> #include <jni.h> #include <JNIHelp.h> #include <utils/KeyedVector.h> #include <utils/String8.h> -#include <gui/CpuConsumer.h> -#include <camera3.h> +#include <SkStream.h> namespace android { +class AssetStream : public piex::StreamInterface { +private: + SkStream *mStream; + size_t mPosition; + +public: + AssetStream(SkStream* stream); + ~AssetStream(); + + // Reads 'length' amount of bytes from 'offset' to 'data'. The 'data' buffer + // provided by the caller, guaranteed to be at least "length" bytes long. + // On 'kOk' the 'data' pointer contains 'length' valid bytes beginning at + // 'offset' bytes from the start of the stream. + // Returns 'kFail' if 'offset' + 'length' exceeds the stream and does not + // change the contents of 'data'. + piex::Error GetData( + const size_t offset, const size_t length, std::uint8_t* data) override; +}; + +class BufferedStream : public piex::StreamInterface { +private: + SkStream *mStream; + // Growable memory stream + SkDynamicMemoryWStream mStreamBuffer; + + // Minimum size to read on filling the buffer. + const size_t kMinSizeToRead = 8192; + +public: + BufferedStream(SkStream* stream); + ~BufferedStream(); + + // Reads 'length' amount of bytes from 'offset' to 'data'. The 'data' buffer + // provided by the caller, guaranteed to be at least "length" bytes long. + // On 'kOk' the 'data' pointer contains 'length' valid bytes beginning at + // 'offset' bytes from the start of the stream. + // Returns 'kFail' if 'offset' + 'length' exceeds the stream and does not + // change the contents of 'data'. + piex::Error GetData( + const size_t offset, const size_t length, std::uint8_t* data) override; +}; + class FileStream : public piex::StreamInterface { private: FILE *mFile; size_t mPosition; - size_t mSize; public: FileStream(const int fd); @@ -50,13 +92,12 @@ public: piex::Error GetData( const size_t offset, const size_t length, std::uint8_t* data) override; bool exists() const; - size_t size() const; }; // Reads EXIF metadata from a given raw image via piex. // And returns true if the operation is successful; otherwise, false. bool GetExifFromRawImage( - FileStream* stream, const String8& filename, piex::PreviewImageData& image_data); + piex::StreamInterface* stream, const String8& filename, piex::PreviewImageData& image_data); // Returns true if the conversion is successful; otherwise, false. bool ConvertKeyValueArraysToKeyedVector( diff --git a/media/tests/MediaFrameworkTest/assets/image_exif_byte_order_ii.jpg b/media/tests/MediaFrameworkTest/assets/image_exif_byte_order_ii.jpg Binary files differnew file mode 100644 index 000000000000..477cd3a574c3 --- /dev/null +++ b/media/tests/MediaFrameworkTest/assets/image_exif_byte_order_ii.jpg diff --git a/media/tests/MediaFrameworkTest/assets/image_exif_byte_order_mm.jpg b/media/tests/MediaFrameworkTest/assets/image_exif_byte_order_mm.jpg Binary files differnew file mode 100644 index 000000000000..78ac703850a1 --- /dev/null +++ b/media/tests/MediaFrameworkTest/assets/image_exif_byte_order_mm.jpg diff --git a/media/tests/MediaFrameworkTest/assets/lg_g4_iso_800.dng b/media/tests/MediaFrameworkTest/assets/lg_g4_iso_800.dng Binary files differnew file mode 100644 index 000000000000..5fcc720a5f8f --- /dev/null +++ b/media/tests/MediaFrameworkTest/assets/lg_g4_iso_800.dng diff --git a/media/tests/MediaFrameworkTest/assets/volantis.jpg b/media/tests/MediaFrameworkTest/assets/volantis.jpg Binary files differnew file mode 100644 index 000000000000..cfe300f4eafc --- /dev/null +++ b/media/tests/MediaFrameworkTest/assets/volantis.jpg diff --git a/media/tests/MediaFrameworkTest/res/raw/volantis.jpg b/media/tests/MediaFrameworkTest/res/raw/volantis.jpg Binary files differnew file mode 100644 index 000000000000..cfe300f4eafc --- /dev/null +++ b/media/tests/MediaFrameworkTest/res/raw/volantis.jpg diff --git a/media/tests/MediaFrameworkTest/res/values/exifinterface.xml b/media/tests/MediaFrameworkTest/res/values/exifinterface.xml index 8fc6adcb0dd9..d556ad33c04a 100644 --- a/media/tests/MediaFrameworkTest/res/values/exifinterface.xml +++ b/media/tests/MediaFrameworkTest/res/values/exifinterface.xml @@ -76,9 +76,9 @@ <item>0</item> </array> <array name="lg_g4_iso_800_dng"> - <item>false</item> - <item>0</item> - <item>0</item> + <item>true</item> + <item>256</item> + <item>144</item> <item>true</item> <item>53.834507</item> <item>10.69585</item> @@ -105,4 +105,34 @@ <item>1</item> <item /> </array> + <array name="volantis_jpg"> + <item>false</item> + <item>0</item> + <item>0</item> + <item>true</item> + <item>37.423</item> + <item>-122.162</item> + <item>0.0</item> + <item>htc</item> + <item>Nexus 9</item> + <item>1.2904</item> + <item>2016:03:09 17:36:42</item> + <item>0.0083</item> + <item>64</item> + <item>3097/1000</item> + <item /> + <item /> + <item>2016:03:09</item> + <item>37/1,25/1,2291/100</item> + <item>N</item> + <item>122/1,9/1,4330/100</item> + <item>W</item> + <item /> + <item>08:35:34</item> + <item>720</item> + <item>1280</item> + <item>175</item> + <item>1</item> + <item>0</item> + </array> </resources> diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ExifInterfaceTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ExifInterfaceTest.java index 1c80746eb445..5bd607922c81 100644 --- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ExifInterfaceTest.java +++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/ExifInterfaceTest.java @@ -23,20 +23,20 @@ import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.media.ExifInterface; import android.os.Environment; -import android.os.ParcelFileDescriptor; import android.test.AndroidTestCase; import android.util.Log; import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; +import java.io.BufferedInputStream; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.IOException; -import java.lang.reflect.Type; import libcore.io.IoUtils; import libcore.io.Streams; @@ -46,16 +46,17 @@ public class ExifInterfaceTest extends AndroidTestCase { private static final boolean VERBOSE = false; // lots of logging private static final double DIFFERENCE_TOLERANCE = .005; - private static final int BUFFER_SIZE = 32768; // List of files. - private static final String EXIF_BYTE_ORDER_II_JPEG = "ExifByteOrderII.jpg"; - private static final String EXIF_BYTE_ORDER_MM_JPEG = "ExifByteOrderMM.jpg"; + private static final String EXIF_BYTE_ORDER_II_JPEG = "image_exif_byte_order_ii.jpg"; + private static final String EXIF_BYTE_ORDER_MM_JPEG = "image_exif_byte_order_mm.jpg"; private static final String LG_G4_ISO_800_DNG = "lg_g4_iso_800.dng"; + private static final String VOLANTIS_JPEG = "volantis.jpg"; private static final int[] IMAGE_RESOURCES = new int[] { - R.raw.image_exif_byte_order_ii, R.raw.image_exif_byte_order_mm, R.raw.lg_g4_iso_800 }; + R.raw.image_exif_byte_order_ii, R.raw.image_exif_byte_order_mm, R.raw.lg_g4_iso_800, + R.raw.volantis }; private static final String[] IMAGE_FILENAMES = new String[] { - EXIF_BYTE_ORDER_II_JPEG, EXIF_BYTE_ORDER_MM_JPEG, LG_G4_ISO_800_DNG }; + EXIF_BYTE_ORDER_II_JPEG, EXIF_BYTE_ORDER_MM_JPEG, LG_G4_ISO_800_DNG, VOLANTIS_JPEG }; private static final String[] EXIF_TAGS = { ExifInterface.TAG_MAKE, @@ -165,8 +166,6 @@ public class ExifInterfaceTest extends AndroidTestCase { @Override protected void setUp() throws Exception { - byte[] buffer = new byte[BUFFER_SIZE]; - for (int i = 0; i < IMAGE_RESOURCES.length; ++i) { String outputPath = new File(Environment.getExternalStorageDirectory(), IMAGE_FILENAMES[i]).getAbsolutePath(); @@ -314,26 +313,30 @@ public class ExifInterfaceTest extends AndroidTestCase { expectedValue.whiteBalance); } - private void testExifInterfaceForJpeg(String fileName, int typedArrayResourceId) + private void testExifInterfaceCommon(File imageFile, ExpectedValue expectedValue) throws IOException { - ExpectedValue expectedValue = new ExpectedValue( - getContext().getResources().obtainTypedArray(typedArrayResourceId)); - File imageFile = new File(Environment.getExternalStorageDirectory(), fileName); - // Created via path. ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath()); if (VERBOSE) { - printExifTagsAndValues(fileName, exifInterface); + printExifTagsAndValues(imageFile.getName(), exifInterface); + } + compareWithExpectedValue(exifInterface, expectedValue); + + // Created from an asset file. + InputStream in = mContext.getAssets().open(imageFile.getName()); + exifInterface = new ExifInterface(in); + if (VERBOSE) { + printExifTagsAndValues(imageFile.getName(), exifInterface); } compareWithExpectedValue(exifInterface, expectedValue); // Created via InputStream. - FileInputStream in = null; + in = null; try { - in = new FileInputStream(imageFile.getAbsolutePath()); + in = new BufferedInputStream(new FileInputStream(imageFile.getAbsolutePath())); exifInterface = new ExifInterface(in); if (VERBOSE) { - printExifTagsAndValues(fileName, exifInterface); + printExifTagsAndValues(imageFile.getName(), exifInterface); } compareWithExpectedValue(exifInterface, expectedValue); } finally { @@ -345,18 +348,30 @@ public class ExifInterfaceTest extends AndroidTestCase { FileDescriptor fd = Os.open(imageFile.getAbsolutePath(), OsConstants.O_RDONLY, 0600); exifInterface = new ExifInterface(fd); if (VERBOSE) { - printExifTagsAndValues(fileName, exifInterface); + printExifTagsAndValues(imageFile.getName(), exifInterface); } compareWithExpectedValue(exifInterface, expectedValue); } catch (ErrnoException e) { e.rethrowAsIOException(); } + } + + private void testExifInterfaceForJpeg(String fileName, int typedArrayResourceId) + throws IOException { + ExpectedValue expectedValue = new ExpectedValue( + getContext().getResources().obtainTypedArray(typedArrayResourceId)); + File imageFile = new File(Environment.getExternalStorageDirectory(), fileName); + + // Test for reading from various inputs. + testExifInterfaceCommon(imageFile, expectedValue); // Test for saving attributes. + ExifInterface exifInterface; try { FileDescriptor fd = Os.open(imageFile.getAbsolutePath(), OsConstants.O_RDWR, 0600); exifInterface = new ExifInterface(fd); exifInterface.saveAttributes(); + fd = Os.open(imageFile.getAbsolutePath(), OsConstants.O_RDWR, 0600); exifInterface = new ExifInterface(fd); if (VERBOSE) { printExifTagsAndValues(fileName, exifInterface); @@ -383,25 +398,11 @@ public class ExifInterfaceTest extends AndroidTestCase { getContext().getResources().obtainTypedArray(typedArrayResourceId)); File imageFile = new File(Environment.getExternalStorageDirectory(), fileName); - // Created via path. - ExifInterface exifInterface = new ExifInterface(imageFile.getAbsolutePath()); - if (VERBOSE) { - printExifTagsAndValues(fileName, exifInterface); - } - compareWithExpectedValue(exifInterface, expectedValue); + // Test for reading from various inputs. + testExifInterfaceCommon(imageFile, expectedValue); - // Created via FileDescriptor. - FileInputStream in = null; - try { - in = new FileInputStream(imageFile); - exifInterface = new ExifInterface(in.getFD()); - if (VERBOSE) { - printExifTagsAndValues(fileName, exifInterface); - } - compareWithExpectedValue(exifInterface, expectedValue); - } finally { - IoUtils.closeQuietly(in); - } + // Since ExifInterface does not support for saving attributes for RAW files, do not test + // about writing back in here. } public void testReadExifDataFromExifByteOrderIIJpeg() throws Throwable { @@ -415,4 +416,19 @@ public class ExifInterfaceTest extends AndroidTestCase { public void testReadExifDataFromLgG4Iso800Dng() throws Throwable { testExifInterfaceForRaw(LG_G4_ISO_800_DNG, R.array.lg_g4_iso_800_dng); } + + public void testCorruptedImage() throws Throwable { + byte[] bytes = new byte[1024]; + try { + new ExifInterface(new ByteArrayInputStream(bytes)); + fail("Should not reach here!"); + } catch (IOException e) { + // Success + } + } + + public void testReadExifDataFromVolantisJpg() throws Throwable { + // Test if it is possible to parse the volantis generated JPEG smoothly. + testExifInterfaceForJpeg(VOLANTIS_JPEG, R.array.volantis_jpg); + } } diff --git a/packages/DocumentsUI/AndroidManifest.xml b/packages/DocumentsUI/AndroidManifest.xml index 637e06e1668d..6f38e25e7158 100644 --- a/packages/DocumentsUI/AndroidManifest.xml +++ b/packages/DocumentsUI/AndroidManifest.xml @@ -40,18 +40,6 @@ </activity> <activity - android:name=".DownloadsActivity" - android:theme="@style/DocumentsTheme" - android:label="@string/downloads_label" - android:icon="@drawable/ic_doc_text"> - <intent-filter> - <action android:name="android.provider.action.MANAGE_ROOT" /> - <category android:name="android.intent.category.DEFAULT" /> - <data android:mimeType="vnd.android.document/root" /> - </intent-filter> - </activity> - - <activity android:name=".LauncherActivity" android:theme="@android:style/Theme.NoDisplay" android:icon="@drawable/ic_files_app" @@ -72,6 +60,10 @@ <action android:name="android.intent.action.MAIN" /> </intent-filter> <intent-filter> + <action android:name="android.intent.action.VIEW_DOWNLOADS" /> + <category android:name="android.intent.category.DEFAULT" /> + </intent-filter> + <intent-filter> <action android:name="android.provider.action.BROWSE" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="vnd.android.document/root" /> 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_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/color/item_details.xml b/packages/DocumentsUI/res/color/item_details.xml new file mode 100644 index 000000000000..769b94472a31 --- /dev/null +++ b/packages/DocumentsUI/res/color/item_details.xml @@ -0,0 +1,26 @@ +<?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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:state_enabled="true" + android:color="?android:attr/textColorPrimary" + android:alpha="0.63" /> + <item + android:state_enabled="false" + android:color="?android:attr/textColorPrimary" + android:alpha="0.3" /> +</selector> diff --git a/packages/DocumentsUI/res/color/item_title.xml b/packages/DocumentsUI/res/color/item_title.xml new file mode 100644 index 000000000000..ef6aea33fece --- /dev/null +++ b/packages/DocumentsUI/res/color/item_title.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2016 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item + android:state_enabled="true" + android:color="?android:attr/textColorPrimary" /> + <item + android:state_enabled="false" + android:color="?android:attr/textColorPrimary" + android:alpha="0.3" /> +</selector> 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/res/layout/item_dir_grid.xml b/packages/DocumentsUI/res/layout/item_dir_grid.xml index a4f06d1cefe8..429a972c5d94 100644 --- a/packages/DocumentsUI/res/layout/item_dir_grid.xml +++ b/packages/DocumentsUI/res/layout/item_dir_grid.xml @@ -66,7 +66,7 @@ android:singleLine="true" android:textAlignment="viewStart" android:textAppearance="@android:style/TextAppearance.Material.Subhead" - android:textColor="@*android:color/primary_text_default_material_light" /> + android:textColor="@color/item_title" /> </LinearLayout> diff --git a/packages/DocumentsUI/res/layout/item_doc_grid.xml b/packages/DocumentsUI/res/layout/item_doc_grid.xml index af1703fbe423..56a061fb1f31 100644 --- a/packages/DocumentsUI/res/layout/item_doc_grid.xml +++ b/packages/DocumentsUI/res/layout/item_doc_grid.xml @@ -93,7 +93,7 @@ android:ellipsize="end" android:textAlignment="viewStart" android:textAppearance="@android:style/TextAppearance.Material.Subhead" - android:textColor="@*android:color/primary_text_default_material_light" /> + android:textColor="@color/item_title" /> <TextView android:id="@+id/size" @@ -106,7 +106,7 @@ android:ellipsize="end" android:textAlignment="viewStart" android:textAppearance="@android:style/TextAppearance.Material.Caption" - android:textColor="@*android:color/primary_text_default_material_light" /> + android:textColor="@color/item_details" /> <TextView android:id="@+id/date" @@ -118,7 +118,7 @@ android:ellipsize="end" android:textAlignment="viewStart" android:textAppearance="@android:style/TextAppearance.Material.Caption" - android:textColor="@*android:color/primary_text_default_material_light" /> + android:textColor="@color/item_details" /> </RelativeLayout> diff --git a/packages/DocumentsUI/res/layout/item_doc_list.xml b/packages/DocumentsUI/res/layout/item_doc_list.xml index 29f65e09f184..a939fcddccee 100644 --- a/packages/DocumentsUI/res/layout/item_doc_list.xml +++ b/packages/DocumentsUI/res/layout/item_doc_list.xml @@ -85,7 +85,7 @@ android:singleLine="true" android:textAlignment="viewStart" android:textAppearance="@android:style/TextAppearance.Material.Subhead" - android:textColor="?android:attr/textColorPrimary" /> + android:textColor="@color/item_title" /> <LinearLayout android:id="@+id/line2" @@ -102,8 +102,8 @@ android:ellipsize="end" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@android:style/TextAppearance.Material.Body1" - android:textColor="?android:attr/textColorSecondary" /> + android:textAppearance="@android:style/TextAppearance.Material.Caption" + android:textColor="@color/item_details" /> <TextView android:id="@+id/size" @@ -113,8 +113,8 @@ android:ellipsize="end" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@android:style/TextAppearance.Material.Body1" - android:textColor="?android:attr/textColorSecondary" /> + android:textAppearance="@android:style/TextAppearance.Material.Caption" + android:textColor="@color/item_details" /> <TextView android:id="@android:id/summary" @@ -125,8 +125,8 @@ android:ellipsize="end" android:singleLine="true" android:textAlignment="viewStart" - android:textAppearance="@android:style/TextAppearance.Material.Body1" - android:textColor="?android:attr/textColorSecondary" /> + android:textAppearance="@android:style/TextAppearance.Material.Caption" + android:textColor="@color/item_details" /> </LinearLayout> </LinearLayout> </LinearLayout> diff --git a/packages/DocumentsUI/res/values-af/strings.xml b/packages/DocumentsUI/res/values-af/strings.xml index d195ed5b14b8..6fff804f12dc 100644 --- a/packages/DocumentsUI/res/values-af/strings.xml +++ b/packages/DocumentsUI/res/values-af/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Vee <xliff:g id="COUNT_1">%1$d</xliff:g> lêers uit?</item> <item quantity="one">Vee <xliff:g id="COUNT_0">%1$d</xliff:g> lêer uit?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> gekies</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> gekies</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-am/strings.xml b/packages/DocumentsUI/res/values-am/strings.xml index d04980e5a89d..c61db57b42ad 100644 --- a/packages/DocumentsUI/res/values-am/strings.xml +++ b/packages/DocumentsUI/res/values-am/strings.xml @@ -116,4 +116,8 @@ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎች ይሰረዙ?</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ፋይሎች ይሰረዙ?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ተመርጠዋል</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ተመርጠዋል</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-ar/strings.xml b/packages/DocumentsUI/res/values-ar/strings.xml index 157d07f835c7..dcfef2ac6534 100644 --- a/packages/DocumentsUI/res/values-ar/strings.xml +++ b/packages/DocumentsUI/res/values-ar/strings.xml @@ -148,4 +148,12 @@ <item quantity="other">هل تريد حذف <xliff:g id="COUNT_1">%1$d</xliff:g> ملف؟</item> <item quantity="one">هل تريد حذف <xliff:g id="COUNT_0">%1$d</xliff:g> ملف؟</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="zero">تم تحديد <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="two">تم تحديد <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="few">تم تحديد <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="many">تم تحديد <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="other">تم تحديد <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="one">تم تحديد <xliff:g id="COUNT_0">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-az-rAZ/strings.xml b/packages/DocumentsUI/res/values-az-rAZ/strings.xml index 2e07260b88df..e1505f8531cf 100644 --- a/packages/DocumentsUI/res/values-az-rAZ/strings.xml +++ b/packages/DocumentsUI/res/values-az-rAZ/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> fayl silinsin?</item> <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> fayl silinsin?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> seçilib</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> seçilib</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml index 457c3e7e0ef6..b884a19a8c38 100644 --- a/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml +++ b/packages/DocumentsUI/res/values-b+sr+Latn/strings.xml @@ -124,4 +124,9 @@ <item quantity="few">Želite li da izbrišete <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke?</item> <item quantity="other">Želite li da izbrišete <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one">Izabrana je <xliff:g id="COUNT_1">%1$d</xliff:g> stavka</item> + <item quantity="few">Izabrane su <xliff:g id="COUNT_1">%1$d</xliff:g> stavke</item> + <item quantity="other">Izabrano je <xliff:g id="COUNT_1">%1$d</xliff:g> stavki</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-bg/strings.xml b/packages/DocumentsUI/res/values-bg/strings.xml index c0fb178b7ca4..94c34bdb93ae 100644 --- a/packages/DocumentsUI/res/values-bg/strings.xml +++ b/packages/DocumentsUI/res/values-bg/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Искате ли да изтриете <xliff:g id="COUNT_1">%1$d</xliff:g> файла?</item> <item quantity="one">Искате ли да изтриете <xliff:g id="COUNT_0">%1$d</xliff:g> файл?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other">Избрахте <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="one">Избрахте <xliff:g id="COUNT_0">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-bn-rBD/strings.xml b/packages/DocumentsUI/res/values-bn-rBD/strings.xml index 0c5e4cb78fdf..215904429482 100644 --- a/packages/DocumentsUI/res/values-bn-rBD/strings.xml +++ b/packages/DocumentsUI/res/values-bn-rBD/strings.xml @@ -116,4 +116,8 @@ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মুছবেন?</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি ফাইল মুছবেন?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>টি নির্বাচন করা হয়েছে</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>টি নির্বাচন করা হয়েছে</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-bs-rBA/strings.xml b/packages/DocumentsUI/res/values-bs-rBA/strings.xml index 03387c383907..f366ce8cf9d2 100644 --- a/packages/DocumentsUI/res/values-bs-rBA/strings.xml +++ b/packages/DocumentsUI/res/values-bs-rBA/strings.xml @@ -124,4 +124,9 @@ <item quantity="few">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> fajla.</item> <item quantity="other">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> fajlova.</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> stavka je odabrana</item> + <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> stavke su odabrane</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> stavki je odabrano</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-ca/strings.xml b/packages/DocumentsUI/res/values-ca/strings.xml index 42eab759c162..5af86b122a72 100644 --- a/packages/DocumentsUI/res/values-ca/strings.xml +++ b/packages/DocumentsUI/res/values-ca/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Vols suprimir <xliff:g id="COUNT_1">%1$d</xliff:g> fitxers?</item> <item quantity="one">Vols suprimir <xliff:g id="COUNT_0">%1$d</xliff:g> fitxer?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elements seleccionats</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> element seleccionat</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-cs/strings.xml b/packages/DocumentsUI/res/values-cs/strings.xml index a9b67241c15a..4e8b4403433a 100644 --- a/packages/DocumentsUI/res/values-cs/strings.xml +++ b/packages/DocumentsUI/res/values-cs/strings.xml @@ -132,4 +132,10 @@ <item quantity="other">Smazat <xliff:g id="COUNT_1">%1$d</xliff:g> souborů?</item> <item quantity="one">Smazat <xliff:g id="COUNT_0">%1$d</xliff:g> soubor?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="few">Vybrány <xliff:g id="COUNT_1">%1$d</xliff:g> položky</item> + <item quantity="many">Vybráno <xliff:g id="COUNT_1">%1$d</xliff:g> položky</item> + <item quantity="other">Vybráno <xliff:g id="COUNT_1">%1$d</xliff:g> položek</item> + <item quantity="one">Vybrána <xliff:g id="COUNT_0">%1$d</xliff:g> položka</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-da/strings.xml b/packages/DocumentsUI/res/values-da/strings.xml index 661e81f0086d..ee5ba49a5426 100644 --- a/packages/DocumentsUI/res/values-da/strings.xml +++ b/packages/DocumentsUI/res/values-da/strings.xml @@ -116,4 +116,8 @@ <item quantity="one">Vil du slette <xliff:g id="COUNT_1">%1$d</xliff:g> filer?</item> <item quantity="other">Vil du slette <xliff:g id="COUNT_1">%1$d</xliff:g> filer?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one">Der er valgt <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="other">Der er valgt <xliff:g id="COUNT_1">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-de/strings.xml b/packages/DocumentsUI/res/values-de/strings.xml index ebbbf3176bf7..a42e9554acd2 100644 --- a/packages/DocumentsUI/res/values-de/strings.xml +++ b/packages/DocumentsUI/res/values-de/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Möchtest du <xliff:g id="COUNT_1">%1$d</xliff:g> Dateien löschen?</item> <item quantity="one">Möchtest du <xliff:g id="COUNT_0">%1$d</xliff:g> Datei löschen?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ausgewählt</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ausgewählt</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-el/strings.xml b/packages/DocumentsUI/res/values-el/strings.xml index 39e68284c4f1..e6839de1455f 100644 --- a/packages/DocumentsUI/res/values-el/strings.xml +++ b/packages/DocumentsUI/res/values-el/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Να διαγραφούν <xliff:g id="COUNT_1">%1$d</xliff:g> αρχεία;</item> <item quantity="one">Να διαγραφεί <xliff:g id="COUNT_0">%1$d</xliff:g> αρχείο;</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> επιλεγμένα</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> επιλεγμένο</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-en-rAU/strings.xml b/packages/DocumentsUI/res/values-en-rAU/strings.xml index c18f1a514db4..8b46660b2329 100644 --- a/packages/DocumentsUI/res/values-en-rAU/strings.xml +++ b/packages/DocumentsUI/res/values-en-rAU/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> files?</item> <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> file?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-en-rGB/strings.xml b/packages/DocumentsUI/res/values-en-rGB/strings.xml index c18f1a514db4..8b46660b2329 100644 --- a/packages/DocumentsUI/res/values-en-rGB/strings.xml +++ b/packages/DocumentsUI/res/values-en-rGB/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> files?</item> <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> file?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-en-rIN/strings.xml b/packages/DocumentsUI/res/values-en-rIN/strings.xml index c18f1a514db4..8b46660b2329 100644 --- a/packages/DocumentsUI/res/values-en-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-en-rIN/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Delete <xliff:g id="COUNT_1">%1$d</xliff:g> files?</item> <item quantity="one">Delete <xliff:g id="COUNT_0">%1$d</xliff:g> file?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selected</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selected</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-es-rUS/strings.xml b/packages/DocumentsUI/res/values-es-rUS/strings.xml index 2808e5f86834..8fd8381d8f18 100644 --- a/packages/DocumentsUI/res/values-es-rUS/strings.xml +++ b/packages/DocumentsUI/res/values-es-rUS/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">¿Deseas borrar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos?</item> <item quantity="one">¿Deseas borrar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementos seleccionados</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento seleccionado</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-es/strings.xml b/packages/DocumentsUI/res/values-es/strings.xml index c8dae74bc1a0..81fc59abb936 100644 --- a/packages/DocumentsUI/res/values-es/strings.xml +++ b/packages/DocumentsUI/res/values-es/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">¿Eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> archivos?</item> <item quantity="one">¿Eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> archivo?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> seleccionados</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> seleccionado</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-et-rEE/strings.xml b/packages/DocumentsUI/res/values-et-rEE/strings.xml index 55749544873b..7cf134e3ebd7 100644 --- a/packages/DocumentsUI/res/values-et-rEE/strings.xml +++ b/packages/DocumentsUI/res/values-et-rEE/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Kas kustutada <xliff:g id="COUNT_1">%1$d</xliff:g> faili?</item> <item quantity="one">Kas kustutada <xliff:g id="COUNT_0">%1$d</xliff:g> fail?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> on valitud</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> on valitud</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-eu-rES/strings.xml b/packages/DocumentsUI/res/values-eu-rES/strings.xml index 0dc1cf84959a..23e407912120 100644 --- a/packages/DocumentsUI/res/values-eu-rES/strings.xml +++ b/packages/DocumentsUI/res/values-eu-rES/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> fitxategi ezabatu nahi dituzu?</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> fitxategi ezabatu nahi duzu?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> hautatuta</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> hautatuta</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-fa/strings.xml b/packages/DocumentsUI/res/values-fa/strings.xml index 52d4910fd87b..6aa56263126c 100644 --- a/packages/DocumentsUI/res/values-fa/strings.xml +++ b/packages/DocumentsUI/res/values-fa/strings.xml @@ -116,4 +116,8 @@ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل حذف شود؟</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فایل حذف شود؟</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد انتخاب شد</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> مورد انتخاب شد</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-fi/strings.xml b/packages/DocumentsUI/res/values-fi/strings.xml index 6afbef261ef4..8be6d6115883 100644 --- a/packages/DocumentsUI/res/values-fi/strings.xml +++ b/packages/DocumentsUI/res/values-fi/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Poistetaanko <xliff:g id="COUNT_1">%1$d</xliff:g> tiedostoa?</item> <item quantity="one">Poistetaanko <xliff:g id="COUNT_0">%1$d</xliff:g> tiedosto?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valittu</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> valittu</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-fr-rCA/strings.xml b/packages/DocumentsUI/res/values-fr-rCA/strings.xml index 2ec67734bbbb..0a3357076722 100644 --- a/packages/DocumentsUI/res/values-fr-rCA/strings.xml +++ b/packages/DocumentsUI/res/values-fr-rCA/strings.xml @@ -116,4 +116,8 @@ <item quantity="one">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> fichier?</item> <item quantity="other">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-fr/strings.xml b/packages/DocumentsUI/res/values-fr/strings.xml index 531a4eec429d..478ea46b83ca 100644 --- a/packages/DocumentsUI/res/values-fr/strings.xml +++ b/packages/DocumentsUI/res/values-fr/strings.xml @@ -116,4 +116,8 @@ <item quantity="one">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> fichier ?</item> <item quantity="other">Supprimer <xliff:g id="COUNT_1">%1$d</xliff:g> fichiers ?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> élément sélectionné</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> éléments sélectionnés</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-gl-rES/strings.xml b/packages/DocumentsUI/res/values-gl-rES/strings.xml index 3d7bdc237348..c933faaf082e 100644 --- a/packages/DocumentsUI/res/values-gl-rES/strings.xml +++ b/packages/DocumentsUI/res/values-gl-rES/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Queres eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros?</item> <item quantity="one">Queres eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other">Seleccionáronse <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="one">Seleccionouse <xliff:g id="COUNT_0">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-gu-rIN/strings.xml b/packages/DocumentsUI/res/values-gu-rIN/strings.xml index 4559354a19e9..e9fda199d091 100644 --- a/packages/DocumentsUI/res/values-gu-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-gu-rIN/strings.xml @@ -116,4 +116,8 @@ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ કાઢી નાખીએ?</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ફાઇલ કાઢી નાખીએ?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> પસંદ કરી</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> પસંદ કરી</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-hi/strings.xml b/packages/DocumentsUI/res/values-hi/strings.xml index b00b5f861a50..489bb98d34e8 100644 --- a/packages/DocumentsUI/res/values-hi/strings.xml +++ b/packages/DocumentsUI/res/values-hi/strings.xml @@ -116,4 +116,8 @@ <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें हटाएं?</item> <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फ़ाइलें हटाएं?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> चयनित</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-hr/strings.xml b/packages/DocumentsUI/res/values-hr/strings.xml index c413e5f3e53f..51b8673a9a91 100644 --- a/packages/DocumentsUI/res/values-hr/strings.xml +++ b/packages/DocumentsUI/res/values-hr/strings.xml @@ -124,4 +124,9 @@ <item quantity="few">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke?</item> <item quantity="other">Želite li izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteka?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one">Odabrano: <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="few">Odabrano: <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="other">Odabrano: <xliff:g id="COUNT_1">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-hu/strings.xml b/packages/DocumentsUI/res/values-hu/strings.xml index c3dca3e509a3..b7e74e024a87 100644 --- a/packages/DocumentsUI/res/values-hu/strings.xml +++ b/packages/DocumentsUI/res/values-hu/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Töröl <xliff:g id="COUNT_1">%1$d</xliff:g> fájlt?</item> <item quantity="one">Töröl <xliff:g id="COUNT_0">%1$d</xliff:g> fájlt?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> kiválasztva</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> kiválasztva</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-hy-rAM/strings.xml b/packages/DocumentsUI/res/values-hy-rAM/strings.xml index f81192806088..4dbae9de21bd 100644 --- a/packages/DocumentsUI/res/values-hy-rAM/strings.xml +++ b/packages/DocumentsUI/res/values-hy-rAM/strings.xml @@ -116,4 +116,8 @@ <item quantity="one">Ջնջե՞լ <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ:</item> <item quantity="other">Ջնջե՞լ <xliff:g id="COUNT_1">%1$d</xliff:g> ֆայլ:</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="other">Ընտրված է՝ <xliff:g id="COUNT_1">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-in/strings.xml b/packages/DocumentsUI/res/values-in/strings.xml index ecf668ce404c..73ed8bcd1c8e 100644 --- a/packages/DocumentsUI/res/values-in/strings.xml +++ b/packages/DocumentsUI/res/values-in/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Hapus <xliff:g id="COUNT_1">%1$d</xliff:g> file?</item> <item quantity="one">Hapus <xliff:g id="COUNT_0">%1$d</xliff:g> file?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-is-rIS/strings.xml b/packages/DocumentsUI/res/values-is-rIS/strings.xml index 5606d8fb3507..75831ed055d9 100644 --- a/packages/DocumentsUI/res/values-is-rIS/strings.xml +++ b/packages/DocumentsUI/res/values-is-rIS/strings.xml @@ -116,4 +116,8 @@ <item quantity="one">Eyða <xliff:g id="COUNT_1">%1$d</xliff:g> skrá?</item> <item quantity="other">Eyða <xliff:g id="COUNT_1">%1$d</xliff:g> skrám?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> valið</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> valin</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-it/strings.xml b/packages/DocumentsUI/res/values-it/strings.xml index 959f33a5fb3e..cfd5611f345e 100644 --- a/packages/DocumentsUI/res/values-it/strings.xml +++ b/packages/DocumentsUI/res/values-it/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Eliminare <xliff:g id="COUNT_1">%1$d</xliff:g> file?</item> <item quantity="one">Eliminare <xliff:g id="COUNT_0">%1$d</xliff:g> file?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> elementi selezionati</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> elemento selezionato</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-iw/strings.xml b/packages/DocumentsUI/res/values-iw/strings.xml index 3c57e8a1cbdc..7d4cb9e99ee0 100644 --- a/packages/DocumentsUI/res/values-iw/strings.xml +++ b/packages/DocumentsUI/res/values-iw/strings.xml @@ -132,4 +132,10 @@ <item quantity="other">האם למחוק <xliff:g id="COUNT_1">%1$d</xliff:g> קבצים?</item> <item quantity="one">האם למחוק קובץ <xliff:g id="COUNT_0">%1$d</xliff:g>?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> נבחרו</item> + <item quantity="many"><xliff:g id="COUNT_1">%1$d</xliff:g> נבחרו</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> נבחרו</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> נבחר</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-ja/strings.xml b/packages/DocumentsUI/res/values-ja/strings.xml index fbfa5edfb91b..9618d36b363e 100644 --- a/packages/DocumentsUI/res/values-ja/strings.xml +++ b/packages/DocumentsUI/res/values-ja/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個のファイルを削除しますか?</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個のファイルを削除しますか?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> 個を選択中</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> 個を選択中</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-ka-rGE/strings.xml b/packages/DocumentsUI/res/values-ka-rGE/strings.xml index ea3633caf680..ac8d267009ff 100644 --- a/packages/DocumentsUI/res/values-ka-rGE/strings.xml +++ b/packages/DocumentsUI/res/values-ka-rGE/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">გსურთ <xliff:g id="COUNT_1">%1$d</xliff:g> ფაილის წაშლა?</item> <item quantity="one">გსურთ <xliff:g id="COUNT_0">%1$d</xliff:g> ფაილის წაშლა?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other">არჩეულია <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="one">არჩეულია <xliff:g id="COUNT_0">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml index 1618e138a06a..759506b34939 100644 --- a/packages/DocumentsUI/res/values-kk-rKZ/strings.xml +++ b/packages/DocumentsUI/res/values-kk-rKZ/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файлды жою керек пе?</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файлды жою керек пе?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> таңдалды</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> таңдалды</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-km-rKH/strings.xml b/packages/DocumentsUI/res/values-km-rKH/strings.xml index 3934348b9195..d83c1d391c5a 100644 --- a/packages/DocumentsUI/res/values-km-rKH/strings.xml +++ b/packages/DocumentsUI/res/values-km-rKH/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">លុបឯកសារ <xliff:g id="COUNT_1">%1$d</xliff:g> ច្បាប់ឬ?</item> <item quantity="one">លុបឯកសារ <xliff:g id="COUNT_0">%1$d</xliff:g> ច្បាប់ឬ?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other">បានជ្រើស <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="one">បានជ្រើស <xliff:g id="COUNT_0">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-kn-rIN/strings.xml b/packages/DocumentsUI/res/values-kn-rIN/strings.xml index 0dda6f1c474f..57ddd0b5ebb3 100644 --- a/packages/DocumentsUI/res/values-kn-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-kn-rIN/strings.xml @@ -116,4 +116,8 @@ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ಅಳಿಸುವುದೇ?</item> <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> ಫೈಲ್ಗಳನ್ನು ಅಳಿಸುವುದೇ?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ಆಯ್ಕೆಮಾಡಲಾಗಿದೆ</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-ko/strings.xml b/packages/DocumentsUI/res/values-ko/strings.xml index bb6c6530d172..907802df36b4 100644 --- a/packages/DocumentsUI/res/values-ko/strings.xml +++ b/packages/DocumentsUI/res/values-ko/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">파일 <xliff:g id="COUNT_1">%1$d</xliff:g>개를 삭제하시겠습니까?</item> <item quantity="one">파일 <xliff:g id="COUNT_0">%1$d</xliff:g>개를 삭제하시겠습니까?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>개 선택됨</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g>개 선택됨</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-ky-rKG/strings.xml b/packages/DocumentsUI/res/values-ky-rKG/strings.xml index ec5faf8822f4..699e76a277bd 100644 --- a/packages/DocumentsUI/res/values-ky-rKG/strings.xml +++ b/packages/DocumentsUI/res/values-ky-rKG/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> файл жок кылынсынбы?</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> файл жок кылынсынбы?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> тандалды</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> тандалды</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-lo-rLA/strings.xml b/packages/DocumentsUI/res/values-lo-rLA/strings.xml index b8968352ef74..468853b99a9c 100644 --- a/packages/DocumentsUI/res/values-lo-rLA/strings.xml +++ b/packages/DocumentsUI/res/values-lo-rLA/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">ລຶບ <xliff:g id="COUNT_1">%1$d</xliff:g> ໄຟລ໌ອອກບໍ?</item> <item quantity="one">ລຶບ <xliff:g id="COUNT_0">%1$d</xliff:g> ໄຟລ໌ອອກບໍ?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other">ເລືອກ <xliff:g id="COUNT_1">%1$d</xliff:g> ແລ້ວ</item> + <item quantity="one">ເລືອກ <xliff:g id="COUNT_0">%1$d</xliff:g> ແລ້ວ</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-lt/strings.xml b/packages/DocumentsUI/res/values-lt/strings.xml index 71fe331b9e21..a6297bec65dd 100644 --- a/packages/DocumentsUI/res/values-lt/strings.xml +++ b/packages/DocumentsUI/res/values-lt/strings.xml @@ -132,4 +132,10 @@ <item quantity="many">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failo?</item> <item quantity="other">Ištrinti <xliff:g id="COUNT_1">%1$d</xliff:g> failų?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one">Pasirinktas <xliff:g id="COUNT_1">%1$d</xliff:g> elementas</item> + <item quantity="few">Pasirinkti <xliff:g id="COUNT_1">%1$d</xliff:g> elementai</item> + <item quantity="many">Pasirinkta <xliff:g id="COUNT_1">%1$d</xliff:g> elemento</item> + <item quantity="other">Pasirinkta <xliff:g id="COUNT_1">%1$d</xliff:g> elementų</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-lv/strings.xml b/packages/DocumentsUI/res/values-lv/strings.xml index d974573ea8e1..1a9b77c065d7 100644 --- a/packages/DocumentsUI/res/values-lv/strings.xml +++ b/packages/DocumentsUI/res/values-lv/strings.xml @@ -124,4 +124,9 @@ <item quantity="one">Vai izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failu?</item> <item quantity="other">Vai izdzēst <xliff:g id="COUNT_1">%1$d</xliff:g> failus?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="zero"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīti</item> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīts</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> atlasīti</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-mk-rMK/strings.xml b/packages/DocumentsUI/res/values-mk-rMK/strings.xml index 632a5102fec3..5bbf8c5d5ee9 100644 --- a/packages/DocumentsUI/res/values-mk-rMK/strings.xml +++ b/packages/DocumentsUI/res/values-mk-rMK/strings.xml @@ -114,6 +114,10 @@ <string name="deny" msgid="2081879885755434506">"Одбиј"</string> <plurals name="delete_confirmation_message" formatted="false" msgid="3519107568984207772"> <item quantity="one">Да се избрише <xliff:g id="COUNT_1">%1$d</xliff:g> датотека?</item> - <item quantity="other">Да се избрише <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки?</item> + <item quantity="other">Да се избришат <xliff:g id="COUNT_1">%1$d</xliff:g> датотеки?</item> + </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> е избрана</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> се избрани</item> </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-ml-rIN/strings.xml b/packages/DocumentsUI/res/values-ml-rIN/strings.xml index 5441e0c88e59..264d196df594 100644 --- a/packages/DocumentsUI/res/values-ml-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-ml-rIN/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ഫയലുകൾ ഇല്ലാതാക്കണോ?</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ഫയൽ ഇല്ലാതാക്കണോ?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> തിരഞ്ഞെടുത്തു</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> തിരഞ്ഞെടുത്തു</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-mn-rMN/strings.xml b/packages/DocumentsUI/res/values-mn-rMN/strings.xml index b556188a8903..02c818b66590 100644 --- a/packages/DocumentsUI/res/values-mn-rMN/strings.xml +++ b/packages/DocumentsUI/res/values-mn-rMN/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> файлыг устгах уу?</item> <item quantity="one"> <xliff:g id="COUNT_0">%1$d</xliff:g> файлыг устгах уу?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> сонгосон</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> сонгосон</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-mr-rIN/strings.xml b/packages/DocumentsUI/res/values-mr-rIN/strings.xml index 721f2d25394c..6fae5787212e 100644 --- a/packages/DocumentsUI/res/values-mr-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-mr-rIN/strings.xml @@ -116,4 +116,8 @@ <item quantity="one"> <xliff:g id="COUNT_1">%1$d</xliff:g> फाईल हटवायची?</item> <item quantity="other"> <xliff:g id="COUNT_1">%1$d</xliff:g> फायली हटवायच्या?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> निवडला</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> निवडले</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-ms-rMY/strings.xml b/packages/DocumentsUI/res/values-ms-rMY/strings.xml index 9985eb60d66e..6f7c5256c8a2 100644 --- a/packages/DocumentsUI/res/values-ms-rMY/strings.xml +++ b/packages/DocumentsUI/res/values-ms-rMY/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Padamkan <xliff:g id="COUNT_1">%1$d</xliff:g> fail?</item> <item quantity="one">Padamkan <xliff:g id="COUNT_0">%1$d</xliff:g> fail?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dipilih</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dipilih</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-my-rMM/strings.xml b/packages/DocumentsUI/res/values-my-rMM/strings.xml index 3e581aea5ed6..9fb7f84cbdd7 100644 --- a/packages/DocumentsUI/res/values-my-rMM/strings.xml +++ b/packages/DocumentsUI/res/values-my-rMM/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">ဖိုင် <xliff:g id="COUNT_1">%1$d</xliff:g> ခုကိုဖျက်မလား။</item> <item quantity="one">ဖိုင် <xliff:g id="COUNT_0">%1$d</xliff:g> ခုကိုဖျက်မလား။</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ခုရွေးချယ်ထားသည်</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ခုရွေးချယ်ထားသည်</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-nb/strings.xml b/packages/DocumentsUI/res/values-nb/strings.xml index 8257d4ad7867..0e48f0f29360 100644 --- a/packages/DocumentsUI/res/values-nb/strings.xml +++ b/packages/DocumentsUI/res/values-nb/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Vil du slette <xliff:g id="COUNT_1">%1$d</xliff:g> filer?</item> <item quantity="one">Vil du slette <xliff:g id="COUNT_0">%1$d</xliff:g> fil?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> er valgt</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> er valgt</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-ne-rNP/strings.xml b/packages/DocumentsUI/res/values-ne-rNP/strings.xml index 2320192d6f23..cc70c91d36f8 100644 --- a/packages/DocumentsUI/res/values-ne-rNP/strings.xml +++ b/packages/DocumentsUI/res/values-ne-rNP/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> फाइलहरूलाई मेट्ने हो?</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> फाइललाई मेट्ने हो?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> लाई चयन गरियो</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> लाई चयन गरियो</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-nl/strings.xml b/packages/DocumentsUI/res/values-nl/strings.xml index 17b6031373f5..ebddf54cc27c 100644 --- a/packages/DocumentsUI/res/values-nl/strings.xml +++ b/packages/DocumentsUI/res/values-nl/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> bestanden verwijderen?</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> bestand verwijderen?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> geselecteerd</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> geselecteerd</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-pa-rIN/strings.xml b/packages/DocumentsUI/res/values-pa-rIN/strings.xml index 009acbea3d33..a8c65e74e6ba 100644 --- a/packages/DocumentsUI/res/values-pa-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-pa-rIN/strings.xml @@ -116,4 +116,8 @@ <item quantity="one">ਕੀ <xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?</item> <item quantity="other">ਕੀ <xliff:g id="COUNT_1">%1$d</xliff:g> ਫ਼ਾਈਲਾਂ ਨੂੰ ਮਿਟਾਉਣਾ ਹੈ?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ਚੁਣੀ ਗਈ</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ਚੁਣੀਆਂ ਗਈਆਂ</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-pl/strings.xml b/packages/DocumentsUI/res/values-pl/strings.xml index b9bec5d40a38..e888fd7b4482 100644 --- a/packages/DocumentsUI/res/values-pl/strings.xml +++ b/packages/DocumentsUI/res/values-pl/strings.xml @@ -132,4 +132,10 @@ <item quantity="other">Usunąć <xliff:g id="COUNT_1">%1$d</xliff:g> pliku?</item> <item quantity="one">Usunąć <xliff:g id="COUNT_0">%1$d</xliff:g> plik?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="few">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="many">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="other">Wybrano <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="one">Wybrano <xliff:g id="COUNT_0">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-pt-rBR/strings.xml b/packages/DocumentsUI/res/values-pt-rBR/strings.xml index 158bd1dff433..213e76a5ed7d 100644 --- a/packages/DocumentsUI/res/values-pt-rBR/strings.xml +++ b/packages/DocumentsUI/res/values-pt-rBR/strings.xml @@ -116,4 +116,8 @@ <item quantity="one">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos?</item> <item quantity="other">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-pt-rPT/strings.xml b/packages/DocumentsUI/res/values-pt-rPT/strings.xml index 14c6291a5092..2c74e6776e1b 100644 --- a/packages/DocumentsUI/res/values-pt-rPT/strings.xml +++ b/packages/DocumentsUI/res/values-pt-rPT/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Pretende eliminar <xliff:g id="COUNT_1">%1$d</xliff:g> ficheiros?</item> <item quantity="one">Pretende eliminar <xliff:g id="COUNT_0">%1$d</xliff:g> ficheiro?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selecionado</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-pt/strings.xml b/packages/DocumentsUI/res/values-pt/strings.xml index 158bd1dff433..213e76a5ed7d 100644 --- a/packages/DocumentsUI/res/values-pt/strings.xml +++ b/packages/DocumentsUI/res/values-pt/strings.xml @@ -116,4 +116,8 @@ <item quantity="one">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos?</item> <item quantity="other">Excluir <xliff:g id="COUNT_1">%1$d</xliff:g> arquivos?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selecionados</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-ro/strings.xml b/packages/DocumentsUI/res/values-ro/strings.xml index 241be4e0d36f..e57d1ab47e32 100644 --- a/packages/DocumentsUI/res/values-ro/strings.xml +++ b/packages/DocumentsUI/res/values-ro/strings.xml @@ -124,4 +124,9 @@ <item quantity="other">Ștergeți <xliff:g id="COUNT_1">%1$d</xliff:g> de fișiere?</item> <item quantity="one">Ștergeți <xliff:g id="COUNT_0">%1$d</xliff:g> fișier?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> selectate</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> selectate</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> selectat</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-ru/strings.xml b/packages/DocumentsUI/res/values-ru/strings.xml index 606c1c53c227..9c0f03140eac 100644 --- a/packages/DocumentsUI/res/values-ru/strings.xml +++ b/packages/DocumentsUI/res/values-ru/strings.xml @@ -132,4 +132,10 @@ <item quantity="many">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файлов?</item> <item quantity="other">Удалить <xliff:g id="COUNT_1">%1$d</xliff:g> файла?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="few">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="many">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="other">Выбрано: <xliff:g id="COUNT_1">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-si-rLK/strings.xml b/packages/DocumentsUI/res/values-si-rLK/strings.xml index a818bae28a05..a34aa88dc692 100644 --- a/packages/DocumentsUI/res/values-si-rLK/strings.xml +++ b/packages/DocumentsUI/res/values-si-rLK/strings.xml @@ -116,4 +116,8 @@ <item quantity="one">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g>ක් මකන්නද?</item> <item quantity="other">ගොනු <xliff:g id="COUNT_1">%1$d</xliff:g>ක් මකන්නද?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g>ක් තෝරන ලදී</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g>ක් තෝරන ලදී</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-sk/strings.xml b/packages/DocumentsUI/res/values-sk/strings.xml index d8b197072f50..113381511ff6 100644 --- a/packages/DocumentsUI/res/values-sk/strings.xml +++ b/packages/DocumentsUI/res/values-sk/strings.xml @@ -132,4 +132,10 @@ <item quantity="other">Odstrániť <xliff:g id="COUNT_1">%1$d</xliff:g> súborov?</item> <item quantity="one">Odstrániť <xliff:g id="COUNT_0">%1$d</xliff:g> súbor?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="few">Vybraté: <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="many">Vybraté: <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="other">Vybraté: <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="one">Vybraté: <xliff:g id="COUNT_0">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-sl/strings.xml b/packages/DocumentsUI/res/values-sl/strings.xml index c7ab185b7564..f2c691dfebc2 100644 --- a/packages/DocumentsUI/res/values-sl/strings.xml +++ b/packages/DocumentsUI/res/values-sl/strings.xml @@ -132,4 +132,10 @@ <item quantity="few">Želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datoteke?</item> <item quantity="other">Želite izbrisati <xliff:g id="COUNT_1">%1$d</xliff:g> datotek?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> izbran</item> + <item quantity="two"><xliff:g id="COUNT_1">%1$d</xliff:g> izbrana</item> + <item quantity="few"><xliff:g id="COUNT_1">%1$d</xliff:g> izbrani</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> izbranih</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-sq-rAL/strings.xml b/packages/DocumentsUI/res/values-sq-rAL/strings.xml index be87dc29d4a3..80ae0007af2f 100644 --- a/packages/DocumentsUI/res/values-sq-rAL/strings.xml +++ b/packages/DocumentsUI/res/values-sq-rAL/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Të fshihen <xliff:g id="COUNT_1">%1$d</xliff:g> skedarë?</item> <item quantity="one">Të fshihet <xliff:g id="COUNT_0">%1$d</xliff:g> skedar?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> të zgjedhur</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> i zgjedhur</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-sr/strings.xml b/packages/DocumentsUI/res/values-sr/strings.xml index ae6b11b59011..be96db60e581 100644 --- a/packages/DocumentsUI/res/values-sr/strings.xml +++ b/packages/DocumentsUI/res/values-sr/strings.xml @@ -124,4 +124,9 @@ <item quantity="few">Желите ли да избришете <xliff:g id="COUNT_1">%1$d</xliff:g> датотеке?</item> <item quantity="other">Желите ли да избришете <xliff:g id="COUNT_1">%1$d</xliff:g> датотека?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one">Изабрана је <xliff:g id="COUNT_1">%1$d</xliff:g> ставка</item> + <item quantity="few">Изабране су <xliff:g id="COUNT_1">%1$d</xliff:g> ставке</item> + <item quantity="other">Изабрано је <xliff:g id="COUNT_1">%1$d</xliff:g> ставки</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-sv/strings.xml b/packages/DocumentsUI/res/values-sv/strings.xml index 1e7eb6078813..7fd4be072d8b 100644 --- a/packages/DocumentsUI/res/values-sv/strings.xml +++ b/packages/DocumentsUI/res/values-sv/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Radera <xliff:g id="COUNT_1">%1$d</xliff:g> filer?</item> <item quantity="one">Radera <xliff:g id="COUNT_0">%1$d</xliff:g> fil?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> har valts</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> har valts</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-sw/strings.xml b/packages/DocumentsUI/res/values-sw/strings.xml index b3f0a6d206f4..2730ce9b6c7d 100644 --- a/packages/DocumentsUI/res/values-sw/strings.xml +++ b/packages/DocumentsUI/res/values-sw/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Ungependa kufuta faili <xliff:g id="COUNT_1">%1$d</xliff:g>?</item> <item quantity="one">Ungependa kufuta faili <xliff:g id="COUNT_0">%1$d</xliff:g>?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other">Imechagua <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="one">Imechagua <xliff:g id="COUNT_0">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-sw720dp-land/config.xml b/packages/DocumentsUI/res/values-sw720dp-land/config.xml index 8d9526d62dff..6893d7a6735b 100644 --- a/packages/DocumentsUI/res/values-sw720dp-land/config.xml +++ b/packages/DocumentsUI/res/values-sw720dp-land/config.xml @@ -15,5 +15,4 @@ --> <resources> - <bool name="always_show_summary">true</bool> </resources> diff --git a/packages/DocumentsUI/res/values-ta-rIN/strings.xml b/packages/DocumentsUI/res/values-ta-rIN/strings.xml index 7c19e53c7a8d..881e05a8305a 100644 --- a/packages/DocumentsUI/res/values-ta-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-ta-rIN/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> கோப்புகளை நீக்கவா?</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> கோப்பை நீக்கவா?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டன</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> தேர்ந்தெடுக்கப்பட்டது</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-te-rIN/strings.xml b/packages/DocumentsUI/res/values-te-rIN/strings.xml index d12bbb8b1da9..0043ddc55e37 100644 --- a/packages/DocumentsUI/res/values-te-rIN/strings.xml +++ b/packages/DocumentsUI/res/values-te-rIN/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఫైల్లను తొలగించాలా?</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఫైల్ను తొలగించాలా?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ఎంచుకోబడ్డాయి</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ఎంచుకోబడింది</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-th/strings.xml b/packages/DocumentsUI/res/values-th/strings.xml index 678628c61dd5..8b24210dfe30 100644 --- a/packages/DocumentsUI/res/values-th/strings.xml +++ b/packages/DocumentsUI/res/values-th/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">ลบ <xliff:g id="COUNT_1">%1$d</xliff:g> ไฟล์ใช่ไหม</item> <item quantity="one">ลบ <xliff:g id="COUNT_0">%1$d</xliff:g> ไฟล์ใช่ไหม</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other">เลือกไว้ <xliff:g id="COUNT_1">%1$d</xliff:g> รายการ</item> + <item quantity="one">เลือกไว้ <xliff:g id="COUNT_0">%1$d</xliff:g> รายการ</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-tl/strings.xml b/packages/DocumentsUI/res/values-tl/strings.xml index 9079c559113d..9849b8597367 100644 --- a/packages/DocumentsUI/res/values-tl/strings.xml +++ b/packages/DocumentsUI/res/values-tl/strings.xml @@ -116,4 +116,8 @@ <item quantity="one">Gusto mo bang i-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> file?</item> <item quantity="other">Gusto mo bang i-delete ang <xliff:g id="COUNT_1">%1$d</xliff:g> na file?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> ang napili</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ang napili</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-tr/strings.xml b/packages/DocumentsUI/res/values-tr/strings.xml index a462491b907f..8df52d205f56 100644 --- a/packages/DocumentsUI/res/values-tr/strings.xml +++ b/packages/DocumentsUI/res/values-tr/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> dosya silinsin mi?</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> dosya silinsin mi?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> öğe seçildi</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> öğe seçildi</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-uk/strings.xml b/packages/DocumentsUI/res/values-uk/strings.xml index 2fc411ef7d7e..d5a1fcd36429 100644 --- a/packages/DocumentsUI/res/values-uk/strings.xml +++ b/packages/DocumentsUI/res/values-uk/strings.xml @@ -132,4 +132,10 @@ <item quantity="many">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> файлів?</item> <item quantity="other">Видалити <xliff:g id="COUNT_1">%1$d</xliff:g> файлу?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="few">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="many">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="other">Вибрано <xliff:g id="COUNT_1">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-ur-rPK/strings.xml b/packages/DocumentsUI/res/values-ur-rPK/strings.xml index 733d31231b2b..846555a5721a 100644 --- a/packages/DocumentsUI/res/values-ur-rPK/strings.xml +++ b/packages/DocumentsUI/res/values-ur-rPK/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> فائلیں حذف کریں؟</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> فائل حذف کریں؟</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> منتخب کردہ</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> منتخب کردہ</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml index 20da8d0d811c..0e1ac5aee187 100644 --- a/packages/DocumentsUI/res/values-uz-rUZ/strings.xml +++ b/packages/DocumentsUI/res/values-uz-rUZ/strings.xml @@ -116,4 +116,8 @@ <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta fayl o‘chirilsinmi?</item> <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta fayl o‘chirilsinmi?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> ta tanlandi</item> + <item quantity="one"><xliff:g id="COUNT_0">%1$d</xliff:g> ta tanlandi</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-vi/strings.xml b/packages/DocumentsUI/res/values-vi/strings.xml index c7df892e74c3..c3c16f44d4d1 100644 --- a/packages/DocumentsUI/res/values-vi/strings.xml +++ b/packages/DocumentsUI/res/values-vi/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">Xóa <xliff:g id="COUNT_1">%1$d</xliff:g> tệp?</item> <item quantity="one">Xóa <xliff:g id="COUNT_0">%1$d</xliff:g> tệp?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other">Đã chọn <xliff:g id="COUNT_1">%1$d</xliff:g></item> + <item quantity="one">Đã chọn <xliff:g id="COUNT_0">%1$d</xliff:g></item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-zh-rCN/strings.xml b/packages/DocumentsUI/res/values-zh-rCN/strings.xml index 15deb7b18787..7f479ff7646f 100644 --- a/packages/DocumentsUI/res/values-zh-rCN/strings.xml +++ b/packages/DocumentsUI/res/values-zh-rCN/strings.xml @@ -113,7 +113,11 @@ <string name="allow" msgid="7225948811296386551">"允许"</string> <string name="deny" msgid="2081879885755434506">"拒绝"</string> <plurals name="delete_confirmation_message" formatted="false" msgid="3519107568984207772"> - <item quantity="other">要删除 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件吗?</item> - <item quantity="one">要删除 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件吗?</item> + <item quantity="other">删除 <xliff:g id="COUNT_1">%1$d</xliff:g> 个文件?</item> + <item quantity="one">删除 <xliff:g id="COUNT_0">%1$d</xliff:g> 个文件?</item> + </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other">已选择 <xliff:g id="COUNT_1">%1$d</xliff:g> 项</item> + <item quantity="one">已选择 <xliff:g id="COUNT_0">%1$d</xliff:g> 项</item> </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-zh-rHK/strings.xml b/packages/DocumentsUI/res/values-zh-rHK/strings.xml index dd95df537b95..f22e27e7458a 100644 --- a/packages/DocumentsUI/res/values-zh-rHK/strings.xml +++ b/packages/DocumentsUI/res/values-zh-rHK/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">要刪除 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案嗎?</item> <item quantity="one">要刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案嗎?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other">已選取 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item> + <item quantity="one">已選取 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-zh-rTW/strings.xml b/packages/DocumentsUI/res/values-zh-rTW/strings.xml index 41ed92237637..a5ede47a5fab 100644 --- a/packages/DocumentsUI/res/values-zh-rTW/strings.xml +++ b/packages/DocumentsUI/res/values-zh-rTW/strings.xml @@ -116,4 +116,8 @@ <item quantity="other">要刪除 <xliff:g id="COUNT_1">%1$d</xliff:g> 個檔案嗎?</item> <item quantity="one">要刪除 <xliff:g id="COUNT_0">%1$d</xliff:g> 個檔案嗎?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="other">已選取 <xliff:g id="COUNT_1">%1$d</xliff:g> 個項目</item> + <item quantity="one">已選取 <xliff:g id="COUNT_0">%1$d</xliff:g> 個項目</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values-zu/strings.xml b/packages/DocumentsUI/res/values-zu/strings.xml index cc90163f35fa..b99ab8c173c6 100644 --- a/packages/DocumentsUI/res/values-zu/strings.xml +++ b/packages/DocumentsUI/res/values-zu/strings.xml @@ -116,4 +116,8 @@ <item quantity="one">Sula amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>?</item> <item quantity="other">Sula amafayela angu-<xliff:g id="COUNT_1">%1$d</xliff:g>?</item> </plurals> + <plurals name="elements_selected" formatted="false" msgid="1376955402452875047"> + <item quantity="one"><xliff:g id="COUNT_1">%1$d</xliff:g> okukhethiwe</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$d</xliff:g> okukhethiwe</item> + </plurals> </resources> diff --git a/packages/DocumentsUI/res/values/colors.xml b/packages/DocumentsUI/res/values/colors.xml index 3785adf7f878..04b7feeca827 100644 --- a/packages/DocumentsUI/res/values/colors.xml +++ b/packages/DocumentsUI/res/values/colors.xml @@ -23,8 +23,6 @@ <color name="window_background">#fff1f1f1</color> <color name="drawer_background">#fff1f1f1</color> <color name="directory_background">#fff7f7f7</color> - <color name="item_doc_background">#fffafafa</color> - <color name="item_doc_background_selected">#ffe0f2f1</color> <color name="menu_search_background">#ff676f74</color> <color name="primary_dark">@*android:color/primary_dark_material_dark</color> @@ -35,4 +33,11 @@ <color name="band_select_background">#88ffffff</color> <color name="band_select_border">#44000000</color> + + <color name="item_doc_background_disabled">#fff4f4f4</color> + + <!-- TODO: Would be nice to move this to a color-set, but not sure how to support animation --> + <color name="item_doc_background">#fffafafa</color> + <color name="item_doc_background_selected">#ffe0f2f1</color> + </resources> diff --git a/packages/DocumentsUI/res/values/config.xml b/packages/DocumentsUI/res/values/config.xml index 8a7654071a3e..86087c3ffa50 100644 --- a/packages/DocumentsUI/res/values/config.xml +++ b/packages/DocumentsUI/res/values/config.xml @@ -21,5 +21,4 @@ <!-- Intentionally unset. Vendors should set this in an overlay. --> <string name="trusted_quick_viewer_package" translatable="false"></string> <bool name="list_divider_inset_left">true</bool> - <bool name="always_show_summary">false</bool> </resources> 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/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 12a41862e436..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; @@ -95,7 +95,7 @@ public class DocumentsActivity extends BaseActivity { } if (mState.restored) { - refreshCurrentRootAndDirectory(ANIM_NONE); + if (DEBUG) Log.d(TAG, "Stack already resolved"); } else { // We set the activity title in AsyncTask.onPostExecute(). // To prevent talkback from reading aloud the default title, we clear it here. @@ -108,9 +108,7 @@ public class DocumentsActivity extends BaseActivity { // we restore the stack as last used from that app. if (mState.action == ACTION_PICK_COPY_DESTINATION) { if (DEBUG) Log.d(TAG, "Launching directly into Home directory."); - Uri homeUri = DocumentsContract.buildHomeUri(); - new LoadRootTask(this, homeUri).executeOnExecutor( - ProviderExecutor.forAuthority(homeUri.getAuthority())); + loadRoot(DocumentsContract.buildHomeUri()); } else { if (DEBUG) Log.d(TAG, "Attempting to load last used stack for calling package."); new LoadLastUsedStackTask(this).execute(); @@ -156,30 +154,6 @@ public class DocumentsActivity extends BaseActivity { } } - private void onStackRestored(boolean restored, boolean external) { - // Show drawer when no stack restored, but only when requesting - // non-visual content. However, if we last used an external app, - // drawer is always shown. - - boolean showDrawer = false; - if (!restored) { - showDrawer = true; - } - if (MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, mState.acceptMimes)) { - showDrawer = false; - } - if (external && mState.action == ACTION_GET_CONTENT) { - showDrawer = true; - } - if (mState.action == ACTION_PICK_COPY_DESTINATION) { - showDrawer = true; - } - - if (showDrawer) { - mNavigator.revealRootsDrawer(true); - } - } - public void onAppPicked(ResolveInfo info) { final Intent intent = new Intent(getIntent()); intent.setFlags(intent.getFlags() & ~Intent.FLAG_ACTIVITY_FORWARD_RESULT); @@ -517,8 +491,8 @@ public class DocumentsActivity extends BaseActivity { @Override protected void finish(Void result) { mState.restored = true; - mOwner.refreshCurrentRootAndDirectory(ANIM_NONE); - mOwner.onStackRestored(mRestoredStack, mExternal); + mState.external = mExternal; + mOwner.refreshCurrentRootAndDirectory(AnimationView.ANIM_NONE); } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java b/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java deleted file mode 100644 index 2f784cbf2ac3..000000000000 --- a/packages/DocumentsUI/src/com/android/documentsui/DownloadsActivity.java +++ /dev/null @@ -1,185 +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 static com.android.documentsui.State.ACTION_MANAGE; -import static com.android.documentsui.dirlist.DirectoryFragment.ANIM_NONE; - -import android.app.Activity; -import android.app.Fragment; -import android.app.FragmentManager; -import android.content.ActivityNotFoundException; -import android.content.ClipData; -import android.content.Context; -import android.content.Intent; -import android.net.Uri; -import android.os.Bundle; -import android.provider.DocumentsContract; -import android.support.design.widget.Snackbar; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.Toolbar; - -import com.android.documentsui.dirlist.DirectoryFragment; -import com.android.documentsui.dirlist.Model; -import com.android.documentsui.model.DocumentInfo; -import com.android.documentsui.model.RootInfo; - -import java.util.Arrays; -import java.util.List; - -// Let's face it. MANAGE_ROOT is used almost exclusively -// for downloads, and is specialized for this purpose. -// So it is now thusly christened. -public class DownloadsActivity extends BaseActivity { - private static final String TAG = "DownloadsActivity"; - - public DownloadsActivity() { - super(R.layout.downloads_activity, TAG); - } - - @Override - public void onCreate(Bundle icicle) { - super.onCreate(icicle); - - final Context context = this; - - Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); - toolbar.setTitleTextAppearance(context, - android.R.style.TextAppearance_DeviceDefault_Widget_ActionBar_Title); - - if (!mState.restored) { - // In this case, we set the activity title in AsyncTask.onPostExecute(). To prevent - // talkback from reading aloud the default title, we clear it here. - setTitle(""); - final Uri rootUri = getIntent().getData(); - new LoadRootTask(this, rootUri).executeOnExecutor(getExecutorForCurrentDirectory()); - } else { - refreshCurrentRootAndDirectory(ANIM_NONE); - } - } - - @Override - void includeState(State state) { - state.action = ACTION_MANAGE; - state.acceptMimes = new String[] { "*/*" }; - state.allowMultiple = true; - state.showSize = true; - state.excludedAuthorities = getExcludedAuthorities(); - } - - @Override - protected void onPostCreate(Bundle savedInstanceState) { - super.onPostCreate(savedInstanceState); - mNavigator.update(); - } - - @Override - public String getDrawerTitle() { - return null; // being and nothingness - } - - @Override - public boolean onPrepareOptionsMenu(Menu menu) { - super.onPrepareOptionsMenu(menu); - - final MenuItem createDir = menu.findItem(R.id.menu_create_dir); - final MenuItem pasteFromCb = menu.findItem(R.id.menu_paste_from_clipboard); - final MenuItem fileSize = menu.findItem(R.id.menu_file_size); - - createDir.setVisible(false); - pasteFromCb.setEnabled(false); - fileSize.setVisible(false); - - Menus.disableHiddenItems(menu); - return true; - } - - @Override - void refreshDirectory(int anim) { - final FragmentManager fm = getFragmentManager(); - final RootInfo root = getCurrentRoot(); - final DocumentInfo cwd = getCurrentDirectory(); - - assert(!mSearchManager.isSearching()); - - // If started in manage roots mode, there has to be a cwd (i.e. the root dir of the managed - // root). - assert(cwd != null); - - // Normal boring directory - DirectoryFragment.showDirectory(fm, root, cwd, anim); - } - - @Override - public void onDocumentPicked(DocumentInfo doc, Model model) { - assert(!doc.isDirectory()); - - // 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); - manage.setData(doc.derivedUri); - - try { - startActivity(manage); - } catch (ActivityNotFoundException ex) { - // Fall back to viewing. - final Intent view = new Intent(Intent.ACTION_VIEW); - view.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - view.setData(doc.derivedUri); - - try { - startActivity(view); - } catch (ActivityNotFoundException ex2) { - Snackbars.makeSnackbar(this, R.string.toast_no_application, Snackbar.LENGTH_SHORT) - .show(); - } - } - } - - @Override - public void onDocumentsPicked(List<DocumentInfo> docs) {} - - @Override - void onTaskFinished(Uri... uris) { - Log.d(TAG, "onFinished() " + Arrays.toString(uris)); - - final Intent intent = new Intent(); - if (uris.length == 1) { - intent.setData(uris[0]); - } else if (uris.length > 1) { - final ClipData clipData = new ClipData( - null, mState.acceptMimes, new ClipData.Item(uris[0])); - for (int i = 1; i < uris.length; i++) { - clipData.addItem(new ClipData.Item(uris[i])); - } - intent.setClipData(clipData); - } - - intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION - | Intent.FLAG_GRANT_WRITE_URI_PERMISSION - | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); - - setResult(Activity.RESULT_OK, intent); - finish(); - } - - public static DownloadsActivity get(Fragment fragment) { - return (DownloadsActivity) fragment.getActivity(); - } -} diff --git a/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java b/packages/DocumentsUI/src/com/android/documentsui/FilesActivity.java index c56a12f5f1e4..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( @@ -108,10 +108,10 @@ public class FilesActivity extends BaseActivity { // authority. That way a misbehaving provider won't result in an ANR. loadRoot(uri); } else { - if (DEBUG) Log.d(TAG, "Launching into Home directory."); - // If all else fails, try to load "Home" directory. - final Uri homeUri = DocumentsContract.buildHomeUri(); - loadRoot(homeUri); + if (DEBUG) Log.d(TAG, "All other means skipped. Launching into default directory."); + Uri defaultUri = DocumentsContract.buildRootUri( + "com.android.providers.downloads.documents", "downloads"); + loadRoot(defaultUri); } final @DialogType int dialogType = intent.getIntExtra( @@ -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/Metrics.java b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java index dcaea15459a6..afd308cc97a7 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/Metrics.java +++ b/packages/DocumentsUI/src/com/android/documentsui/Metrics.java @@ -18,6 +18,7 @@ package com.android.documentsui; import static android.os.Environment.STANDARD_DIRECTORIES; import static com.android.documentsui.Shared.DEBUG; + import android.annotation.IntDef; import android.annotation.Nullable; import android.annotation.StringDef; @@ -58,7 +59,7 @@ public final class Metrics { private static final String COUNT_CREATE_MIME = "docsui_create_mime"; private static final String COUNT_GET_CONTENT_MIME = "docsui_get_content_mime"; private static final String COUNT_BROWSE_ROOT = "docsui_browse_root"; - private static final String COUNT_MANAGE_ROOT = "docsui_manage_root"; + @Deprecated private static final String COUNT_MANAGE_ROOT = "docsui_manage_root"; private static final String COUNT_MULTI_WINDOW = "docsui_multi_window"; private static final String COUNT_FILEOP_SYSTEM = "docsui_fileop_system"; private static final String COUNT_FILEOP_EXTERNAL = "docsui_fileop_external"; @@ -194,7 +195,7 @@ public final class Metrics { private static final int ACTION_CREATE = 3; private static final int ACTION_GET_CONTENT = 4; private static final int ACTION_OPEN_TREE = 5; - private static final int ACTION_MANAGE = 6; + @Deprecated private static final int ACTION_MANAGE = 6; private static final int ACTION_BROWSE = 7; private static final int ACTION_PICK_COPY_DESTINATION = 8; @@ -246,9 +247,6 @@ public final class Metrics { case State.ACTION_GET_CONTENT: logHistogram(context, COUNT_GET_CONTENT_MIME, sanitizeMime(intent.getType())); break; - case State.ACTION_MANAGE: - logHistogram(context, COUNT_MANAGE_ROOT, sanitizeRoot(uri)); - break; case State.ACTION_BROWSE: logHistogram(context, COUNT_BROWSE_ROOT, sanitizeRoot(uri)); break; @@ -641,8 +639,6 @@ public final class Metrics { return ACTION_GET_CONTENT; case State.ACTION_OPEN_TREE: return ACTION_OPEN_TREE; - case State.ACTION_MANAGE: - return ACTION_MANAGE; case State.ACTION_BROWSE: return ACTION_BROWSE; case State.ACTION_PICK_COPY_DESTINATION: 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/QuickViewIntentBuilder.java b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java index a77a9b3559dc..8fcd9d1545c3 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java +++ b/packages/DocumentsUI/src/com/android/documentsui/QuickViewIntentBuilder.java @@ -113,8 +113,8 @@ final class QuickViewIntentBuilder { } private int collectViewableUris(ArrayList<Uri> uris) { - final List<String> siblingIds = mModel.getModelIds(); - uris.ensureCapacity(siblingIds.size()); + final String[] siblingIds = mModel.getModelIds(); + uris.ensureCapacity(siblingIds.length); int documentLocation = 0; Cursor cursor; @@ -124,8 +124,8 @@ final class QuickViewIntentBuilder { Uri uri; // Cursor's are not guaranteed to be immutable. Hence, traverse it only once. - for (int i = 0; i < siblingIds.size(); i++) { - cursor = mModel.getItem(siblingIds.get(i)); + for (int i = 0; i < siblingIds.length; i++) { + cursor = mModel.getItem(siblingIds[i]); mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); if (Document.MIME_TYPE_DIR.equals(mimeType)) { diff --git a/packages/DocumentsUI/src/com/android/documentsui/State.java b/packages/DocumentsUI/src/com/android/documentsui/State.java index 4f460b4a5cf6..16b7660e8ba4 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/State.java +++ b/packages/DocumentsUI/src/com/android/documentsui/State.java @@ -43,13 +43,15 @@ public class State implements android.os.Parcelable { private static final String TAG = "State"; - public static final int ACTION_OPEN = 1; - public static final int ACTION_CREATE = 2; - public static final int ACTION_GET_CONTENT = 3; - public static final int ACTION_OPEN_TREE = 4; - public static final int ACTION_MANAGE = 5; - public static final int ACTION_BROWSE = 6; - public static final int ACTION_PICK_COPY_DESTINATION = 8; + // File manager and related private picking activity. + public static final int ACTION_BROWSE = 1; + public static final int ACTION_PICK_COPY_DESTINATION = 2; + + // All public picking activities + public static final int ACTION_OPEN = 3; + public static final int ACTION_CREATE = 4; + public static final int ACTION_GET_CONTENT = 5; + public static final int ACTION_OPEN_TREE = 6; @IntDef(flag = true, value = { MODE_UNKNOWN, @@ -83,6 +85,10 @@ public class State implements android.os.Parcelable { public boolean showSize; public boolean localOnly; public boolean restored; + /* + * Indicates handler was an external app, like photos. + */ + public boolean external; // Indicates that a copy operation (or move) includes a directory. // Why? Directory creation isn't supported by some roots (like Downloads). @@ -180,6 +186,7 @@ public class State implements android.os.Parcelable { out.writeInt(showSize ? 1 : 0); out.writeInt(localOnly ? 1 : 0); out.writeInt(restored ? 1 : 0); + out.writeInt(external ? 1 : 0); DurableUtils.writeToParcel(out, stack); out.writeMap(dirState); out.writeParcelable(selectedDocuments, 0); @@ -208,6 +215,7 @@ public class State implements android.os.Parcelable { state.showSize = in.readInt() != 0; state.localOnly = in.readInt() != 0; state.restored = in.readInt() != 0; + state.external = in.readInt() != 0; DurableUtils.readFromParcel(in, state.stack); in.readMap(state.dirState, loader); state.selectedDocuments = in.readParcelable(loader); 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 ca1b444b3531..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) @@ -281,16 +267,6 @@ public class DirectoryFragment extends Fragment mTuner = FragmentTuner.pick(getContext(), state); mClipper = new DocumentClipper(context); - boolean hideGridTitles; - if (mType == TYPE_RECENT_OPEN) { - // Hide titles when showing recents for picking images/videos - hideGridTitles = MimePredicate.mimeMatches( - MimePredicate.VISUAL_MIMES, state.acceptMimes); - } else { - hideGridTitles = (mDocument != null) && mDocument.isGridTitlesHidden(); - } - GridDocumentHolder.setHideTitles(hideGridTitles); - final ActivityManager am = (ActivityManager) context.getSystemService( Context.ACTIVITY_SERVICE); boolean svelte = am.isLowRamDevice() && (mType == TYPE_RECENT_OPEN); @@ -1495,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/dirlist/DocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java index 3b5ce87ebfb0..5edda3866d5c 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/DocumentHolder.java @@ -16,6 +16,7 @@ package com.android.documentsui.dirlist; +import android.annotation.ColorInt; import android.content.Context; import android.database.Cursor; import android.graphics.Rect; @@ -35,17 +36,19 @@ public abstract class DocumentHolder extends RecyclerView.ViewHolder implements View.OnKeyListener { + static final float DISABLED_ALPHA = 0.3f; + public @Nullable String modelId; - final int mSelectedItemColor; - final int mDefaultItemColor; - final boolean mAlwaysShowSummary; final Context mContext; + final @ColorInt int mDefaultBgColor; + final @ColorInt int mSelectedBgColor; DocumentHolder.EventListener mEventListener; private View.OnKeyListener mKeyListener; private View mSelectionHotspot; + public DocumentHolder(Context context, ViewGroup parent, int layout) { this(context, inflateLayout(context, parent, layout)); } @@ -57,9 +60,8 @@ public abstract class DocumentHolder mContext = context; - mDefaultItemColor = context.getColor(R.color.item_doc_background); - mSelectedItemColor = context.getColor(R.color.item_doc_background_selected); - mAlwaysShowSummary = context.getResources().getBoolean(R.bool.always_show_summary); + mDefaultBgColor = context.getColor(R.color.item_doc_background); + mSelectedBgColor = context.getColor(R.color.item_doc_background_selected); mSelectionHotspot = itemView.findViewById(R.id.icon_check); } @@ -80,7 +82,7 @@ public abstract class DocumentHolder */ public void setSelected(boolean selected) { itemView.setActivated(selected); - itemView.setBackgroundColor(selected ? mSelectedItemColor : mDefaultItemColor); + itemView.setBackgroundColor(selected ? mSelectedBgColor : mDefaultBgColor); } /** @@ -88,7 +90,11 @@ public abstract class DocumentHolder * @param highlighted */ public void setHighlighted(boolean highlighted) { - itemView.setBackgroundColor(highlighted ? mSelectedItemColor : mDefaultItemColor); + itemView.setBackgroundColor(highlighted ? mSelectedBgColor : mDefaultBgColor); + } + + public void setEnabled(boolean enabled) { + setEnabledRecursive(itemView, enabled); } @Override @@ -111,10 +117,6 @@ public abstract class DocumentHolder mKeyListener = listener; } - public void setEnabled(boolean enabled) { - setEnabledRecursive(itemView, enabled); - } - public boolean onSingleTapUp(MotionEvent event) { if (Events.isMouseEvent(event)) { // Mouse clicks select. diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java index adaa850b0950..0ee7623a3fe3 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/FragmentTuner.java @@ -19,9 +19,9 @@ package com.android.documentsui.dirlist; import static com.android.documentsui.State.ACTION_BROWSE; import static com.android.documentsui.State.ACTION_CREATE; import static com.android.documentsui.State.ACTION_GET_CONTENT; -import static com.android.documentsui.State.ACTION_MANAGE; 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 android.content.Context; import android.provider.DocumentsContract.Document; @@ -53,8 +53,6 @@ public abstract class FragmentTuner { switch (state.action) { case ACTION_BROWSE: return new FilesTuner(context, state); - case ACTION_MANAGE: - return new DownloadsTuner(context, state); default: return new DocumentsTuner(context, state); } @@ -157,8 +155,27 @@ public abstract class FragmentTuner { @Override void onModelLoaded(Model model, @ResultType int resultType, boolean isSearch) { + boolean showDrawer = false; + + if (mState.restored) { + showDrawer = true; + } + if (MimePredicate.mimeMatches(MimePredicate.VISUAL_MIMES, mState.acceptMimes)) { + showDrawer = false; + } + if (mState.external && mState.action == ACTION_GET_CONTENT) { + showDrawer = true; + } + if (mState.action == ACTION_PICK_COPY_DESTINATION) { + showDrawer = true; + } + // When launched into empty root, open drawer. - if (model.isEmpty() && !mState.hasInitialLocationChanged() && !isSearch) { + if (model.isEmpty()) { + showDrawer = true; + } + + if (showDrawer && !mState.hasInitialLocationChanged() && !isSearch) { // This noops on layouts without drawer, so no need to guard. ((BaseActivity) mContext).setRootsDrawerOpen(true); } @@ -171,47 +188,6 @@ public abstract class FragmentTuner { } /** - * Provides support for Platform specific specializations of DirectoryFragment. - */ - private static final class DownloadsTuner extends FragmentTuner { - - public DownloadsTuner(Context context, State state) { - super(context, state); - assert(state.action == ACTION_MANAGE); - } - - @Override - public void updateActionMenu( - Menu menu, @ResultType int resultType, boolean canDelete, boolean canRename) { - assert(resultType != DirectoryFragment.TYPE_RECENT_OPEN); - - MenuItem open = menu.findItem(R.id.menu_open); - MenuItem delete = menu.findItem(R.id.menu_delete); - MenuItem copyTo = menu.findItem(R.id.menu_copy_to); - MenuItem moveTo = menu.findItem(R.id.menu_move_to); - MenuItem rename = menu.findItem(R.id.menu_rename); - MenuItem copy = menu.findItem(R.id.menu_copy_to_clipboard); - - open.setVisible(false); - delete.setVisible(canDelete); - copy.setEnabled(true); // to clipboard - copyTo.setVisible(true); - copyTo.setEnabled(true); - moveTo.setVisible(true); - moveTo.setEnabled(true); - rename.setVisible(false); - } - - @Override - void onModelLoaded(Model model, @ResultType int resultType, boolean isSearch) {} - - @Override - public boolean enableManagedMode() { - return mState.stack.root != null && mState.stack.root.isDownloads(); - } - } - - /** * Provides support for Files activity specific specializations of DirectoryFragment. */ private static final class FilesTuner extends FragmentTuner { diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java index a4bce1626fb4..c8641a8000f5 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/GridDocumentHolder.java @@ -20,6 +20,7 @@ import static com.android.documentsui.model.DocumentInfo.getCursorInt; import static com.android.documentsui.model.DocumentInfo.getCursorLong; import static com.android.documentsui.model.DocumentInfo.getCursorString; +import android.annotation.ColorInt; import android.content.Context; import android.database.Cursor; import android.net.Uri; @@ -37,6 +38,7 @@ import com.android.documentsui.Shared; import com.android.documentsui.State; final class GridDocumentHolder extends DocumentHolder { + private static boolean mHideTitles; final TextView mTitle; @@ -48,9 +50,13 @@ final class GridDocumentHolder extends DocumentHolder { final ImageView mIconCheck; final IconHelper mIconHelper; + private final @ColorInt int mDisabledBgColor; + public GridDocumentHolder(Context context, ViewGroup parent, IconHelper iconHelper) { super(context, parent, R.layout.item_doc_grid); + mDisabledBgColor = context.getColor(R.color.item_doc_background_disabled); + mTitle = (TextView) itemView.findViewById(android.R.id.title); mDate = (TextView) itemView.findViewById(R.id.date); mSize = (TextView) itemView.findViewById(R.id.size); @@ -64,13 +70,35 @@ final class GridDocumentHolder extends DocumentHolder { @Override public void setSelected(boolean selected) { - super.setSelected(selected); + // We always want to make sure our check box disappears if we're not selected, + // even if the item is disabled. This is because this object can be reused + // and this method will be called to setup initial state. float checkAlpha = selected ? 1f : 0f; - mIconCheck.animate().alpha(checkAlpha).start(); + + // But it should be an error to be set to selected && be disabled. + if (!itemView.isEnabled()) { + assert(!selected); + return; + } + + super.setSelected(selected); + mIconMimeSm.animate().alpha(1f - checkAlpha).start(); } + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + + // Text colors enabled/disabled is handle via a color set. + itemView.setBackgroundColor(enabled ? mDefaultBgColor : mDisabledBgColor); + float imgAlpha = enabled ? 1f : DISABLED_ALPHA; + + mIconMimeLg.setAlpha(imgAlpha); + mIconMimeSm.setAlpha(imgAlpha); + mIconThumb.setAlpha(imgAlpha); + } + /** * Bind this view to the given document for display. * @param cursor Pointing to the item to be bound. @@ -122,12 +150,4 @@ final class GridDocumentHolder extends DocumentHolder { mSize.setText(Formatter.formatFileSize(mContext, docSize)); } } - - /** - * Sets whether to hide titles on subsequently created GridDocumentHolder items. - * @param hideTitles - */ - public static void setHideTitles(boolean hideTitles) { - mHideTitles = hideTitles; - } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java index 0831dbfc14d2..3a1be119896b 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ListDocumentHolder.java @@ -66,14 +66,33 @@ final class ListDocumentHolder extends DocumentHolder { @Override public void setSelected(boolean selected) { - super.setSelected(selected); + // We always want to make sure our check box disappears if we're not selected, + // even if the item is disabled. But it should be an error (see assert below) + // to be set to selected && be disabled. float checkAlpha = selected ? 1f : 0f; - mIconCheck.animate().alpha(checkAlpha).start(); + + if (!itemView.isEnabled()) { + assert(!selected); + return; + } + + super.setSelected(selected); + mIconMime.animate().alpha(1f - checkAlpha).start(); mIconThumb.animate().alpha(1f - checkAlpha).start(); } + @Override + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + + // Text colors enabled/disabled is handle via a color set. + final float imgAlpha = enabled ? 1f : DISABLED_ALPHA; + mIconMime.setAlpha(imgAlpha); + mIconThumb.setAlpha(imgAlpha); + } + /** * Bind this view to the given document for display. * @param cursor Pointing to the item to be bound. @@ -145,12 +164,4 @@ final class ListDocumentHolder extends DocumentHolder { mDetails.setVisibility(hasDetails ? View.VISIBLE : View.GONE); } } - - @Override - public void setEnabled(boolean enabled) { - super.setEnabled(enabled); - final float iconAlpha = enabled ? 1f : 0.5f; - mIconMime.setAlpha(iconAlpha); - mIconThumb.setAlpha(iconAlpha); - } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java index 8170e2ab8fa2..ab4f5c4f90ad 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/Model.java @@ -59,7 +59,7 @@ public class Model { * A sorted array of model IDs for the files currently in the Model. Sort order is determined * by {@link #mSortOrder} */ - private List<String> mIds = new ArrayList<>(); + private String mIds[] = new String[0]; private int mSortOrder = SORT_ORDER_DISPLAY_NAME; @Nullable String info; @@ -108,7 +108,7 @@ public class Model { if (result == null) { mCursor = null; mCursorCount = 0; - mIds.clear(); + mIds = new String[0]; mPositions.clear(); info = null; error = null; @@ -152,7 +152,7 @@ public class Model { */ private void updateModelData() { int[] positions = new int[mCursorCount]; - mIds.clear(); + mIds = new String[mCursorCount]; String[] stringValues = new String[mCursorCount]; long[] longValues = null; @@ -164,7 +164,7 @@ public class Model { for (int pos = 0; pos < mCursorCount; ++pos) { mCursor.moveToNext(); positions[pos] = pos; - mIds.add(createModelId(mCursor)); + mIds[pos] = createModelId(mCursor); switch(mSortOrder) { case SORT_ORDER_DISPLAY_NAME: @@ -201,7 +201,7 @@ public class Model { // Populate the positions. mPositions.clear(); for (int i = 0; i < mCursorCount; ++i) { - mPositions.put(mIds.get(i), positions[i]); + mPositions.put(mIds[i], positions[i]); } } @@ -214,12 +214,12 @@ public class Model { * @param positions Cursor positions to be sorted. * @param ids Model IDs to be sorted. */ - private static void binarySort(String[] sortKey, int[] positions, List<String> ids) { + private static void binarySort(String[] sortKey, int[] positions, String[] ids) { final int count = positions.length; for (int start = 1; start < count; start++) { final int pivotPosition = positions[start]; final String pivotValue = sortKey[start]; - final String pivotId = ids.get(start); + final String pivotId = ids[start]; int left = 0; int right = start; @@ -243,23 +243,21 @@ public class Model { case 2: positions[left + 2] = positions[left + 1]; sortKey[left + 2] = sortKey[left + 1]; - ids.set(left + 2, ids.get(left + 1)); + ids[left + 2] = ids[left + 1]; case 1: positions[left + 1] = positions[left]; sortKey[left + 1] = sortKey[left]; - ids.set(left + 1, ids.get(left)); + ids[left + 1] = ids[left]; break; default: System.arraycopy(positions, left, positions, left + 1, n); System.arraycopy(sortKey, left, sortKey, left + 1, n); - for (int i = n; i >= 1; --i) { - ids.set(left + i, ids.get(left + i - 1)); - } + System.arraycopy(ids, left, ids, left + 1, n); } positions[left] = pivotPosition; sortKey[left] = pivotValue; - ids.set(left, pivotId); + ids[left] = pivotId; } } @@ -275,13 +273,13 @@ public class Model { * @param ids Model IDs to be sorted. */ private static void binarySort( - long[] sortKey, String[] mimeTypes, int[] positions, List<String> ids) { + long[] sortKey, String[] mimeTypes, int[] positions, String[] ids) { final int count = positions.length; for (int start = 1; start < count; start++) { final int pivotPosition = positions[start]; final long pivotValue = sortKey[start]; final String pivotMime = mimeTypes[start]; - final String pivotId = ids.get(start); + final String pivotId = ids[start]; int left = 0; int right = start; @@ -310,7 +308,7 @@ public class Model { // have identical numerical sort keys. One common example of this scenario is seen // when sorting a set of active downloads by mod time. if (compare == 0) { - compare = pivotId.compareTo(ids.get(mid)); + compare = pivotId.compareTo(ids[mid]); } if (compare < 0) { @@ -326,26 +324,24 @@ public class Model { positions[left + 2] = positions[left + 1]; sortKey[left + 2] = sortKey[left + 1]; mimeTypes[left + 2] = mimeTypes[left + 1]; - ids.set(left + 2, ids.get(left + 1)); + ids[left + 2] = ids[left + 1]; case 1: positions[left + 1] = positions[left]; sortKey[left + 1] = sortKey[left]; mimeTypes[left + 1] = mimeTypes[left]; - ids.set(left + 1, ids.get(left)); + ids[left + 1] = ids[left]; break; default: System.arraycopy(positions, left, positions, left + 1, n); System.arraycopy(sortKey, left, sortKey, left + 1, n); System.arraycopy(mimeTypes, left, mimeTypes, left + 1, n); - for (int i = n; i >= 1; --i) { - ids.set(left + i, ids.get(left + i - 1)); - } + System.arraycopy(ids, left, ids, left + 1, n); } positions[left] = pivotPosition; sortKey[left] = pivotValue; mimeTypes[left] = pivotMime; - ids.set(left, pivotId); + ids[left] = pivotId; } } @@ -413,7 +409,7 @@ public class Model { * @return An ordered array of model IDs representing the documents in the model. It is sorted * according to the current sort order, which was set by the last model update. */ - public List<String> getModelIds() { + public String[] getModelIds() { return mIds; } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java index 2b073397f292..149ecdd58565 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java +++ b/packages/DocumentsUI/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapter.java @@ -118,8 +118,13 @@ final class ModelBackedDocumentsAdapter extends DocumentsAdapter { final String docMimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE); final int docFlags = getCursorInt(cursor, Document.COLUMN_FLAGS); + boolean enabled = mEnv.isDocumentEnabled(docMimeType, docFlags); + boolean selected = mEnv.isSelected(modelId); + if (!enabled) { + assert(!selected); + } + holder.setEnabled(enabled); holder.setSelected(mEnv.isSelected(modelId)); - holder.setEnabled(mEnv.isDocumentEnabled(docMimeType, docFlags)); mEnv.onBindDocumentHolder(holder, cursor); } @@ -135,8 +140,8 @@ final class ModelBackedDocumentsAdapter extends DocumentsAdapter { Log.d(TAG, "Updating model with hidden ids: " + mHiddenIds); } - List<String> modelIds = model.getModelIds(); - mModelIds = new ArrayList<>(modelIds.size()); + String[] modelIds = model.getModelIds(); + mModelIds = new ArrayList<>(modelIds.length); for (String id : modelIds) { if (!mHiddenIds.contains(id)) { mModelIds.add(id); diff --git a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java index d74121e536bd..d5327f916bed 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java +++ b/packages/DocumentsUI/src/com/android/documentsui/model/DocumentInfo.java @@ -245,10 +245,6 @@ public class DocumentInfo implements Durable, Parcelable { return (flags & Document.FLAG_SUPPORTS_RENAME) != 0; } - public boolean isGridTitlesHidden() { - return (flags & Document.FLAG_DIR_HIDE_GRID_TITLES) != 0; - } - public boolean isArchive() { return (flags & Document.FLAG_ARCHIVE) != 0; } diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java index ad48a70c4075..9ed2abf9c9b8 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java +++ b/packages/DocumentsUI/src/com/android/documentsui/services/CopyJob.java @@ -299,18 +299,15 @@ class CopyJob extends Job { if ((src.flags & Document.FLAG_SUPPORTS_COPY) != 0) { try { if (DocumentsContract.copyDocument(getClient(src), src.derivedUri, - dstDirInfo.derivedUri) == null) { - throw new ResourceException("Provider side copy failed for document %s.", - src.derivedUri); + dstDirInfo.derivedUri) != null) { + return; } - } catch (ResourceException e) { - throw e; } catch (RemoteException | RuntimeException e) { - throw new ResourceException( - "Provider side copy failed for document %s due to an exception.", - src.derivedUri, e); + Log.e(TAG, "Provider side copy failed for: " + src.derivedUri + + " due to an exception: " + e); } - return; + // If optimized copy fails, then fallback to byte-by-byte copy. + if (DEBUG) Log.d(TAG, "Fallback to byte-by-byte copy for: " + src.derivedUri); } } diff --git a/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java b/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java index dc39235b35c5..aaa7596be014 100644 --- a/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java +++ b/packages/DocumentsUI/src/com/android/documentsui/services/MoveJob.java @@ -16,6 +16,7 @@ package com.android.documentsui.services; +import static com.android.documentsui.Shared.DEBUG; import static com.android.documentsui.services.FileOperationService.OPERATION_MOVE; import android.app.Notification; @@ -24,6 +25,7 @@ import android.content.Context; import android.os.RemoteException; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Document; +import android.util.Log; import com.android.documentsui.R; import com.android.documentsui.model.DocumentInfo; @@ -34,6 +36,8 @@ import java.util.List; // TODO: Stop extending CopyJob. final class MoveJob extends CopyJob { + private static final String TAG = "MoveJob"; + final DocumentInfo mSrcParent; /** @@ -68,7 +72,7 @@ final class MoveJob extends CopyJob { @Override public Notification getProgressNotification() { - return getProgressNotification(R.string.copy_preparing); + return getProgressNotification(R.string.copy_remaining); } @Override @@ -89,16 +93,15 @@ final class MoveJob extends CopyJob { try { if (DocumentsContract.moveDocument(getClient(src), src.derivedUri, srcParent != null ? srcParent.derivedUri : mSrcParent.derivedUri, - dest.derivedUri) == null) { - throw new ResourceException("Provider side move failed for document %s.", - src.derivedUri); + dest.derivedUri) != null) { + return; } - } catch (RuntimeException | RemoteException e) { - throw new ResourceException( - "Provider side move failed for document %s due to an exception.", - src.derivedUri, e); + } catch (RemoteException | RuntimeException e) { + Log.e(TAG, "Provider side move failed for: " + src.derivedUri + + " due to an exception: " + e); } - return; + // If optimized move fails, then fallback to byte-by-byte copy. + if (DEBUG) Log.d(TAG, "Fallback to byte-by-byte move for: " + src.derivedUri); } } 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/DocumentsProviderHelper.java b/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java index af478eafc38e..16ed2d9dee3c 100644 --- a/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java +++ b/packages/DocumentsUI/tests/src/com/android/documentsui/DocumentsProviderHelper.java @@ -106,13 +106,15 @@ public class DocumentsProviderHelper { return createDocument(root.documentId, mimeType, name); } - public Uri createDocumentWithFlags(String documentId, String mimeType, String name, int flags) + public Uri createDocumentWithFlags(String documentId, String mimeType, String name, int flags, + String... streamTypes) throws RemoteException { Bundle in = new Bundle(); in.putInt(StubProvider.EXTRA_FLAGS, flags); in.putString(StubProvider.EXTRA_PARENT_ID, documentId); in.putString(Document.COLUMN_MIME_TYPE, mimeType); in.putString(Document.COLUMN_DISPLAY_NAME, name); + in.putStringArrayList(StubProvider.EXTRA_STREAM_TYPES, Lists.newArrayList(streamTypes)); Bundle out = mClient.call("createDocumentWithFlags", null, in); Uri uri = out.getParcelable(DocumentsContract.EXTRA_URI); diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/DownloadsActivityUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/DownloadsActivityUiTest.java deleted file mode 100644 index 79d7887198b5..000000000000 --- a/packages/DocumentsUI/tests/src/com/android/documentsui/DownloadsActivityUiTest.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.documentsui; - -import static com.android.documentsui.StubProvider.ROOT_0_ID; - -import android.content.Intent; -import android.os.RemoteException; -import android.provider.DocumentsContract; -import android.support.test.uiautomator.By; -import android.support.test.uiautomator.Until; -import android.test.suitebuilder.annotation.LargeTest; - -@LargeTest -public class DownloadsActivityUiTest extends ActivityTest<DownloadsActivity> { - - public DownloadsActivityUiTest() { - super(DownloadsActivity.class); - } - - @Override - void launchActivity() { - final Intent intent = new Intent(DocumentsContract.ACTION_MANAGE_ROOT); - intent.setDataAndType(rootDir0.getUri(), DocumentsContract.Root.MIME_TYPE_ITEM); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK); - setActivityIntent(intent); - getActivity(); // Launch the activity. - } - - @Override - void initTestFiles() throws RemoteException { - mDocsHelper.createDocument(rootDir0, "text/plain", "file0.log"); - mDocsHelper.createDocument(rootDir0, "image/png", "file1.png"); - mDocsHelper.createDocument(rootDir0, "text/csv", "file2.csv"); - } - - public void testWindowTitle() throws Exception { - initTestFiles(); - - bots.main.assertWindowTitle(ROOT_0_ID); - } - - public void testFilesListed() throws Exception { - initTestFiles(); - - bots.directory.assertDocumentsPresent("file0.log", "file1.png", "file2.csv"); - } - - public void testFilesList_LiveUpdate() throws Exception { - initTestFiles(); - - mDocsHelper.createDocument(rootDir0, "yummers/sandwich", "Ham & Cheese.sandwich"); - - bots.directory.waitForDocument("Ham & Cheese.sandwich"); - bots.directory.assertDocumentsPresent( - "file0.log", "file1.png", "file2.csv", "Ham & Cheese.sandwich"); - } - - public void testDeleteDocument() throws Exception { - initTestFiles(); - - bots.directory.clickDocument("file1.png"); - device.waitForIdle(); - bots.main.menuDelete().click(); - - bots.directory.waitForDeleteSnackbar(); - bots.directory.assertDocumentsAbsent("file1.png"); - - bots.directory.waitForDeleteSnackbarGone(); - bots.directory.assertDocumentsAbsent("file1.png"); - } - - public void testSupportsShare() throws Exception { - initTestFiles(); - - bots.directory.clickDocument("file1.png"); - device.waitForIdle(); - assertNotNull(bots.main.menuShare()); - } - - public void testClosesOnBack() throws Exception { - DownloadsActivity activity = getActivity(); - device.pressBack(); - device.wait(Until.gone(By.text(ROOT_0_ID)), TIMEOUT); // wait for the window to go away - assertTrue(activity.isDestroyed()); - } -} diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/FilesActivityUiTest.java index 2486209d777e..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; @@ -72,11 +79,11 @@ public class FilesActivityUiTest extends ActivityTest<FilesActivity> { bots.directory.assertDocumentsPresent("file0.log", "file1.png", "file2.csv"); } - public void testLoadsHomeDirectoryByDefault() throws Exception { + public void testLoadsDownloadsDirectoryByDefault() throws Exception { initTestFiles(); device.waitForIdle(); - bots.main.assertWindowTitle("Documents"); + bots.main.assertWindowTitle("Downloads"); } public void testRootClickSetsWindowTitle() throws Exception { @@ -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/StubProvider.java b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java index 25276505ee43..f71ce5d1b930 100644 --- a/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java +++ b/packages/DocumentsUI/tests/src/com/android/documentsui/StubProvider.java @@ -518,28 +518,29 @@ public class StubProvider extends DocumentsProvider { String rootId = extras.getString(EXTRA_PARENT_ID); String mimeType = extras.getString(Document.COLUMN_MIME_TYPE); String name = extras.getString(Document.COLUMN_DISPLAY_NAME); + List<String> streamTypes = extras.getStringArrayList(EXTRA_STREAM_TYPES); int flags = extras.getInt(EXTRA_FLAGS); Bundle out = new Bundle(); String documentId = null; try { - documentId = createDocument(rootId, mimeType, name, flags); + documentId = createDocument(rootId, mimeType, name, flags, streamTypes); Uri uri = DocumentsContract.buildDocumentUri(mAuthority, documentId); out.putParcelable(DocumentsContract.EXTRA_URI, uri); } catch (FileNotFoundException e) { - Log.d(TAG, "Cretaing document with flags failed" + name); + Log.d(TAG, "Creating document with flags failed" + name); } return out; } - public String createDocument(String parentId, String mimeType, String displayName, int flags) - throws FileNotFoundException { + public String createDocument(String parentId, String mimeType, String displayName, int flags, + List<String> streamTypes) throws FileNotFoundException { StubDocument parent = mStorage.get(parentId); File file = createFile(parent, mimeType, displayName); final StubDocument document = StubDocument.createDocumentWithFlags(file, mimeType, parent, - flags); + flags, streamTypes); mStorage.put(document.documentId, document); Log.d(TAG, "Created document " + document.documentId); notifyParentChanged(document.parentId); @@ -787,8 +788,9 @@ public class StubProvider extends DocumentsProvider { } public static StubDocument createDocumentWithFlags( - File file, String mimeType, StubDocument parent, int flags) { - return new StubDocument(file, mimeType, new ArrayList<String>(), flags, parent); + File file, String mimeType, StubDocument parent, int flags, + List<String> streamTypes) { + return new StubDocument(file, mimeType, streamTypes, flags, parent); } public static StubDocument createVirtualDocument( 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/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java index adc814147336..7ab51ba278c1 100644 --- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java +++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelBackedDocumentsAdapterTest.java @@ -68,8 +68,8 @@ public class ModelBackedDocumentsAdapterTest extends AndroidTestCase { // Tests that the item count is correct. public void testHide_ItemCount() { - List<String> ids = mModel.getModelIds(); - mAdapter.hide(ids.get(0), ids.get(1)); + String[] ids = mModel.getModelIds(); + mAdapter.hide(ids[0], ids[1]); assertEquals(mModel.getItemCount() - 2, mAdapter.getItemCount()); } diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java index 4b0bc41f19fe..c6ad5116d93b 100644 --- a/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java +++ b/packages/DocumentsUI/tests/src/com/android/documentsui/dirlist/ModelTest.java @@ -107,7 +107,7 @@ public class ModelTest extends AndroidTestCase { assertTrue(model.isEmpty()); assertEquals(0, model.getItemCount()); - assertEquals(0, model.getModelIds().size()); + assertEquals(0, model.getModelIds().length); } // Tests that the item count is correct. @@ -165,10 +165,10 @@ public class ModelTest extends AndroidTestCase { // Tests the base case for Model.getItem. public void testGetItem() { - List<String> ids = model.getModelIds(); - assertEquals(ITEM_COUNT, ids.size()); + String[] ids = model.getModelIds(); + assertEquals(ITEM_COUNT, ids.length); for (int i = 0; i < ITEM_COUNT; ++i) { - Cursor c = model.getItem(ids.get(i)); + Cursor c = model.getItem(ids[i]); assertEquals(i, c.getPosition()); } } @@ -292,14 +292,14 @@ public class ModelTest extends AndroidTestCase { r.sortOrder = State.SORT_ORDER_LAST_MODIFIED; model.update(r); - List<String> ids = model.getModelIds(); + String[] ids = model.getModelIds(); // Check that all items were accounted for - assertEquals(ITEM_COUNT + DL_COUNT, ids.size()); + assertEquals(ITEM_COUNT + DL_COUNT, ids.length); // Check that active downloads are sorted to the top. for (int i = 0; i < DL_COUNT; i++) { - assertTrue(currentDownloads.contains(ids.get(i))); + assertTrue(currentDownloads.contains(ids[i])); } } @@ -316,11 +316,11 @@ public class ModelTest extends AndroidTestCase { } private Selection positionToSelection(int... positions) { - List<String> ids = model.getModelIds(); + String[] ids = model.getModelIds(); Selection s = new Selection(); // Construct a selection of the given positions. for (int p: positions) { - s.add(ids.get(p)); + s.add(ids[p]); } return s; } diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java index 543396eec7b5..bb7c01afb65e 100644 --- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java +++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/CopyJobTest.java @@ -16,6 +16,10 @@ package com.android.documentsui.services; +import static com.google.common.collect.Lists.newArrayList; + +import android.net.Uri; +import android.provider.DocumentsContract.Document; import android.test.suitebuilder.annotation.MediumTest; import com.android.documentsui.model.DocumentInfo; @@ -38,6 +42,21 @@ public class CopyJobTest extends AbstractCopyJobTest<CopyJob> { runCopyVirtualNonTypedFileTest(); } + public void testCopy_BackendSideVirtualTypedFile_Fallback() throws Exception { + mDocs.assertChildCount(mDestRoot, 0); + + Uri testFile = mDocs.createDocumentWithFlags( + mSrcRoot.documentId, "virtual/mime-type", "tokyo.sth", + Document.FLAG_VIRTUAL_DOCUMENT | Document.FLAG_SUPPORTS_COPY + | Document.FLAG_SUPPORTS_MOVE, "application/pdf"); + + createJob(newArrayList(testFile)).run(); + + mJobListener.waitForFinished(); + mDocs.assertChildCount(mDestRoot, 1); + mDocs.assertHasFile(mDestRoot, "tokyo.sth.pdf"); // Copy should convert file to PDF. + } + public void testCopyEmptyDir() throws Exception { runCopyEmptyDirTest(); } diff --git a/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java b/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java index 749264a9ada8..24181d62e208 100644 --- a/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java +++ b/packages/DocumentsUI/tests/src/com/android/documentsui/services/MoveJobTest.java @@ -59,6 +59,21 @@ public class MoveJobTest extends AbstractCopyJobTest<MoveJob> { mDocs.assertChildCount(mSrcRoot, 1); } + public void testMove_BackendSideVirtualTypedFile_Fallback() throws Exception { + Uri testFile = mDocs.createDocumentWithFlags( + mSrcRoot.documentId, "virtual/mime-type", "tokyo.sth", + Document.FLAG_VIRTUAL_DOCUMENT | Document.FLAG_SUPPORTS_COPY + | Document.FLAG_SUPPORTS_MOVE, "application/pdf"); + + createJob(newArrayList(testFile)).run(); + mJobListener.waitForFinished(); + + // Should have failed, source not deleted. Moving by bytes for virtual files + // is not supported. + mDocs.assertChildCount(mDestRoot, 0); + mDocs.assertChildCount(mSrcRoot, 1); + } + public void testMoveEmptyDir() throws Exception { runCopyEmptyDirTest(); diff --git a/packages/ExtServices/AndroidManifest.xml b/packages/ExtServices/AndroidManifest.xml index 100b35c13d34..519db66cf910 100644 --- a/packages/ExtServices/AndroidManifest.xml +++ b/packages/ExtServices/AndroidManifest.xml @@ -15,18 +15,27 @@ --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" package="android.ext.services" android:versionCode="1" android:versionName="1" coreApp="true"> <application android:label="@string/app_name" - android:allowBackup="false" android:forceDeviceEncrypted="true" android:encryptionAware="true"> <library android:name="android.ext.services"/> + <service android:name=".notification.Ranker" + android:label="@string/notification_ranker" + android:permission="android.permission.BIND_NOTIFICATION_RANKER_SERVICE" + android:exported="true"> + <intent-filter> + <action android:name="android.service.notification.NotificationRankerService" /> + </intent-filter> + </service> + </application> </manifest> diff --git a/packages/ExtServices/res/values/strings.xml b/packages/ExtServices/res/values/strings.xml index 531e5171dec8..076340341d1f 100644 --- a/packages/ExtServices/res/values/strings.xml +++ b/packages/ExtServices/res/values/strings.xml @@ -16,4 +16,5 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <string name="app_name">Android Services Library</string> + <string name="notification_ranker">Android Notification Ranking Service</string> </resources> diff --git a/packages/ExtServices/src/android/ext/services/notification/Ranker.java b/packages/ExtServices/src/android/ext/services/notification/Ranker.java new file mode 100644 index 000000000000..0b2b1a447b91 --- /dev/null +++ b/packages/ExtServices/src/android/ext/services/notification/Ranker.java @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.ext.services.notification; + +import android.service.notification.NotificationRankerService; +import android.service.notification.StatusBarNotification; +import android.util.Log; + +/** + * Class that provides an updatable ranker module for the notification manager.. + */ +public final class Ranker extends NotificationRankerService { + private static final String TAG = "RocketRanker"; + private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);; + + @Override + public Adjustment onNotificationEnqueued(StatusBarNotification sbn, int importance, + boolean user) { + if (DEBUG) Log.i(TAG, "ENQUEUED " + sbn.getKey()); + return null; + } + + @Override + public void onNotificationPosted(StatusBarNotification sbn) { + if (DEBUG) Log.i(TAG, "POSTED " + sbn.getKey()); + } + + @Override + public void onListenerConnected() { + if (DEBUG) Log.i(TAG, "CONNECTED"); + } +}
\ No newline at end of file diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java index 203d6dc64d41..8c73211cccf1 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabase.java @@ -32,6 +32,7 @@ import android.database.sqlite.SQLiteQueryBuilder; import android.media.MediaFile; import android.mtp.MtpConstants; import android.mtp.MtpObjectInfo; +import android.net.Uri; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Document; import android.provider.DocumentsContract.Root; @@ -40,8 +41,9 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import java.io.FileNotFoundException; -import java.io.IOException; +import java.util.HashSet; import java.util.Objects; +import java.util.Set; /** * Database for MTP objects. @@ -606,7 +608,7 @@ class MtpDatabase { * @param deviceId Device to find documents. * @return Identifier of found document or null. */ - public @Nullable Identifier getUnmappedDocumentsParent(int deviceId) { + @Nullable Identifier getUnmappedDocumentsParent(int deviceId) { final String fromClosure = TABLE_DOCUMENTS + " AS child INNER JOIN " + TABLE_DOCUMENTS + " AS parent ON " + @@ -643,6 +645,65 @@ class MtpDatabase { } } + /** + * Removes metadata except for data used by outgoingPersistedUriPermissions. + */ + void cleanDatabase(Uri[] outgoingPersistedUris) { + mDatabase.beginTransaction(); + try { + final Set<String> ids = new HashSet<>(); + for (final Uri uri : outgoingPersistedUris) { + String documentId = DocumentsContract.getDocumentId(uri); + while (documentId != null) { + if (ids.contains(documentId)) { + break; + } + ids.add(documentId); + try (final Cursor cursor = mDatabase.query( + TABLE_DOCUMENTS, + strings(COLUMN_PARENT_DOCUMENT_ID), + SELECTION_DOCUMENT_ID, + strings(documentId), + null, + null, + null)) { + documentId = cursor.moveToNext() ? cursor.getString(0) : null; + } + } + } + deleteDocumentsAndRoots( + Document.COLUMN_DOCUMENT_ID + " NOT IN " + getIdList(ids), null); + mDatabase.setTransactionSuccessful(); + } finally { + mDatabase.endTransaction(); + } + } + + int getLastBootCount() { + try (final Cursor cursor = mDatabase.query( + TABLE_LAST_BOOT_COUNT, strings(COLUMN_VALUE), null, null, null, null, null)) { + if (cursor.moveToNext()) { + return cursor.getInt(0); + } else { + return 0; + } + } + } + + void setLastBootCount(int value) { + Preconditions.checkArgumentNonnegative(value, "Boot count must not be negative."); + mDatabase.beginTransaction(); + try { + final ContentValues values = new ContentValues(); + values.put(COLUMN_VALUE, value); + mDatabase.delete(TABLE_LAST_BOOT_COUNT, null, null); + mDatabase.insert(TABLE_LAST_BOOT_COUNT, null, values); + mDatabase.setTransactionSuccessful(); + } finally { + mDatabase.endTransaction(); + } + } + private static class OpenHelper extends SQLiteOpenHelper { public OpenHelper(Context context, int flags) { super(context, @@ -655,12 +716,14 @@ class MtpDatabase { public void onCreate(SQLiteDatabase db) { db.execSQL(QUERY_CREATE_DOCUMENTS); db.execSQL(QUERY_CREATE_ROOT_EXTRA); + db.execSQL(QUERY_CREATE_LAST_BOOT_COUNT); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { - db.execSQL("DROP TABLE " + TABLE_DOCUMENTS); - db.execSQL("DROP TABLE " + TABLE_ROOT_EXTRA); + db.execSQL("DROP TABLE IF EXISTS " + TABLE_DOCUMENTS); + db.execSQL("DROP TABLE IF EXISTS " + TABLE_ROOT_EXTRA); + db.execSQL("DROP TABLE IF EXISTS " + TABLE_LAST_BOOT_COUNT); onCreate(db); } } @@ -767,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; } @@ -818,4 +891,16 @@ class MtpDatabase { } return results; } + + private static String getIdList(Set<String> ids) { + String result = "("; + for (final String id : ids) { + if (result.length() > 1) { + result += ","; + } + result += id; + } + result += ")"; + return result; + } } diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java index ff4b89f99e12..6d98e3419de8 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDatabaseConstants.java @@ -30,7 +30,7 @@ import java.util.Map; * Class containing MtpDatabase constants. */ class MtpDatabaseConstants { - static final int DATABASE_VERSION = 4; + static final int DATABASE_VERSION = 5; static final String DATABASE_NAME = "database"; static final int FLAG_DATABASE_IN_MEMORY = 1; @@ -48,6 +48,11 @@ class MtpDatabaseConstants { static final String TABLE_ROOT_EXTRA = "RootExtra"; /** + * Table containing last boot count. + */ + static final String TABLE_LAST_BOOT_COUNT = "LastBootCount"; + + /** * 'FROM' closure of joining TABLE_DOCUMENTS and TABLE_ROOT_EXTRA. */ static final String JOIN_ROOTS = createJoinFromClosure( @@ -62,7 +67,13 @@ class MtpDatabaseConstants { static final String COLUMN_PARENT_DOCUMENT_ID = "parent_document_id"; static final String COLUMN_DOCUMENT_TYPE = "document_type"; static final String COLUMN_ROW_STATE = "row_state"; - static final String COLUMN_MAPPING_KEY = "column_mapping_key"; + static final String COLUMN_MAPPING_KEY = "mapping_key"; + + /** + * Value for TABLE_LAST_BOOT_COUNT. + * Type: INTEGER + */ + static final String COLUMN_VALUE = "value"; /** * The state represents that the row has a valid object handle. @@ -133,6 +144,9 @@ class MtpDatabaseConstants { Root.COLUMN_CAPACITY_BYTES + " INTEGER," + Root.COLUMN_MIME_TYPES + " TEXT NOT NULL);"; + static final String QUERY_CREATE_LAST_BOOT_COUNT = + "CREATE TABLE " + TABLE_LAST_BOOT_COUNT + " (value INTEGER NOT NULL);"; + /** * Map for columns names to provide DocumentContract.Root compatible columns. * @see SQLiteQueryBuilder#setProjectionMap(Map) diff --git a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java index 7211253faea5..d4d45912aecc 100644 --- a/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java +++ b/packages/MtpDocumentsProvider/src/com/android/mtp/MtpDocumentsProvider.java @@ -17,6 +17,7 @@ package com.android.mtp; import android.content.ContentResolver; +import android.content.UriPermission; import android.content.res.AssetFileDescriptor; import android.content.res.Resources; import android.database.Cursor; @@ -25,6 +26,7 @@ import android.graphics.Point; import android.media.MediaFile; import android.mtp.MtpConstants; import android.mtp.MtpObjectInfo; +import android.net.Uri; import android.os.Bundle; import android.os.CancellationSignal; import android.os.ParcelFileDescriptor; @@ -33,6 +35,8 @@ import android.provider.DocumentsContract.Document; import android.provider.DocumentsContract.Root; import android.provider.DocumentsContract; import android.provider.DocumentsProvider; +import android.provider.Settings; +import android.provider.Settings.SettingNotFoundException; import android.util.Log; import com.android.internal.annotations.GuardedBy; @@ -42,6 +46,7 @@ import com.android.mtp.exceptions.BusyDeviceException; import java.io.FileNotFoundException; import java.io.IOException; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -95,6 +100,21 @@ public class MtpDocumentsProvider extends DocumentsProvider { mRootScanner = new RootScanner(mResolver, mMtpManager, mDatabase); mAppFuse = new AppFuse(TAG, new AppFuseCallback()); mIntentSender = new ServiceIntentSender(getContext()); + + // Check boot count and cleans database if it's first time to launch MtpDocumentsProvider + // after booting. + final int bootCount = Settings.Global.getInt(mResolver, Settings.Global.BOOT_COUNT, -1); + final int lastBootCount = mDatabase.getLastBootCount(); + if (bootCount != -1 && bootCount != lastBootCount) { + mDatabase.setLastBootCount(bootCount); + final List<UriPermission> permissions = mResolver.getOutgoingPersistedUriPermissions(); + final Uri[] uris = new Uri[permissions.size()]; + for (int i = 0; i < permissions.size(); i++) { + uris[i] = permissions.get(i).getUri(); + } + mDatabase.cleanDatabase(uris); + } + // TODO: Mount AppFuse on demands. try { mAppFuse.mount(getContext().getSystemService(StorageManager.class)); @@ -122,6 +142,7 @@ public class MtpDocumentsProvider extends DocumentsProvider { mRootScanner = new RootScanner(mResolver, mMtpManager, mDatabase); mAppFuse = new AppFuse(TAG, new AppFuseCallback()); mIntentSender = intentSender; + // TODO: Mount AppFuse on demands. try { mAppFuse.mount(storageManager); diff --git a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java index f9e8225dcb24..b74069ae36bb 100644 --- a/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java +++ b/packages/MtpDocumentsProvider/tests/src/com/android/mtp/MtpDatabaseTest.java @@ -17,8 +17,11 @@ 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; import android.provider.DocumentsContract; import android.provider.DocumentsContract.Document; import android.provider.DocumentsContract.Root; @@ -26,6 +29,7 @@ import android.test.AndroidTestCase; import android.test.suitebuilder.annotation.SmallTest; import java.io.FileNotFoundException; +import java.util.Arrays; import static android.provider.DocumentsContract.Document.*; import static com.android.mtp.MtpDatabase.strings; @@ -1023,6 +1027,99 @@ public class MtpDatabaseTest extends AndroidTestCase { assertFalse(mDatabase.getMapper().stopAddingDocuments(null)); } + public void testSetBootCount() { + assertEquals(0, mDatabase.getLastBootCount()); + mDatabase.setLastBootCount(10); + assertEquals(10, mDatabase.getLastBootCount()); + try { + mDatabase.setLastBootCount(-1); + fail(); + } catch (IllegalArgumentException e) {} + } + + public void testCleanDatabase() throws FileNotFoundException { + // Add tree. + addTestDevice(); + addTestStorage("1"); + mDatabase.getMapper().startAddingDocuments("2"); + mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] { + createDocument(100, "apple.txt", MtpConstants.FORMAT_TEXT, 1024), + createDocument(101, "orange.txt", MtpConstants.FORMAT_TEXT, 1024), + }); + mDatabase.getMapper().stopAddingDocuments("2"); + + // Disconnect the device. + mDatabase.getMapper().startAddingDocuments(null); + mDatabase.getMapper().stopAddingDocuments(null); + + // Clean database. + mDatabase.cleanDatabase(new Uri[] { + DocumentsContract.buildDocumentUri(MtpDocumentsProvider.AUTHORITY, "3") + }); + + // Add tree again. + addTestDevice(); + addTestStorage("1"); + mDatabase.getMapper().startAddingDocuments("2"); + mDatabase.getMapper().putChildDocuments(0, "2", OPERATIONS_SUPPORTED, new MtpObjectInfo[] { + createDocument(100, "apple.txt", MtpConstants.FORMAT_TEXT, 1024), + createDocument(101, "orange.txt", MtpConstants.FORMAT_TEXT, 1024), + }); + mDatabase.getMapper().stopAddingDocuments("2"); + + try (final Cursor cursor = mDatabase.queryChildDocuments( + strings(COLUMN_DOCUMENT_ID, Document.COLUMN_DISPLAY_NAME), "2")) { + assertEquals(2, cursor.getCount()); + + // Persistent uri uses the same ID. + cursor.moveToNext(); + assertEquals("3", cursor.getString(0)); + assertEquals("apple.txt", cursor.getString(1)); + + // Others does not. + cursor.moveToNext(); + assertEquals("5", cursor.getString(0)); + assertEquals("orange.txt", cursor.getString(1)); + } + } + + 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-af/strings.xml b/packages/PrintSpooler/res/values-af/strings.xml index 57ba2b68c69c..c8478f2a8c2f 100644 --- a/packages/PrintSpooler/res/values-af/strings.xml +++ b/packages/PrintSpooler/res/values-af/strings.xml @@ -61,11 +61,17 @@ </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">"Meer inligting oor hierdie drukker"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Sommige drukdienste is gedeaktiveer."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Kies drukdiens"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Sommige drukdienste is gedeaktiveer"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Soek tans vir drukkers"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Geen drukdienste is geaktiveer nie"</string> <string name="print_no_printers" msgid="4869403323900054866">"Geen drukkers gekry nie"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Kan nie drukkers byvoeg nie"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Kies om drukker by te voeg"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Kies om te aktiveer"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Geaktiveerde dienste"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Aanbevole dienste"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Gedeaktiveerde dienste"</string> + <string name="all_services_title" msgid="5578662754874906455">"Alle dienste"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Druk tans <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Kanselleer tans <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Drukkerfout by <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-am/strings.xml b/packages/PrintSpooler/res/values-am/strings.xml index a2182fb54748..d4426cce5145 100644 --- a/packages/PrintSpooler/res/values-am/strings.xml +++ b/packages/PrintSpooler/res/values-am/strings.xml @@ -61,11 +61,17 @@ </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">"ተጨማሪ የዚህ አታሚ መረጃ"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"አንዳንድ የህትመት አገልግሎቶች ተሰናክለዋል።"</string> - <string name="choose_print_service" msgid="3740309762324459694">"የህትመት አገልግሎት ይምረጡ"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"አንዳንድ የህትመት አገልግሎቶች ተሰናክለዋል"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"አታሚዎችን በመፈለግ ላይ"</string> <string name="print_no_print_services" msgid="8561247706423327966">"ምንም የህትመት አገልግሎቶች አልነቁም"</string> <string name="print_no_printers" msgid="4869403323900054866">"ምንም አታሚዎች አልተገኙም"</string> + <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="recommended_services_title" msgid="3799434882937956924">"የሚመከሩ አገልግሎቶች"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"የተሰናከሉ አገልግሎቶች"</string> + <string name="all_services_title" msgid="5578662754874906455">"ሁሉም አገልግሎቶች"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ን በማተም ላይ"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ን በመተው ላይ"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"የአታሚ ስህተት <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ar/strings.xml b/packages/PrintSpooler/res/values-ar/strings.xml index eab1339a4d21..2e1b6d0fa2ed 100644 --- a/packages/PrintSpooler/res/values-ar/strings.xml +++ b/packages/PrintSpooler/res/values-ar/strings.xml @@ -65,11 +65,17 @@ </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">"مزيد من المعلومات حول هذه الطابعة"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"بعض خدمات الطباعة معطَّلة."</string> - <string name="choose_print_service" msgid="3740309762324459694">"اختر خدمة طباعة"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"بعض خدمات الطباعة معطَّلة"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"البحث عن طابعات"</string> <string name="print_no_print_services" msgid="8561247706423327966">"لم يتم تمكين أي خدمات طباعة"</string> <string name="print_no_printers" msgid="4869403323900054866">"لم يتم العثور على طابعات"</string> + <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="recommended_services_title" msgid="3799434882937956924">"الخدمات الموصى بها"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"الخدمات المعطَّلة"</string> + <string name="all_services_title" msgid="5578662754874906455">"جميع الخدمات"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"جارٍ طباعة <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"جارٍ إلغاء <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"خطا في الطابعة <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-az-rAZ/strings.xml b/packages/PrintSpooler/res/values-az-rAZ/strings.xml index bff477d53454..5490b84366a1 100644 --- a/packages/PrintSpooler/res/values-az-rAZ/strings.xml +++ b/packages/PrintSpooler/res/values-az-rAZ/strings.xml @@ -61,11 +61,17 @@ </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">"Bu printer haqqında daha ətraflı məlumat"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Bəzi çap xidmətləri deaktiv edilib."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Çap xidmətini seçin"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Bəzi çap xidmətləri deaktiv edilib."</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Printer axtarılır"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Heç bir çap xidməti aktiv edilməyib"</string> <string name="print_no_printers" msgid="4869403323900054866">"Heç bir printer tapılmadı"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Printerlər əlavə edilmədi"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Printer əlavə etmək üçün seçin"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Aktiv etmək üçün seçin"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Aktiv edilmiş xidmətlər"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Tövsiyə olunan xidmətlər"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Deaktiv edilmiş xidmətlər"</string> + <string name="all_services_title" msgid="5578662754874906455">"Bütün xidmətlər"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> çap edilir"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ləğv edilir"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printer xətası <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml index b28aa29304c0..0574dae2022b 100644 --- a/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml +++ b/packages/PrintSpooler/res/values-b+sr+Latn/strings.xml @@ -62,11 +62,17 @@ </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">"Još informacija o ovom štampaču"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Neke usluge štampanja su onemogućene."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Izaberite uslugu štampanja"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Neke usluge štampanja su onemogućene"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Pretraga štampača"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Nijedna usluga štampanja nije omogućena"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nije pronađen nijedan štampač"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Nije moguće dodati štampače"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Izaberite da biste dodali štampač"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Izaberite da biste omogućili"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Omogućene usluge"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Preporučene usluge"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Onemogućene usluge"</string> + <string name="all_services_title" msgid="5578662754874906455">"Sve usluge"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Štampa se <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Otkazuje se <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Greška štampača <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-bg/strings.xml b/packages/PrintSpooler/res/values-bg/strings.xml index e8de8ea96e90..88af8e44eeb1 100644 --- a/packages/PrintSpooler/res/values-bg/strings.xml +++ b/packages/PrintSpooler/res/values-bg/strings.xml @@ -61,11 +61,17 @@ </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">"Още информация за този принтер"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Някои услуги за отпечатване са деактивирани."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Избиране на услуга за отпечатване"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Някои услуги за отпечатване са деактивирани"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Търсене на принтери"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Няма активирани услуги за отпечатване"</string> <string name="print_no_printers" msgid="4869403323900054866">"Няма намерени принтери"</string> + <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="recommended_services_title" msgid="3799434882937956924">"Препоръчителни услуги"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Деактивирани услуги"</string> + <string name="all_services_title" msgid="5578662754874906455">"Всички услуги"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"„<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“ се отпечатва"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"„<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“ се анулира"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Грешка в принтера при „<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>“"</string> diff --git a/packages/PrintSpooler/res/values-bn-rBD/strings.xml b/packages/PrintSpooler/res/values-bn-rBD/strings.xml index a1ca4945327a..c61ef742ca77 100644 --- a/packages/PrintSpooler/res/values-bn-rBD/strings.xml +++ b/packages/PrintSpooler/res/values-bn-rBD/strings.xml @@ -16,7 +16,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <string name="app_label" msgid="4469836075319831821">"মুদ্রণ স্পোলার"</string> + <string name="app_label" msgid="4469836075319831821">"প্রিন্ট স্পোলার"</string> <string name="more_options_button" msgid="2243228396432556771">"আরো বিকল্প"</string> <string name="label_destination" msgid="9132510997381599275">"গন্তব্য"</string> <string name="label_copies" msgid="3634531042822968308">"প্রতিলিপিগুলি"</string> @@ -31,22 +31,22 @@ <string name="template_all_pages" msgid="3322235982020148762">"সমস্ত <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string> <string name="template_page_range" msgid="428638530038286328">"<xliff:g id="PAGE_COUNT">%1$s</xliff:g> এর পরিসর"</string> <string name="pages_range_example" msgid="8558694453556945172">"যেমন, ১—৫,৮,১১—১৩"</string> - <string name="print_preview" msgid="8010217796057763343">"মুদ্রণ পূর্বরূপ"</string> + <string name="print_preview" msgid="8010217796057763343">"প্রিন্ট পূর্বরূপ"</string> <string name="install_for_print_preview" msgid="6366303997385509332">"পূর্বরূপ দেখার জন্য PDF ভিউয়ার ইনস্টল করুন"</string> - <string name="printing_app_crashed" msgid="854477616686566398">"মুদ্রণ অ্যাপ্লিকেশান ক্র্যাশ করছে"</string> - <string name="generating_print_job" msgid="3119608742651698916">"মুদ্রণ কার্য তৈরি করা হচ্ছে"</string> + <string name="printing_app_crashed" msgid="854477616686566398">"প্রিন্ট অ্যাপ্লিকেশান ক্র্যাশ করছে"</string> + <string name="generating_print_job" msgid="3119608742651698916">"প্রিন্ট কার্য তৈরি করা হচ্ছে"</string> <string name="save_as_pdf" msgid="5718454119847596853">"PDF হিসাবে সংরক্ষণ করুন"</string> <string name="all_printers" msgid="5018829726861876202">"সমস্ত মুদ্রক…"</string> - <string name="print_dialog" msgid="32628687461331979">"মুদ্রণ ডায়লগ"</string> + <string name="print_dialog" msgid="32628687461331979">"প্রিন্ট ডায়লগ"</string> <string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string> <string name="page_description_template" msgid="6831239682256197161">"<xliff:g id="PAGE_COUNT">%2$d</xliff:g>টির মধ্যে <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> নম্বর পৃষ্ঠা"</string> <string name="summary_template" msgid="8899734908625669193">"সারাংশ, <xliff:g id="COPIES">%1$s</xliff:g>টি অনুলিপি, কাগজের আকার <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string> <string name="expand_handle" msgid="7282974448109280522">"প্রসারিত করার হ্যান্ডেল"</string> <string name="collapse_handle" msgid="6886637989442507451">"সঙ্কুচিত করার হ্যান্ডেল"</string> - <string name="print_button" msgid="645164566271246268">"মুদ্রণ করুন"</string> + <string name="print_button" msgid="645164566271246268">"প্রিন্ট করুন"</string> <string name="savetopdf_button" msgid="2976186791686924743">"PDF হিসাবে সংরক্ষণ করুন"</string> - <string name="print_options_expanded" msgid="6944679157471691859">"মুদ্রণ বিকল্প প্রসারিত হয়েছে"</string> - <string name="print_options_collapsed" msgid="7455930445670414332">"মুদ্রণ বিকল্প সংকুচিত হয়েছে"</string> + <string name="print_options_expanded" msgid="6944679157471691859">"প্রিন্ট বিকল্প প্রসারিত হয়েছে"</string> + <string name="print_options_collapsed" msgid="7455930445670414332">"প্রিন্ট বিকল্প সংকুচিত হয়েছে"</string> <string name="search" msgid="5421724265322228497">"অনুসন্ধান করুন"</string> <string name="all_printers_label" msgid="3178848870161526399">"সমস্ত মুদ্রক"</string> <string name="add_print_service_label" msgid="5356702546188981940">"পরিষেবা যোগ করুন"</string> @@ -61,12 +61,18 @@ </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">"এই মুদ্রকটির বিষয়ে আরো তথ্য"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"কিছু মুদ্রণ পরিষেবা অক্ষম করা হয়েছে৷"</string> - <string name="choose_print_service" msgid="3740309762324459694">"মুদ্রণ পরিষেবা চয়ন করুন"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"কিছু মুদ্রণ পরিষেবা অক্ষম করা আছে"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"মুদ্রকগুলি অনুসন্ধান করা হচ্ছে"</string> - <string name="print_no_print_services" msgid="8561247706423327966">"মুদ্রণ পরিষেবা সক্ষম নেই"</string> + <string name="print_no_print_services" msgid="8561247706423327966">"প্রিন্ট পরিষেবা সক্ষম নেই"</string> <string name="print_no_printers" msgid="4869403323900054866">"কোনো মুদ্রক পাওয়া যায়নি"</string> - <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> মুদ্রণ করা হচ্ছে"</string> + <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="recommended_services_title" msgid="3799434882937956924">"প্রস্তাবিত পরিষেবাগুলি"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"অক্ষম করা পরিষেবাগুলি"</string> + <string name="all_services_title" msgid="5578662754874906455">"সমস্ত পরিষেবা"</string> + <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> প্রিন্ট করা হচ্ছে"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> বাতিল করা হচ্ছে"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> মুদ্রক ত্রুটি"</string> <string name="blocked_notification_title_template" msgid="1175435827331588646">"মুদ্রক <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> অবরুদ্ধ করেছে"</string> diff --git a/packages/PrintSpooler/res/values-bs-rBA/strings.xml b/packages/PrintSpooler/res/values-bs-rBA/strings.xml new file mode 100644 index 000000000000..7465c3c74cc3 --- /dev/null +++ b/packages/PrintSpooler/res/values-bs-rBA/strings.xml @@ -0,0 +1,105 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- 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. + --> + +<resources xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <string name="app_label" msgid="4469836075319831821">"Štampanje na čekanju"</string> + <string name="more_options_button" msgid="2243228396432556771">"Više opcija"</string> + <string name="label_destination" msgid="9132510997381599275">"Odredište"</string> + <string name="label_copies" msgid="3634531042822968308">"Kopije"</string> + <string name="label_copies_summary" msgid="3861966063536529540">"Primjeraka:"</string> + <string name="label_paper_size" msgid="908654383827777759">"Veličina papira"</string> + <string name="label_paper_size_summary" msgid="5668204981332138168">"Veličina papira:"</string> + <string name="label_color" msgid="1108690305218188969">"U boji"</string> + <string name="label_duplex" msgid="5370037254347072243">"Dvostrano"</string> + <string name="label_orientation" msgid="2853142581990496477">"Orijentacija"</string> + <string name="label_pages" msgid="7768589729282182230">"Stranicā"</string> + <string name="destination_default_text" msgid="5422708056807065710">"Odaberite štampač"</string> + <string name="template_all_pages" msgid="3322235982020148762">"Sve stranice (<xliff:g id="PAGE_COUNT">%1$s</xliff:g>)"</string> + <string name="template_page_range" msgid="428638530038286328">"Opseg od <xliff:g id="PAGE_COUNT">%1$s</xliff:g>"</string> + <string name="pages_range_example" msgid="8558694453556945172">"npr. 1—5,8,11—13"</string> + <string name="print_preview" msgid="8010217796057763343">"Pregled prije štampanja"</string> + <string name="install_for_print_preview" msgid="6366303997385509332">"Instaliraj PDF preglednik za prikaz"</string> + <string name="printing_app_crashed" msgid="854477616686566398">"Aplikacija za štampanje je prestala raditi"</string> + <string name="generating_print_job" msgid="3119608742651698916">"Kreiranje zadatka za štampu"</string> + <string name="save_as_pdf" msgid="5718454119847596853">"Sačuvaj kao PDF"</string> + <string name="all_printers" msgid="5018829726861876202">"Svi štampači…"</string> + <string name="print_dialog" msgid="32628687461331979">"Dijaloški okvir za štampanje"</string> + <string name="current_page_template" msgid="1386638343571771292">"<xliff:g id="CURRENT_PAGE">%1$d</xliff:g> /<xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string> + <string name="page_description_template" msgid="6831239682256197161">"Strana <xliff:g id="CURRENT_PAGE">%1$d</xliff:g> od <xliff:g id="PAGE_COUNT">%2$d</xliff:g>"</string> + <string name="summary_template" msgid="8899734908625669193">"Rezime, primjeraka <xliff:g id="COPIES">%1$s</xliff:g>, veličina papira <xliff:g id="PAPER_SIZE">%2$s</xliff:g>"</string> + <string name="expand_handle" msgid="7282974448109280522">"Regulator za proširivanje"</string> + <string name="collapse_handle" msgid="6886637989442507451">"Regulator za skupljanje"</string> + <string name="print_button" msgid="645164566271246268">"Štampaj"</string> + <string name="savetopdf_button" msgid="2976186791686924743">"Sačuvaj u PDF"</string> + <string name="print_options_expanded" msgid="6944679157471691859">"Opcije za štampanje su proširene"</string> + <string name="print_options_collapsed" msgid="7455930445670414332">"Opcije za štampanje su skupljene"</string> + <string name="search" msgid="5421724265322228497">"Traži"</string> + <string name="all_printers_label" msgid="3178848870161526399">"Svi štampači"</string> + <string name="add_print_service_label" msgid="5356702546188981940">"Dodaj uslugu"</string> + <string name="print_search_box_shown_utterance" msgid="7967404953901376090">"Okvir za pretraživanje je prikazan"</string> + <string name="print_search_box_hidden_utterance" msgid="5727755169343113351">"Okvir za pretraživanje je skriven"</string> + <string name="print_add_printer" msgid="1088656468360653455">"Dodaj štampač"</string> + <string name="print_select_printer" msgid="7388760939873368698">"Izaberite štampač"</string> + <string name="print_forget_printer" msgid="5035287497291910766">"Zaboravi ovaj štampač"</string> + <plurals name="print_search_result_count_utterance" formatted="false" msgid="6997663738361080868"> + <item quantity="one"><xliff:g id="COUNT_1">%1$s</xliff:g> štampač je pronađen</item> + <item quantity="few"><xliff:g id="COUNT_1">%1$s</xliff:g> štampača su pronađena</item> + <item quantity="other"><xliff:g id="COUNT_1">%1$s</xliff:g> štampača je pronađeno</item> + </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">"Više informacija o ovom štampaču"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Neke usluge za štampanje su isključene"</string> + <string name="print_searching_for_printers" msgid="6550424555079932867">"Traženje štampača"</string> + <string name="print_no_print_services" msgid="8561247706423327966">"Usluga za štampanje nije uključena"</string> + <string name="print_no_printers" msgid="4869403323900054866">"Nijedan štampač nije pronađen"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Ne mogu se dodati štampači"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Odaberite da biste dodali štampač"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Odaberite da biste uključili"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Uključene usluge"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Preporučene usluge"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Isključene usluge"</string> + <string name="all_services_title" msgid="5578662754874906455">"Sve usluge"</string> + <string name="printing_notification_title_template" msgid="295903957762447362">"Štampa se <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> + <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Otkazivanje <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> + <string name="failed_notification_title_template" msgid="2256217208186530973">"Greška pri štampanju <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> + <string name="blocked_notification_title_template" msgid="1175435827331588646">"Štampač je blokirao <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> + <string name="cancel" msgid="4373674107267141885">"Otkaži"</string> + <string name="restart" msgid="2472034227037808749">"Ponovo pokreni"</string> + <string name="no_connection_to_printer" msgid="2159246915977282728">"Nema konekcije sa štampačem"</string> + <string name="reason_unknown" msgid="5507940196503246139">"nepoznat"</string> + <string name="printer_unavailable" msgid="2434170617003315690">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> – nedostupan"</string> + <string name="print_service_security_warning_title" msgid="2160752291246775320">"Zaista želite koristiti uslugu <xliff:g id="SERVICE">%1$s</xliff:g>?"</string> + <string name="print_service_security_warning_summary" msgid="1427434625361692006">"Moguće je da dokument prije štampanja prođe kroz jedan ili više servera."</string> + <string-array name="color_mode_labels"> + <item msgid="7602948745415174937">"Crno-bijela"</item> + <item msgid="2762241247228983754">"U boji"</item> + </string-array> + <string-array name="duplex_mode_labels"> + <item msgid="3882302912790928315">"Nije podržano"</item> + <item msgid="7296563835355641719">"Po dužoj strani"</item> + <item msgid="79513688117503758">"Po kraćoj strani"</item> + </string-array> + <string-array name="orientation_labels"> + <item msgid="4061931020926489228">"Uspravno"</item> + <item msgid="3199660090246166812">"Vodoravno"</item> + </string-array> + <string name="print_write_error_message" msgid="5787642615179572543">"Nije moguće pisati u fajl"</string> + <string name="print_error_default_message" msgid="8602678405502922346">"Nažalost, nije uspjelo. Pokušajte ponovo."</string> + <string name="print_error_retry" msgid="1426421728784259538">"Ponovi"</string> + <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Štampač trenutno nije dostupan."</string> + <string name="print_preparing_preview" msgid="3939930735671364712">"Priprema pregleda..."</string> +</resources> diff --git a/packages/PrintSpooler/res/values-ca/strings.xml b/packages/PrintSpooler/res/values-ca/strings.xml index aa6f9925fda5..482100a4b83f 100644 --- a/packages/PrintSpooler/res/values-ca/strings.xml +++ b/packages/PrintSpooler/res/values-ca/strings.xml @@ -61,11 +61,17 @@ </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">"Més informació sobre aquesta impressora"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Hi ha serveis d\'impressió que estan desactivats."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Selecció del servei d\'impressió"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Alguns serveis d\'impressió estan desactivats"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Cerca d\'impressores"</string> <string name="print_no_print_services" msgid="8561247706423327966">"No hi ha cap servei d\'impressió activat"</string> <string name="print_no_printers" msgid="4869403323900054866">"No s\'ha trobat cap impressora"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"No poden afegir impressores"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Selecciona per afegir una impressora"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Selecciona\'ls per activar-los"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Serveis activats"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Serveis recomanats"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Serveis desactivats"</string> + <string name="all_services_title" msgid="5578662754874906455">"Tots els serveis"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"S\'està imprimint <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"S\'està cancel·lant <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Error d\'impressora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-cs/strings.xml b/packages/PrintSpooler/res/values-cs/strings.xml index 4bc22d40a1be..a4c412c67d0f 100644 --- a/packages/PrintSpooler/res/values-cs/strings.xml +++ b/packages/PrintSpooler/res/values-cs/strings.xml @@ -63,11 +63,17 @@ </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">"Další informace o této tiskárně"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Některé tiskové služby nejsou aktivovány."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Zvolte službu tisku"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Některé tiskové služby nejsou aktivovány"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Vyhledávání tiskáren"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Nejsou aktivovány žádné tiskové služby"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nebyly nalezeny žádné tiskárny"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Tiskárny nelze přidat"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Výběrem přidáte tiskárnu"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Výběrem službu aktivujete"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Aktivované služby"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Doporučené služby"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Deaktivované služby"</string> + <string name="all_services_title" msgid="5578662754874906455">"Všechny služby"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Tisk úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Rušení úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Chyba tiskárny u úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-da/strings.xml b/packages/PrintSpooler/res/values-da/strings.xml index b8be624169e4..9ee252167605 100644 --- a/packages/PrintSpooler/res/values-da/strings.xml +++ b/packages/PrintSpooler/res/values-da/strings.xml @@ -61,11 +61,17 @@ </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">"Flere oplysninger om denne printer"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Nogle udskrivningstjenester er deaktiveret."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Vælg udskriftstjeneste"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Nogle udskrivningstjenester er deaktiveret"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Søger efter printere"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Ingen udskrivningstjenester er aktiveret"</string> <string name="print_no_printers" msgid="4869403323900054866">"Der blev ikke fundet nogen printere"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Der kan ikke tilføjes printere"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Vælg for at tilføje en printer"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Vælg for at aktivere"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Aktiverede tjenester"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Anbefalede tjenester"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Deaktiverede tjenester"</string> + <string name="all_services_title" msgid="5578662754874906455">"Alle tjenester"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> udskrives"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> annulleres"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Udskriften <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> mislykkedes"</string> diff --git a/packages/PrintSpooler/res/values-de/strings.xml b/packages/PrintSpooler/res/values-de/strings.xml index bcb7e73d7bd9..ef451b7abf14 100644 --- a/packages/PrintSpooler/res/values-de/strings.xml +++ b/packages/PrintSpooler/res/values-de/strings.xml @@ -61,11 +61,17 @@ </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">"Weitere Informationen über diesen Drucker"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Einige Druckdienste sind deaktiviert."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Druckdienst auswählen"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Einige Druckdienste sind deaktiviert"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Suche nach Druckern"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Keine Druckdienste aktiviert"</string> <string name="print_no_printers" msgid="4869403323900054866">"Keine Drucker gefunden"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Hinzufügen von Druckern nicht möglich"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Auswählen, um Drucker hinzuzufügen"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Zum Aktivieren auswählen"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Aktivierte Dienste"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Empfohlene Dienste"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Deaktivierte Dienste"</string> + <string name="all_services_title" msgid="5578662754874906455">"Alle Dienste"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> wird gedruckt..."</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> wird abgebrochen..."</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Druckerfehler <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-el/strings.xml b/packages/PrintSpooler/res/values-el/strings.xml index d9a4aeba4ed6..9be81c1f2280 100644 --- a/packages/PrintSpooler/res/values-el/strings.xml +++ b/packages/PrintSpooler/res/values-el/strings.xml @@ -61,11 +61,17 @@ </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">"Περισσότερες πληροφορίες σχετικά με αυτόν τον εκτυπωτή"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Κάποιες υπηρ. εκτύπωσης είναι απενεργοποιημένες."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Επιλέξτε υπηρεσία εκτύπωσης"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Ορισμένες υπηρ. εκτύπωσης είναι απενεργοποιημένες"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Αναζήτηση για εκτυπωτές"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Δεν έχουν ενεργοποιηθεί υπηρεσίες εκτύπωσης"</string> <string name="print_no_printers" msgid="4869403323900054866">"Δεν βρέθηκαν εκτυπωτές"</string> + <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="recommended_services_title" msgid="3799434882937956924">"Προτεινόμενες υπηρεσίες"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Υπηρεσίες για άτομα με αναπηρία"</string> + <string name="all_services_title" msgid="5578662754874906455">"Όλες οι υπηρεσίες"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Εκτύπωση <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Ακύρωση <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Σφάλμα εκτυπωτή <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-en-rAU/strings.xml b/packages/PrintSpooler/res/values-en-rAU/strings.xml index d8a94372938f..8b580116f5f4 100644 --- a/packages/PrintSpooler/res/values-en-rAU/strings.xml +++ b/packages/PrintSpooler/res/values-en-rAU/strings.xml @@ -61,11 +61,17 @@ </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">"More information about this printer"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Some print services are disabled."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Choose print service"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Some print services are disabled"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Searching for printers"</string> <string name="print_no_print_services" msgid="8561247706423327966">"No print services enabled"</string> <string name="print_no_printers" msgid="4869403323900054866">"No printers found"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Cannot add printers"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Select to add printer"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Select to enable"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Enabled services"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Recommended services"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Disabled services"</string> + <string name="all_services_title" msgid="5578662754874906455">"All services"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printer error <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-en-rGB/strings.xml b/packages/PrintSpooler/res/values-en-rGB/strings.xml index d8a94372938f..8b580116f5f4 100644 --- a/packages/PrintSpooler/res/values-en-rGB/strings.xml +++ b/packages/PrintSpooler/res/values-en-rGB/strings.xml @@ -61,11 +61,17 @@ </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">"More information about this printer"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Some print services are disabled."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Choose print service"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Some print services are disabled"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Searching for printers"</string> <string name="print_no_print_services" msgid="8561247706423327966">"No print services enabled"</string> <string name="print_no_printers" msgid="4869403323900054866">"No printers found"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Cannot add printers"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Select to add printer"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Select to enable"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Enabled services"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Recommended services"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Disabled services"</string> + <string name="all_services_title" msgid="5578662754874906455">"All services"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printer error <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-en-rIN/strings.xml b/packages/PrintSpooler/res/values-en-rIN/strings.xml index d8a94372938f..8b580116f5f4 100644 --- a/packages/PrintSpooler/res/values-en-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-en-rIN/strings.xml @@ -61,11 +61,17 @@ </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">"More information about this printer"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Some print services are disabled."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Choose print service"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Some print services are disabled"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Searching for printers"</string> <string name="print_no_print_services" msgid="8561247706423327966">"No print services enabled"</string> <string name="print_no_printers" msgid="4869403323900054866">"No printers found"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Cannot add printers"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Select to add printer"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Select to enable"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Enabled services"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Recommended services"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Disabled services"</string> + <string name="all_services_title" msgid="5578662754874906455">"All services"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Printing <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelling <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printer error <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-es-rUS/strings.xml b/packages/PrintSpooler/res/values-es-rUS/strings.xml index 19cbee7e0ae2..8fa609416899 100644 --- a/packages/PrintSpooler/res/values-es-rUS/strings.xml +++ b/packages/PrintSpooler/res/values-es-rUS/strings.xml @@ -61,11 +61,17 @@ </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">"Más información sobre esta impresora"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Hay servicios de impresión inhabilitados."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Elegir servicio de impresión"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Hay servicios de impresión inhabilitados"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Buscando impresoras"</string> <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 es posible agregar impresoras"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Seleccionar para agregar impresoras"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Seleccionar 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> + <string name="all_services_title" msgid="5578662754874906455">"Todos los servicios"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimiendo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Error de impresora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-es/strings.xml b/packages/PrintSpooler/res/values-es/strings.xml index d13ccda2bff2..dba0491fe70a 100644 --- a/packages/PrintSpooler/res/values-es/strings.xml +++ b/packages/PrintSpooler/res/values-es/strings.xml @@ -61,11 +61,17 @@ </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">"Más información sobre esta impresora"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Algunos servicios de impresión están inhabilitados."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Seleccionar servicio de impresión"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Algunos servicios de impresión están inhabilitados"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Buscando impresoras"</string> <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">"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> + <string name="all_services_title" msgid="5578662754874906455">"Todos los servicios"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimiendo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Error de impresora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> @@ -91,7 +97,7 @@ <item msgid="3199660090246166812">"Horizontal"</item> </string-array> <string name="print_write_error_message" msgid="5787642615179572543">"Error al escribir en el archivo"</string> - <string name="print_error_default_message" msgid="8602678405502922346">"No ha funcionado. Repítelo."</string> + <string name="print_error_default_message" msgid="8602678405502922346">"No ha funcionado. Prueba de nuevo."</string> <string name="print_error_retry" msgid="1426421728784259538">"Reintentar"</string> <string name="print_error_printer_unavailable" msgid="8985614415253203381">"Esta impresora no está disponible en este momento."</string> <string name="print_preparing_preview" msgid="3939930735671364712">"Preparando vista previa…"</string> diff --git a/packages/PrintSpooler/res/values-et-rEE/strings.xml b/packages/PrintSpooler/res/values-et-rEE/strings.xml index f03eb37588ad..6dde083d29fd 100644 --- a/packages/PrintSpooler/res/values-et-rEE/strings.xml +++ b/packages/PrintSpooler/res/values-et-rEE/strings.xml @@ -61,11 +61,17 @@ </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">"Lisateave selle printeri kohta"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Mõned printimisteenused on keelatud."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Prinditeenuse valimine"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Mõned printimisteenused on keelatud"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Printerite otsimine"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Ühtegi printimisteenust pole lubatud"</string> <string name="print_no_printers" msgid="4869403323900054866">"Printereid ei leitud"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Printereid ei saa lisada"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Valige printeri lisamiseks"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Valige lubamiseks"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Lubatud teenused"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Soovitatud teenused"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Keelatud teenused"</string> + <string name="all_services_title" msgid="5578662754874906455">"Kõik teenused"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Prinditöö <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> printimine"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Prinditöö <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> tühistamine"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printeri viga: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-eu-rES/strings.xml b/packages/PrintSpooler/res/values-eu-rES/strings.xml index d4255e29b409..858444b4a2ba 100644 --- a/packages/PrintSpooler/res/values-eu-rES/strings.xml +++ b/packages/PrintSpooler/res/values-eu-rES/strings.xml @@ -61,11 +61,17 @@ </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">"Informazio gehiago inprimagailuari buruz"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Desgaituta daude inprimatzeko zerbitzu batzuk."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Aukeratu inprimatze-zerbitzua"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Desgaituta daude inprimatzeko zerbitzu batzuk"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Inprimagailuak bilatzen"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Ez dago gaituta inprimatzeko zerbitzurik"</string> <string name="print_no_printers" msgid="4869403323900054866">"Ez da inprimagailurik aurkitu"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Ezin da gehitu inprimagailurik"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Hautatu inprimagailua gehitzeko"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Hautatu gehitzeko"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Gaitutako zerbitzuak"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Gomendatutako zerbitzuak"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Desgaitutako zerbitzuak"</string> + <string name="all_services_title" msgid="5578662754874906455">"Zerbitzu guztiak"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> inprimatzen"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> bertan behera uzten"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Errorea <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> inprimatzean"</string> diff --git a/packages/PrintSpooler/res/values-fa/strings.xml b/packages/PrintSpooler/res/values-fa/strings.xml index 907123c0c753..7c69c27910a0 100644 --- a/packages/PrintSpooler/res/values-fa/strings.xml +++ b/packages/PrintSpooler/res/values-fa/strings.xml @@ -61,11 +61,17 @@ </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">"اطلاعات بیشتر درباره چاپگر"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"بعضی از خدمات چاپ غیرفعال هستند."</string> - <string name="choose_print_service" msgid="3740309762324459694">"انتخاب سرویس چاپ"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"بعضی از خدمات چاپ غیرفعال هستند"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"درحال جستجوی چاپگرها"</string> <string name="print_no_print_services" msgid="8561247706423327966">"هیچ خدمات چاپی فعال نیست"</string> <string name="print_no_printers" msgid="4869403323900054866">"هیچ چاپگری یافت نشد"</string> + <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="recommended_services_title" msgid="3799434882937956924">"خدمات توصیهشده"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"خدمات غیرفعال"</string> + <string name="all_services_title" msgid="5578662754874906455">"همه خدمات"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"در حال چاپ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"در حال لغو <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"خطای چاپگر <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-fi/strings.xml b/packages/PrintSpooler/res/values-fi/strings.xml index f57b8843a72f..dfd98f87a217 100644 --- a/packages/PrintSpooler/res/values-fi/strings.xml +++ b/packages/PrintSpooler/res/values-fi/strings.xml @@ -61,11 +61,17 @@ </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">"Lisätietoja tästä tulostimesta"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Osa tulostuspalveluista on poistettu käytöstä."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Valitse tulostuspalvelu"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Osa tulostuspalveluista on poistettu käytöstä."</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Etsitään tulostimia"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Ei käytössä olevia tulostuspalveluita"</string> <string name="print_no_printers" msgid="4869403323900054866">"Tulostimia ei löydy"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Tulostimien lisääminen ei onnistu."</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Valitse palvelu tulostimen lisäämistä varten."</string> + <string name="enable_print_service" msgid="3482815747043533842">"Valitse käyttöön otettavat palvelut."</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Käytössä olevat palvelut"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Suositellut palvelut"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Käytöstä poistetut palvelut"</string> + <string name="all_services_title" msgid="5578662754874906455">"Kaikki palvelut"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Tulostetaan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Peruutetaan työ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Tulostinvirhe työlle <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-fr-rCA/strings.xml b/packages/PrintSpooler/res/values-fr-rCA/strings.xml index 949ba556d7f6..a95d5657cd03 100644 --- a/packages/PrintSpooler/res/values-fr-rCA/strings.xml +++ b/packages/PrintSpooler/res/values-fr-rCA/strings.xml @@ -61,11 +61,17 @@ </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">"Plus d\'information sur cette imprimante"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Certains services d\'impression sont désactivés."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Sélectionner le service d\'impression"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Certains services d\'impression sont désactivés"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Recherche d\'imprimantes en cours..."</string> <string name="print_no_print_services" msgid="8561247706423327966">"Aucun service d\'impression activé"</string> <string name="print_no_printers" msgid="4869403323900054866">"Aucune imprimante trouvée"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Impossible d’ajouter des imprimantes"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Sélectionnez pour ajouter une imprimante"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Sélectionner pour activer"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Services activés"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Services recommandés"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Services désactivés"</string> + <string name="all_services_title" msgid="5578662754874906455">"Tous les services"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Impression de <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> en cours…"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Annulation de « <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> »…"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Erreur impression : « <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> »"</string> diff --git a/packages/PrintSpooler/res/values-fr/strings.xml b/packages/PrintSpooler/res/values-fr/strings.xml index 1fcc0400bbac..dd1f490ea297 100644 --- a/packages/PrintSpooler/res/values-fr/strings.xml +++ b/packages/PrintSpooler/res/values-fr/strings.xml @@ -61,11 +61,17 @@ </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">"Plus d\'informations sur cette imprimante"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Certains services d\'impression sont désactivés."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Sélectionner le service d\'impression"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Certains services d\'impression sont désactivés."</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Recherche d\'imprimantes en cours"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Aucun service d\'impression activé"</string> <string name="print_no_printers" msgid="4869403323900054866">"Aucune imprimante trouvée"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Impossible d\'ajouter des imprimantes"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Sélectionnez pour ajouter une imprimante."</string> + <string name="enable_print_service" msgid="3482815747043533842">"Sélectionnez pour activer."</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Services activés"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Services recommandés"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Services désactivés"</string> + <string name="all_services_title" msgid="5578662754874906455">"Tous les services"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Impression de \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" en cours…"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Annulation de \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" en cours…"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Erreur impression pour \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\""</string> diff --git a/packages/PrintSpooler/res/values-gl-rES/strings.xml b/packages/PrintSpooler/res/values-gl-rES/strings.xml index 2e60960bc997..81e080e6cd65 100644 --- a/packages/PrintSpooler/res/values-gl-rES/strings.xml +++ b/packages/PrintSpooler/res/values-gl-rES/strings.xml @@ -61,11 +61,17 @@ </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">"Máis información sobre esta impresora"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Algúns servizos de impresión están desactivados."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Escoller servizo de impresión"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Algúns servizos de impresión están desactivados"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Busca de impresoras"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Non hai servizos de impresión activados"</string> <string name="print_no_printers" msgid="4869403323900054866">"Non se atopou ningunha impresora"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Non se poden engadir impresoras"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Selecciona un servizo para engadirlle impresora"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Selecciona un servizo para activalo"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Servizos activados"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Servizos recomendados"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Servizos desactivados"</string> + <string name="all_services_title" msgid="5578662754874906455">"Todos os servizos"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Erro da impresora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-gu-rIN/strings.xml b/packages/PrintSpooler/res/values-gu-rIN/strings.xml index 4ba969c1cc16..44ede8634397 100644 --- a/packages/PrintSpooler/res/values-gu-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-gu-rIN/strings.xml @@ -61,11 +61,17 @@ </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">"આ પ્રિન્ટર વિશે વધુ માહિતી"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"કેટલીક છાપ સેવાઓ અક્ષમ કરેલ છે."</string> - <string name="choose_print_service" msgid="3740309762324459694">"પ્રિન્ટ સેવા પસંદ કરો"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"કેટલીક છાપવાની સેવાઓ અક્ષમ કરેલ છે"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"પ્રિન્ટર્સ માટે શોધી રહ્યું છે"</string> <string name="print_no_print_services" msgid="8561247706423327966">"કોઈ છાપ સેવાઓ સક્ષમ કરેલ નથી"</string> <string name="print_no_printers" msgid="4869403323900054866">"કોઈ પ્રિન્ટર મળ્યા નથી"</string> + <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="recommended_services_title" msgid="3799434882937956924">"ભલામણ કરેલી સેવાઓ"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"અક્ષમ કરેલી સેવાઓ"</string> + <string name="all_services_title" msgid="5578662754874906455">"બધી સેવાઓ"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> છાપી રહ્યાં છે"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ને રદ કરી રહ્યું છે"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"પ્રિન્ટર ભૂલ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-hi/strings.xml b/packages/PrintSpooler/res/values-hi/strings.xml index 106134635bff..f75630e0eec8 100644 --- a/packages/PrintSpooler/res/values-hi/strings.xml +++ b/packages/PrintSpooler/res/values-hi/strings.xml @@ -61,11 +61,17 @@ </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">"इस प्रिंटर के बारे में अधिक जानकारी"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"कुछ प्रिंट सेवाएं अक्षम हैं."</string> - <string name="choose_print_service" msgid="3740309762324459694">"प्रिंट सेवा चुनें"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"कुछ प्रिंट सेवाएं अक्षम हैं"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"प्रिंटर खोज रहा है"</string> <string name="print_no_print_services" msgid="8561247706423327966">"कोई भी प्रिंट सेवा सक्षम नहीं है"</string> <string name="print_no_printers" msgid="4869403323900054866">"कोई प्रिंटर नहीं मिले"</string> + <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="recommended_services_title" msgid="3799434882937956924">"सुझाई गई सेवाएं"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"अक्षम सेवाएं"</string> + <string name="all_services_title" msgid="5578662754874906455">"सभी सेवाएं"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> प्रिंट हो रहा है"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> रद्द हो रहा है"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिंटर त्रुटि <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-hr/strings.xml b/packages/PrintSpooler/res/values-hr/strings.xml index 4a7d29f41534..bd29d028ac72 100644 --- a/packages/PrintSpooler/res/values-hr/strings.xml +++ b/packages/PrintSpooler/res/values-hr/strings.xml @@ -62,11 +62,17 @@ </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">"Više informacija o ovom pisaču"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Neke su usluge ispisa onemogućene."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Odaberite uslugu ispisa"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Neke su usluge ispisa onemogućene"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Traženje pisača"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Nije omogućena nijedna usluga ispisa"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nije pronađen nijedan pisač"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Ne možete dodati pisače"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Odaberite da biste dodali pisač"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Odaberite za omogućavanje"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Omogućene usluge"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Preporučene usluge"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Onemogućene usluge"</string> + <string name="all_services_title" msgid="5578662754874906455">"Sve usluge"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Ispisivanje <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Otkazivanje zadatka <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Pogreška pisača <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-hu/strings.xml b/packages/PrintSpooler/res/values-hu/strings.xml index 5aae2e41eb3d..356cb761241b 100644 --- a/packages/PrintSpooler/res/values-hu/strings.xml +++ b/packages/PrintSpooler/res/values-hu/strings.xml @@ -61,11 +61,17 @@ </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">"További információ erről a nyomtatóról"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Egyes nyomtatási szolgáltatások le vannak tiltva."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Nyomtatási szolgáltatás kiválasztása"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Egyes nyomtatási szolgáltatások le vannak tiltva"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Nyomtatók keresése"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Nincs engedélyezett nyomtatási szolgáltatás"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nem található nyomtató"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Nem lehet nyomtatókat hozzáadni"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Nyomtató hozzáadásához válassza ki"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Az engedélyezéshez válassza ki"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Engedélyezett szolgáltatások"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Javasolt szolgáltatások"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Letiltott szolgáltatások"</string> + <string name="all_services_title" msgid="5578662754874906455">"Minden szolgáltatás"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"A(z) <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> nyomtatása"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"A(z) <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> törlése"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Nyomtatási hiba: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-hy-rAM/strings.xml b/packages/PrintSpooler/res/values-hy-rAM/strings.xml index 179c384110e6..2d101662ec04 100644 --- a/packages/PrintSpooler/res/values-hy-rAM/strings.xml +++ b/packages/PrintSpooler/res/values-hy-rAM/strings.xml @@ -61,11 +61,17 @@ </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">"Հավելյալ տեղեկություններ այս տպիչի մասին"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Տպելու որոշ ծառայությունները կասեցված են:"</string> - <string name="choose_print_service" msgid="3740309762324459694">"Ընտրեք տպելու ծառայությունը"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Տպելու որոշ ծառայությունները կասեցված են"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Տպիչների որոնում"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Ակտիվացված տպման ծառայություններ չկան"</string> <string name="print_no_printers" msgid="4869403323900054866">"Տպիչներ չեն գտնվել"</string> + <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="recommended_services_title" msgid="3799434882937956924">"Խորհուրդ տրվող ծառայությունները"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Կասեցված ծառայությունները"</string> + <string name="all_services_title" msgid="5578662754874906455">"Բոլոր ծառայությունները"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Տպվում է՝ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>-ը չեղարկվում է"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Տպիչի սխալ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-in/strings.xml b/packages/PrintSpooler/res/values-in/strings.xml index 7286f7aae7e4..8e20d27d49dc 100644 --- a/packages/PrintSpooler/res/values-in/strings.xml +++ b/packages/PrintSpooler/res/values-in/strings.xml @@ -61,11 +61,17 @@ </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">"Informasi selengkapnya tentang printer ini"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Beberapa layanan cetak dinonaktifkan."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Pilih layanan cetak"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Beberapa layanan cetak dinonaktifkan"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Mencari printer"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Tidak ada layanan cetak yang aktif"</string> <string name="print_no_printers" msgid="4869403323900054866">"Tidak ditemukan printer"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Tidak dapat menambahkan printer"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Pilih untuk menambahkan printer"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Pilih untuk mengaktifkan"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Layanan diaktifkan"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Layanan yang disarankan"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Layanan dinonaktifkan"</string> + <string name="all_services_title" msgid="5578662754874906455">"Semua layanan"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Mencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Membatalkan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Ada kesalahan printer <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-is-rIS/strings.xml b/packages/PrintSpooler/res/values-is-rIS/strings.xml index 9ea49a92a75c..73660fb55a15 100644 --- a/packages/PrintSpooler/res/values-is-rIS/strings.xml +++ b/packages/PrintSpooler/res/values-is-rIS/strings.xml @@ -61,11 +61,17 @@ </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">"Frekari upplýsingar um þennan prentara"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Hluti prentþjónustunnar er óvirkur."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Veldu prentþjónustu"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Hluti prentþjónustunnar er óvirkur"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Leitar að prentara"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Engin prentþjónusta er virk"</string> <string name="print_no_printers" msgid="4869403323900054866">"Engir prentarar fundust"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Ekki er hægt að bæta við prenturum"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Veldu til að bæta prentara við"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Veldu til að virkja"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Virkjaðar þjónustur"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Þjónusta sem mælt er með"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Þjónusta við fatlaða"</string> + <string name="all_services_title" msgid="5578662754874906455">"Öll þjónusta"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Prentar <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Hættir við <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Prentaravilla <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-it/strings.xml b/packages/PrintSpooler/res/values-it/strings.xml index c19d012ec865..46a570d820d9 100644 --- a/packages/PrintSpooler/res/values-it/strings.xml +++ b/packages/PrintSpooler/res/values-it/strings.xml @@ -61,11 +61,17 @@ </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">"Ulteriori informazioni su questa stampante"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Alcuni servizi di stampa sono disattivati."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Scegli servizio di stampa"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Alcuni servizi di stampa sono disattivati"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Ricerca di stampanti"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Non è stato attivato alcun servizio di stampa"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nessuna stampante trovata"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Impossibile aggiungere stampanti"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Seleziona per aggiungere stampanti"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Seleziona per attivare"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Servizi abilitati"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Servizi consigliati"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Servizi disattivati"</string> + <string name="all_services_title" msgid="5578662754874906455">"Tutti i servizi"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Stampa di <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Annullamento di <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Errore della stampante: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-iw/strings.xml b/packages/PrintSpooler/res/values-iw/strings.xml index 00bf27c69ebd..c26c3d12a97d 100644 --- a/packages/PrintSpooler/res/values-iw/strings.xml +++ b/packages/PrintSpooler/res/values-iw/strings.xml @@ -63,11 +63,17 @@ </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">"מידע נוסף על מדפסת זו"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"שירותי הדפסה מסוימים מושבתים."</string> - <string name="choose_print_service" msgid="3740309762324459694">"בחר שירות הדפסה"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"שירותי הדפסה מסוימים מושבתים"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"מחפש מדפסות"</string> <string name="print_no_print_services" msgid="8561247706423327966">"לא הופעלו שירותי הדפסה"</string> <string name="print_no_printers" msgid="4869403323900054866">"לא נמצאו מדפסות"</string> + <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="recommended_services_title" msgid="3799434882937956924">"שירותים מומלצים"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"שירותים מושבתים"</string> + <string name="all_services_title" msgid="5578662754874906455">"כל השירותים"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"מדפיס את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"מבטל את <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"שגיאת מדפסת ב-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ja/strings.xml b/packages/PrintSpooler/res/values-ja/strings.xml index e0fc79a9b26f..a6e243f880e5 100644 --- a/packages/PrintSpooler/res/values-ja/strings.xml +++ b/packages/PrintSpooler/res/values-ja/strings.xml @@ -61,11 +61,17 @@ </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">"このプリンタの詳細"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"一部の印刷サービスは無効になっています。"</string> - <string name="choose_print_service" msgid="3740309762324459694">"印刷サービスの選択"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"一部の印刷サービスは無効になっています"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"プリンタの検索中"</string> <string name="print_no_print_services" msgid="8561247706423327966">"使用できる印刷サービスがありません"</string> <string name="print_no_printers" msgid="4869403323900054866">"プリンタが見つかりません"</string> + <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="recommended_services_title" msgid="3799434882937956924">"推奨されているサービス"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"無効になっているサービス"</string> + <string name="all_services_title" msgid="5578662754874906455">"すべてのサービス"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>を印刷しています"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>をキャンセルしています"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"プリンタエラー: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ka-rGE/strings.xml b/packages/PrintSpooler/res/values-ka-rGE/strings.xml index ad1468a6c103..2608ed48af41 100644 --- a/packages/PrintSpooler/res/values-ka-rGE/strings.xml +++ b/packages/PrintSpooler/res/values-ka-rGE/strings.xml @@ -61,11 +61,17 @@ </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">"დამატებითი ინფორმაცია ამ პრინტერის შესახებ"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"ბეჭდვის ზოგიერთი სერვისი გათიშულია."</string> - <string name="choose_print_service" msgid="3740309762324459694">"აირჩიეთ ბეჭდვის სერვისი"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"ბეჭდვის ზოგიერთი სერვისი გათიშულია"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"მიმდინარეობს პრინტერების ძიება"</string> <string name="print_no_print_services" msgid="8561247706423327966">"ბეჭდვის სერვისები გააქტიურებული არ არის"</string> <string name="print_no_printers" msgid="4869403323900054866">"პრინტერები ვერ მოიძებნა"</string> + <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="recommended_services_title" msgid="3799434882937956924">"რეკომენდებული სერვისები"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"გათიშული სერვისები"</string> + <string name="all_services_title" msgid="5578662754874906455">"ყველა სერვისი"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"იბეჭდება <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"მიმდინარეობს <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>-ის გაუქმება"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"ბეჭდვის შეცდომა <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml index d0337a6d97c2..def0c3c92ac7 100644 --- a/packages/PrintSpooler/res/values-kk-rKZ/strings.xml +++ b/packages/PrintSpooler/res/values-kk-rKZ/strings.xml @@ -61,11 +61,17 @@ </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">"Осы принтер туралы қосымша ақпарат"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Кейбір басып шығару қызметтері өшірілген."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Принтер қызметін таңдау"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Кейбір басып шығару қызметтері өшірілген."</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Принтерлерді іздеу"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Басып шығару қызметтері қосылмаған"</string> <string name="print_no_printers" msgid="4869403323900054866">"Ешқандай принтер табылмады"</string> + <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="recommended_services_title" msgid="3799434882937956924">"Ұсынылған қызметтер"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Өшірілген қызметтер"</string> + <string name="all_services_title" msgid="5578662754874906455">"Барлық қызметтер"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> басып шығарылуда"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> жұмысын тоқтатуда"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> принтер қателігі"</string> diff --git a/packages/PrintSpooler/res/values-km-rKH/strings.xml b/packages/PrintSpooler/res/values-km-rKH/strings.xml index c9431e988ce4..24048cf6d9a1 100644 --- a/packages/PrintSpooler/res/values-km-rKH/strings.xml +++ b/packages/PrintSpooler/res/values-km-rKH/strings.xml @@ -61,11 +61,17 @@ </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">"ព័ត៌មានបន្ថែមអំពីម៉ាស៊ីបោះពុម្ពនេះ"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"សេវាកម្មបោះពុម្ពមួយចំនួនត្រូវបានបិទដំណើរការ"</string> - <string name="choose_print_service" msgid="3740309762324459694">"ជ្រើសសេវាបោះពុម្ព"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"សេវាកម្មបោះពុម្ពមួយចំនួនត្រូវបានបិទដំណើរការ"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"ស្វែងរកម៉ាស៊ីនបោះពុម្ព"</string> <string name="print_no_print_services" msgid="8561247706423327966">"គ្មានការបើកដំណើរការសេវាបោះពុម្ពទេ"</string> <string name="print_no_printers" msgid="4869403323900054866">"រកមិនឃើញម៉ាស៊ីនបោះពុម្ព"</string> + <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="recommended_services_title" msgid="3799434882937956924">"សេវាកម្មដែលបានណែនាំ"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"សេវាកម្មដែលបិទដំណើរការ"</string> + <string name="all_services_title" msgid="5578662754874906455">"សេវាកម្មទាំងអស់"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"កំពុងបោះពុម្ព <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"ការបោះបង់ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"កំហុសម៉ាស៊ីនបោះពុម្ព <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-kn-rIN/strings.xml b/packages/PrintSpooler/res/values-kn-rIN/strings.xml index fc5149a495cb..af2096554376 100644 --- a/packages/PrintSpooler/res/values-kn-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-kn-rIN/strings.xml @@ -61,11 +61,17 @@ </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">"ಈ ಪ್ರಿಂಟರ್ ಬಗ್ಗೆ ಇನ್ನಷ್ಟು ಮಾಹಿತಿ"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"ಕೆಲವು ಮುದ್ರಣ ಸೇವೆಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string> - <string name="choose_print_service" msgid="3740309762324459694">"ಮುದ್ರಣ ಸೇವೆಯನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"ಕೆಲವು ಮುದ್ರಣ ಸೇವೆಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"ಪ್ರಿಂಟರ್ಗಳಿಗಾಗಿ ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string> <string name="print_no_print_services" msgid="8561247706423327966">"ಯಾವುದೇ ಮುದ್ರಣ ಸೇವೆಗಳನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿಲ್ಲ"</string> <string name="print_no_printers" msgid="4869403323900054866">"ಯಾವುದೇ ಮುದ್ರಕಗಳು ಕಂಡುಬಂದಿಲ್ಲ"</string> + <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="recommended_services_title" msgid="3799434882937956924">"ಶಿಫಾರಸು ಮಾಡಲಾದ ಸೇವೆಗಳು"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾದ ಸೇವೆಗಳು"</string> + <string name="all_services_title" msgid="5578662754874906455">"ಎಲ್ಲ ಸೇವೆಗಳು"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ಮುದ್ರಿಸಲಾಗುತ್ತಿದೆ"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ರದ್ದು ಮಾಡಲಾಗುತ್ತಿದೆ"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"ಮುದ್ರಕ ದೋಷ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ko/strings.xml b/packages/PrintSpooler/res/values-ko/strings.xml index 2faff1f97837..0b297a211bc2 100644 --- a/packages/PrintSpooler/res/values-ko/strings.xml +++ b/packages/PrintSpooler/res/values-ko/strings.xml @@ -61,11 +61,17 @@ </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">"이 프린터에 대한 정보 더보기"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"프린트 서비스 일부가 사용 중지되었습니다."</string> - <string name="choose_print_service" msgid="3740309762324459694">"인쇄 서비스 선택"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"프린트 서비스 일부가 사용 중지되었습니다."</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"프린터 검색 중"</string> <string name="print_no_print_services" msgid="8561247706423327966">"사용 가능한 프린트 서비스 없음"</string> <string name="print_no_printers" msgid="4869403323900054866">"프린터 없음"</string> + <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="recommended_services_title" msgid="3799434882937956924">"권장 서비스"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"사용 중지된 서비스"</string> + <string name="all_services_title" msgid="5578662754874906455">"모든 서비스"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> 인쇄 중"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> 취소 중"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"프린터 오류: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ky-rKG/strings.xml b/packages/PrintSpooler/res/values-ky-rKG/strings.xml index a01e4a8aad1b..85b25269cc7b 100644 --- a/packages/PrintSpooler/res/values-ky-rKG/strings.xml +++ b/packages/PrintSpooler/res/values-ky-rKG/strings.xml @@ -61,11 +61,17 @@ </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">"Бул принтер жөнүндө көбүрөөк маалымат"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Басып чыгаруу кызматтарынын айрымы өчүрүлгөн."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Принтер кызматын тандоо"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Басып чыгаруу кызматтарынын айрымы өчүрүлгөн"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Принтерлер изделүүдө"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Принтер-кызматтары иштетилген эмес"</string> <string name="print_no_printers" msgid="4869403323900054866">"Принтерлер табылган жок"</string> + <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="recommended_services_title" msgid="3799434882937956924">"Сунушталган кызматтар"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Өчүрүлгөн кызматтар"</string> + <string name="all_services_title" msgid="5578662754874906455">"Бардык кызматтар"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> басылууда"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> токтотулууда"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Принтерде ката кетти: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-lo-rLA/strings.xml b/packages/PrintSpooler/res/values-lo-rLA/strings.xml index b5d13b54fdbc..81ace83b8456 100644 --- a/packages/PrintSpooler/res/values-lo-rLA/strings.xml +++ b/packages/PrintSpooler/res/values-lo-rLA/strings.xml @@ -61,11 +61,17 @@ </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">"ຂໍ້ມູນເພີ່ມເຕີມກ່ຽວກັບເຄື່ອງພິມນີ້"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"ບາງການບໍລິການພິມຖືກປິດນຳໃຊ້."</string> - <string name="choose_print_service" msgid="3740309762324459694">"ເລືອກບໍລິການການພິມ"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"ບາງການບໍລິການພິມຖືກປິດການນຳໃຊ້"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"ກຳລັງຊອກຫາເຄື່ອງພິມ"</string> <string name="print_no_print_services" msgid="8561247706423327966">"ບໍ່ມີການບໍລິການພິມເປີດໃຊ້ງານໄວ້"</string> <string name="print_no_printers" msgid="4869403323900054866">"ບໍ່ພົບເຄື່ອງພິມ"</string> + <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="recommended_services_title" msgid="3799434882937956924">"ບໍລິການທີ່ແນະນຳ"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"ບໍລິການທີ່ຖືກປິດການນຳໃຊ້"</string> + <string name="all_services_title" msgid="5578662754874906455">"ບໍລິການທັງໝົດ"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"ກຳລັງພິມ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"ກຳລັງຍົກເລີກ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"ເຄື່ອງພິມເກີດຂໍ້ຜິດພາດ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-lt/strings.xml b/packages/PrintSpooler/res/values-lt/strings.xml index 3b8f14312d60..40bc7f127afb 100644 --- a/packages/PrintSpooler/res/values-lt/strings.xml +++ b/packages/PrintSpooler/res/values-lt/strings.xml @@ -63,11 +63,17 @@ </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">"Daugiau informacijos apie šį spausdintuvą"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Kai kurios spausdinimo paslaugos išjungtos."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Pasirinkite spausdinimo paslaugą"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Kai kurios spausdinimo paslaugos išjungtos"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Ieškoma spausdintuvų"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Neįgalinta jokių spausdinimo paslaugų"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nerasta spausdintuvų"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Nepavyko pridėti spausdintuvų"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Pasirinkite, kad pridėtumėte spausdintuvą"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Pasirinkite, kad įgalintumėte"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Įgalintos paslaugos"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Rekomenduojamos paslaugos"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Išjungtos paslaugos"</string> + <string name="all_services_title" msgid="5578662754874906455">"Visos paslaugos"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Spausdinama: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Atšaukiama: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Spausdintuvo klaida: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-lv/strings.xml b/packages/PrintSpooler/res/values-lv/strings.xml index 762d0bd1d26d..11e689b9a4c1 100644 --- a/packages/PrintSpooler/res/values-lv/strings.xml +++ b/packages/PrintSpooler/res/values-lv/strings.xml @@ -62,11 +62,17 @@ </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">"Plašāka informācija par šo printeri"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Daži drukas pakalpojumi ir atspējoti."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Izvēlieties drukāšanas pakalpojumu"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Daži drukas pakalpojumi ir atspējoti."</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Printeru meklēšana"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Nav iespējots neviens drukas pakalpojums"</string> <string name="print_no_printers" msgid="4869403323900054866">"Netika atrasts neviens printeris."</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Nevar pievienot printerus"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Atlasiet, lai pievienotu printeri"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Izvēlieties, lai iespējotu"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Iespējotie pakalpojumi"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Ieteiktie pakalpojumi"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Atspējotie pakalpojumi"</string> + <string name="all_services_title" msgid="5578662754874906455">"Visi pakalpojumi"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Notiek darba <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> drukāšana…"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Pārtrauc drukas darbu <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>…"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printera kļūda ar darbu <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-mk-rMK/strings.xml b/packages/PrintSpooler/res/values-mk-rMK/strings.xml index de6d3e9656e7..bc2b498585ec 100644 --- a/packages/PrintSpooler/res/values-mk-rMK/strings.xml +++ b/packages/PrintSpooler/res/values-mk-rMK/strings.xml @@ -61,11 +61,17 @@ </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">"Повеќе информации за овој печатач"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Некои услуги за печатење се оневозможени."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Избери услуга печатење"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Некои услуги за печатење се оневозможени"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Пребарување печатачи"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Нема овозможени услуги за печатење"</string> <string name="print_no_printers" msgid="4869403323900054866">"Не се пронајдени печатачи"</string> + <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="recommended_services_title" msgid="3799434882937956924">"Препорачани услуги"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Оневозможени услуги"</string> + <string name="all_services_title" msgid="5578662754874906455">"Сите услуги"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> се печати"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> се откажува"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Грешка при печатење <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ml-rIN/strings.xml b/packages/PrintSpooler/res/values-ml-rIN/strings.xml index 7a33e14e0e6a..ade7fb39f400 100644 --- a/packages/PrintSpooler/res/values-ml-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-ml-rIN/strings.xml @@ -61,11 +61,17 @@ </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">"ഈ പ്രിന്ററിനെ കുറിച്ചുള്ള കൂടുതൽ വിവരങ്ങൾ"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"ചില പ്രിന്റ് സേവനങ്ങൾ പ്രവർത്തനരഹിതമാക്കിയിരിക്കുന്നു."</string> - <string name="choose_print_service" msgid="3740309762324459694">"പ്രിന്റ് സേവനം തിരഞ്ഞെടുക്കുക"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"ചില പ്രിന്റ് സേവനങ്ങൾ പ്രവർത്തനരഹിതമാക്കി"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"പ്രിന്ററുകൾക്കായി തിരയുന്നു"</string> <string name="print_no_print_services" msgid="8561247706423327966">"പ്രിന്റ് സേവനങ്ങളൊന്നും പ്രവർത്തനക്ഷമാക്കിയിട്ടില്ല"</string> <string name="print_no_printers" msgid="4869403323900054866">"പ്രിന്ററുകളൊന്നും കണ്ടെത്തിയില്ല"</string> + <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="recommended_services_title" msgid="3799434882937956924">"ശുപാർശ ചെയ്യപ്പെടുന്ന സേവനങ്ങൾ"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"പ്രവർത്തനരഹിതമാക്കിയ സേവനങ്ങൾ"</string> + <string name="all_services_title" msgid="5578662754874906455">"എല്ലാ സേവനങ്ങളും"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> പ്രിന്റുചെയ്യുന്നു"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> റദ്ദാക്കുന്നു"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"പ്രിന്റർ പിശക് <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-mn-rMN/strings.xml b/packages/PrintSpooler/res/values-mn-rMN/strings.xml index c94e56d2fedc..133d88c58fb2 100644 --- a/packages/PrintSpooler/res/values-mn-rMN/strings.xml +++ b/packages/PrintSpooler/res/values-mn-rMN/strings.xml @@ -61,11 +61,17 @@ </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">"Энэ хэвлэгчийн талаарх дэлгэрэнгүй мэдээлэл"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Зарим хэвлэх үйлчилгээг идэвхгүй болгосон байна."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Хэвлэх үйлчилгээг сонгох"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Зарим хэвлэх үйлчилгээг идэвхгүй болгосон байна"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Принтер хайж байна"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Хэвлэх үйлчилгээг идэвхжүүлээгүй"</string> <string name="print_no_printers" msgid="4869403323900054866">"Принтер олдсонгүй"</string> + <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="recommended_services_title" msgid="3799434882937956924">"Санал болгосон үйлчилгээ"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Идэвхгүй болгосон үйлчилгээ"</string> + <string name="all_services_title" msgid="5578662754874906455">"Бүх үйлчилгээ"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Хэвлэж байна <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Цуцлаж байна <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Принтерийн алдаа <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-mr-rIN/strings.xml b/packages/PrintSpooler/res/values-mr-rIN/strings.xml index ab25010a7d57..2b3b29f87b36 100644 --- a/packages/PrintSpooler/res/values-mr-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-mr-rIN/strings.xml @@ -61,11 +61,17 @@ </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">"या प्रिंटर विषयी अधिक माहिती"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"काही मुद्रण सेवा अक्षम केल्या आहेत."</string> - <string name="choose_print_service" msgid="3740309762324459694">"मुद्रण सेवा निवडा"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"काही मुद्रण सेवा अक्षम केल्या आहेत"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"प्रिंटर शोधत आहे"</string> <string name="print_no_print_services" msgid="8561247706423327966">"कोणत्याही मुद्रण सेवा सक्षम केलेल्या नाहीत"</string> <string name="print_no_printers" msgid="4869403323900054866">"कोणतेही प्रिंटर आढळले नाही"</string> + <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="recommended_services_title" msgid="3799434882937956924">"शिफारस केलेल्या सेवा"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"अक्षम केलल्या सेवा"</string> + <string name="all_services_title" msgid="5578662754874906455">"सर्व सेवा"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> मुद्रण करीत आहे"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> रद्द करीत आहे"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिंटर त्रुटी <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ms-rMY/strings.xml b/packages/PrintSpooler/res/values-ms-rMY/strings.xml index 917ae8a7222f..73104e18b1e2 100644 --- a/packages/PrintSpooler/res/values-ms-rMY/strings.xml +++ b/packages/PrintSpooler/res/values-ms-rMY/strings.xml @@ -61,11 +61,17 @@ </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">"Maklumat lanjut tentang pencetak ini"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Sesetengah perkhidmatan cetak dilumpuhkan."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Pilih perkhidmatan cetak"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Sesetengah perkhidmatan cetak dilumpuhkan"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Mencari pencetak"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Perkhidmatan cetak tidak didayakan"</string> <string name="print_no_printers" msgid="4869403323900054866">"Tiada pencetak ditemui"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Tidak dapat menambahkan pencetak"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Pilih untuk menambahkan pencetak"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Pilih untuk mendayakan"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Perkhidmatan yang didayakan"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Perkhidmatan yang disyorkan"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Perkhidmatan yang dilumpuhkan"</string> + <string name="all_services_title" msgid="5578662754874906455">"Semua perkhidmatan"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Mencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Membatalkan <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Ralat pencetak <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-my-rMM/strings.xml b/packages/PrintSpooler/res/values-my-rMM/strings.xml index 4d4c95bd7d29..8cec0683afe6 100644 --- a/packages/PrintSpooler/res/values-my-rMM/strings.xml +++ b/packages/PrintSpooler/res/values-my-rMM/strings.xml @@ -61,11 +61,17 @@ </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">"ဤပရင်တာ အကြောင်း ပိုမိုလေ့လာပါ"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"ပရင့်ထုတ်ရေး အချို့ဝန်ဆောင်မှုများကို ပိတ်ထားပါသည်။"</string> - <string name="choose_print_service" msgid="3740309762324459694">"စာထုတ်ရန် ဝန်ဆောင်မှုကို ရွေးချယ်ပါ"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"အချို့ပုံနှိပ်ဝန်ဆောင်မှုများကို ပိတ်ထားပါသည်"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"စာထုတ်စက်များကို ရှာနေပါသည်"</string> <string name="print_no_print_services" msgid="8561247706423327966">"ပုံနှိပ်ထုတ်ယူရေး ဝန်ဆောင်မှုများ ဖွင့်မထားပါ"</string> <string name="print_no_printers" msgid="4869403323900054866">"စာထုတ်စက် တစ်ခုမှ မတွေ့ရှိပါ"</string> + <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="recommended_services_title" msgid="3799434882937956924">"အကြံပြုထားသည့် ဝန်ဆောင်မှုများ"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"ပိတ်ထားသည့် ဝန်ဆောင်မှုများ"</string> + <string name="all_services_title" msgid="5578662754874906455">"ဝန်ဆောင်မှုများ အားလုံး"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ကို စာထုတ်နေပါသည်"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ကို ပယ်ဖျက်နေပါသည်"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"စာထုတ်စက်မှ အမှား <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-nb/strings.xml b/packages/PrintSpooler/res/values-nb/strings.xml index 9efa5d1b923e..0a6f6c3bfd60 100644 --- a/packages/PrintSpooler/res/values-nb/strings.xml +++ b/packages/PrintSpooler/res/values-nb/strings.xml @@ -61,11 +61,17 @@ </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">"Mer informasjon om denne printeren"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Noen utskriftstjenester er slått av."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Velg utskriftstjeneste"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Noen utskriftstjenester er slått av"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Søker etter skrivere"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Ingen utskriftstjenester er slått på"</string> <string name="print_no_printers" msgid="4869403323900054866">"Fant ingen skrivere"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Kan ikke legge til skrivere"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Velg for å legge til skrivere"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Velg for å slå på"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Tjenester som er slått på"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Anbefalte tjenester"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Tjenester som er slått av"</string> + <string name="all_services_title" msgid="5578662754874906455">"Alle tjenester"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Skriver ut <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Avbryter <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Skriverfeil <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ne-rNP/strings.xml b/packages/PrintSpooler/res/values-ne-rNP/strings.xml index 281a65d97fb8..5af3a04ed698 100644 --- a/packages/PrintSpooler/res/values-ne-rNP/strings.xml +++ b/packages/PrintSpooler/res/values-ne-rNP/strings.xml @@ -61,11 +61,17 @@ </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">"यस प्रिन्टरको बारेमा थप जानकारी"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"केही मुद्रण सेवाहरू असक्षम छन्।"</string> - <string name="choose_print_service" msgid="3740309762324459694">"प्रिन्ट सेवा छनौट गर्नुहोस्"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"केही मुद्रण सम्बन्धी सेवाहरूलाई असक्षम गरिएको छ"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"प्रिन्टरहरू खोज्दै"</string> <string name="print_no_print_services" msgid="8561247706423327966">"कुनै पनि मुद्रण सेवाहरू सक्रिय छैनन्"</string> <string name="print_no_printers" msgid="4869403323900054866">"कुनै प्रिन्टरहरू भेटाइएन"</string> + <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="recommended_services_title" msgid="3799434882937956924">"सिफारिस गरिएका सेवाहरू"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"असक्षम गरिएका सेवाहरू"</string> + <string name="all_services_title" msgid="5578662754874906455">"सबै सेवाहरू"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"प्रिन्ट गरिँदै <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"रद्द गरिँदै <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"प्रिन्टर त्रुटि <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-nl/strings.xml b/packages/PrintSpooler/res/values-nl/strings.xml index eef9880283df..4afdb86cac8b 100644 --- a/packages/PrintSpooler/res/values-nl/strings.xml +++ b/packages/PrintSpooler/res/values-nl/strings.xml @@ -61,11 +61,17 @@ </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">"Meer informatie over deze printer"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Sommige afdrukservices zijn uitgeschakeld."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Afdrukservice kiezen"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Sommige afdrukservices zijn uitgeschakeld"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Printers zoeken"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Geen afdrukservices ingeschakeld"</string> <string name="print_no_printers" msgid="4869403323900054866">"Geen printers gevonden"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Kan geen printers toevoegen"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Selecteer om printer toe te voegen"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Selecteer om in te schakelen"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Ingeschakelde services"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Aanbevolen services"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Uitgeschakelde services"</string> + <string name="all_services_title" msgid="5578662754874906455">"Alle services"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> afdrukken"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> annuleren"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printerfout <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-pa-rIN/strings.xml b/packages/PrintSpooler/res/values-pa-rIN/strings.xml index 7d7860cca1f0..1886ef53a3e6 100644 --- a/packages/PrintSpooler/res/values-pa-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-pa-rIN/strings.xml @@ -61,11 +61,17 @@ </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">"ਇਸ ਪ੍ਰਿੰਟਰ ਬਾਰੇ ਹੋਰ ਜਾਣਕਾਰੀ"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"ਕੁਝ ਪ੍ਰਿੰਟ ਸੇਵਾਵਾਂ ਅਯੋਗ ਬਣਾਈਆਂ ਗਈਆਂ ਹਨ।"</string> - <string name="choose_print_service" msgid="3740309762324459694">"ਪ੍ਰਿੰਟ ਸੇਵਾ ਚੁਣੋ"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"ਕੁਝ ਪ੍ਰਿੰਟ ਸੇਵਾਵਾਂ ਅਯੋਗ ਬਣਾਈਆਂ ਗਈਆਂ ਹਨ"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"ਪ੍ਰਿੰਟਰ ਖੋਜ ਰਿਹਾ ਹੈ"</string> <string name="print_no_print_services" msgid="8561247706423327966">"ਪ੍ਰਿੰਟ ਸੇਵਾਵਾਂ ਯੋਗ ਨਹੀਂ ਬਣਾਈਆਂ ਗਈਆਂ"</string> <string name="print_no_printers" msgid="4869403323900054866">"ਕੋਈ ਪ੍ਰਿੰਟਰ ਨਹੀਂ ਮਿਲੇ"</string> + <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="recommended_services_title" msgid="3799434882937956924">"ਸਿਫ਼ਾਰਸ਼ ਕੀਤੀਆਂ ਸੇਵਾਵਾਂ"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"ਅਯੋਗ ਬਣਾਈਆਂ ਗਈਆਂ ਸੇਵਾਵਾਂ"</string> + <string name="all_services_title" msgid="5578662754874906455">"ਸਾਰੀਆਂ ਸੇਵਾਵਾਂ"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ਨੂੰ ਪ੍ਰਿੰਟ ਕਰ ਰਿਹਾ ਹੈ"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ਨੂੰ ਰੱਦ ਕਰ ਰਿਹਾ ਹੈ"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"ਪ੍ਰਿੰਟਰ ਅਸ਼ੁੱਧੀ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-pl/strings.xml b/packages/PrintSpooler/res/values-pl/strings.xml index 6837edf77996..45649bb10df6 100644 --- a/packages/PrintSpooler/res/values-pl/strings.xml +++ b/packages/PrintSpooler/res/values-pl/strings.xml @@ -63,11 +63,17 @@ </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">"Więcej informacji o tej drukarce"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Niektóre usługi drukowania są wyłączone."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Wybierz usługę drukowania"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Niektóre usługi drukowania są wyłączone"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Szukanie drukarek"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Brak włączonych usług drukowania"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nie znaleziono drukarek"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Nie można dodawać drukarek"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Wybierz, by dodać drukarkę"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Wybierz, by włączyć usługę"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Włączone usługi"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Polecane usługi"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Wyłączone usługi"</string> + <string name="all_services_title" msgid="5578662754874906455">"Wszystkie usługi"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Drukowanie: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Anulowanie: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Błąd drukarki: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-pt-rBR/strings.xml b/packages/PrintSpooler/res/values-pt-rBR/strings.xml index c9713c9e7efb..58eb24f71b91 100644 --- a/packages/PrintSpooler/res/values-pt-rBR/strings.xml +++ b/packages/PrintSpooler/res/values-pt-rBR/strings.xml @@ -61,11 +61,17 @@ </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">"Mais informações sobre essa impressora"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Alguns serviços de impressão estão desativados."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Selecione o serviço de impressão"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Alguns serviços de impressão estão desativados"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Procurando impressoras"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Nenhum serviço de impressão ativado"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nenhuma impressora encontrada"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Não é possível adicionar impressoras"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Selecione para adicionar uma impressora"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Selecione para ativar"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Serviços ativados"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Serviços recomendados"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Serviços desativados"</string> + <string name="all_services_title" msgid="5578662754874906455">"Todos os serviços"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Erro ao imprimir <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-pt-rPT/strings.xml b/packages/PrintSpooler/res/values-pt-rPT/strings.xml index 9fabc0fced5f..370bbb935822 100644 --- a/packages/PrintSpooler/res/values-pt-rPT/strings.xml +++ b/packages/PrintSpooler/res/values-pt-rPT/strings.xml @@ -61,11 +61,17 @@ </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">"Mais informações acerca desta impressora"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Alguns serviços de impressão estão desativados."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Escolher o serviço de impressão"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Alguns serviços de impressão estão desativados"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"A procurar impressoras"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Nenhum serviço de impressão ativado"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nenhuma impressora encontrada"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Não é possível adicionar impressoras"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Selecione para adicionar uma impressora"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Selecione para ativar"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Serviços ativados"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Serviços recomendados"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Serviços desativados"</string> + <string name="all_services_title" msgid="5578662754874906455">"Todos os serviços"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"A imprimir <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"A cancelar <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Erro da impressora <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-pt/strings.xml b/packages/PrintSpooler/res/values-pt/strings.xml index c9713c9e7efb..58eb24f71b91 100644 --- a/packages/PrintSpooler/res/values-pt/strings.xml +++ b/packages/PrintSpooler/res/values-pt/strings.xml @@ -61,11 +61,17 @@ </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">"Mais informações sobre essa impressora"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Alguns serviços de impressão estão desativados."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Selecione o serviço de impressão"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Alguns serviços de impressão estão desativados"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Procurando impressoras"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Nenhum serviço de impressão ativado"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nenhuma impressora encontrada"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Não é possível adicionar impressoras"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Selecione para adicionar uma impressora"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Selecione para ativar"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Serviços ativados"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Serviços recomendados"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Serviços desativados"</string> + <string name="all_services_title" msgid="5578662754874906455">"Todos os serviços"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Imprimindo <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Cancelando <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Erro ao imprimir <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ro/strings.xml b/packages/PrintSpooler/res/values-ro/strings.xml index 7364eb0dae2c..1097d566f430 100644 --- a/packages/PrintSpooler/res/values-ro/strings.xml +++ b/packages/PrintSpooler/res/values-ro/strings.xml @@ -62,11 +62,17 @@ </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">"Mai multe informații despre această imprimantă"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Unele servicii de printare sunt dezactivate."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Alegeți serviciul de printare"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Unele servicii de printare sunt dezactivate"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Se caută imprimante"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Niciun serviciu de printare activat"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nu au fost găsite imprimante"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Nu pot fi adăugate imprimante"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Selectați pentru a adăuga o imprimantă"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Selectați pentru a activa"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Servicii activate"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Servicii recomandate"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Servicii dezactivate"</string> + <string name="all_services_title" msgid="5578662754874906455">"Toate serviciile"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Se printează <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Se anulează <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Eroare de printare: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ru/strings.xml b/packages/PrintSpooler/res/values-ru/strings.xml index d3d0d3f1f322..24b1e0d5db21 100644 --- a/packages/PrintSpooler/res/values-ru/strings.xml +++ b/packages/PrintSpooler/res/values-ru/strings.xml @@ -63,11 +63,17 @@ </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">"Подробные сведения о принтере"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Некоторые службы печати отключены."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Выберите службу печати"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Некоторые службы печати отключены"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Поиск принтеров…"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Службы печати недоступны"</string> <string name="print_no_printers" msgid="4869403323900054866">"Ничего не найдено"</string> + <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="recommended_services_title" msgid="3799434882937956924">"Рекомендуемые службы"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Отключенные службы"</string> + <string name="all_services_title" msgid="5578662754874906455">"Все службы печати"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Печать задания \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\"…"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Отмена задания <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>…"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Ошибка задания \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\""</string> diff --git a/packages/PrintSpooler/res/values-si-rLK/strings.xml b/packages/PrintSpooler/res/values-si-rLK/strings.xml index 610442d25141..707c1514b963 100644 --- a/packages/PrintSpooler/res/values-si-rLK/strings.xml +++ b/packages/PrintSpooler/res/values-si-rLK/strings.xml @@ -61,11 +61,17 @@ </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">"මෙම මුද්රණ යන්ත්රය ගැන තවත් තොරතුරු"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"සමහර මුද්රණ සේවා අබලයි."</string> - <string name="choose_print_service" msgid="3740309762324459694">"මුද්රණ සේවාව තෝරන්න"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"සමහර මුද්රණ සේවා අබලයි"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"මුද්රණ යන්ත්ර සොයමින්"</string> <string name="print_no_print_services" msgid="8561247706423327966">"මුද්රණ සේවා සබල නැත"</string> <string name="print_no_printers" msgid="4869403323900054866">"මුද්රණ යන්ත්ර සොයා නොගැනුණි"</string> + <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="recommended_services_title" msgid="3799434882937956924">"නිර්දේශිත සේවා"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"අබල කළ සේවා"</string> + <string name="all_services_title" msgid="5578662754874906455">"සියලු සේවා"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> මුද්රණය වේ"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"අවලංගු කෙරේ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"මුද්රණ දෝෂය <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-sk/strings.xml b/packages/PrintSpooler/res/values-sk/strings.xml index 603d1d2242f3..1f13b54d24ef 100644 --- a/packages/PrintSpooler/res/values-sk/strings.xml +++ b/packages/PrintSpooler/res/values-sk/strings.xml @@ -63,11 +63,17 @@ </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">"Ďalšie informácie o tejto tlačiarni"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Niektoré tlačové služby sú vypnuté."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Výber tlačovej služby"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Niektoré tlačové služby sú zakázané"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Vyhľadávanie tlačiarní"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Žiadne tlačové služby nie sú aktivované"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nenašli sa žiadne tlačiarne"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Nie je možné pridať tlačiarne"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Výber služby na pridanie tlačiarne"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Vyberte a povoľte"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Povolené služby"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Odporúčané služby"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Zakázané služby"</string> + <string name="all_services_title" msgid="5578662754874906455">"Všetky služby"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Prebieha tlač úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Prebieha zrušenie úlohy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Chyba tlačiarne – úloha <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-sl/strings.xml b/packages/PrintSpooler/res/values-sl/strings.xml index 4a0826944448..3f8a5e629c25 100644 --- a/packages/PrintSpooler/res/values-sl/strings.xml +++ b/packages/PrintSpooler/res/values-sl/strings.xml @@ -63,11 +63,17 @@ </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">"Več informacij o tem tiskalniku"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Nekatere tiskalne storitve so onemogočene."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Izberite tiskalno storitev"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Nekatere tiskalne storitve so onemogočene"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Iskanje tiskalnikov"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Ni omogočenih tiskalnih storitev"</string> <string name="print_no_printers" msgid="4869403323900054866">"Tiskalnikov ni mogoče najti"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Tiskalnikov ni mogoče dodati"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Izberite za dodajanje tiskalnika"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Izberite, če želite omogočiti"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Omogočene storitve"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Priporočene storitve"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Onemogočene storitve"</string> + <string name="all_services_title" msgid="5578662754874906455">"Vse storitve"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Tiskanje: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Preklic: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Napaka tiskalnika: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-sq-rAL/strings.xml b/packages/PrintSpooler/res/values-sq-rAL/strings.xml index b0902efb7540..0b843d7fbfaa 100644 --- a/packages/PrintSpooler/res/values-sq-rAL/strings.xml +++ b/packages/PrintSpooler/res/values-sq-rAL/strings.xml @@ -61,11 +61,17 @@ </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">"Më shumë informacione mbi këtë printer"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Disa shërbime printimi janë çaktivizuar."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Zgjidh shërbimin e printimit"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Disa shërbime printimi janë çaktivizuar"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Po kërkon për printerë"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Nuk ka shërbime printimi të aktivizuara"</string> <string name="print_no_printers" msgid="4869403323900054866">"Nuk u gjet asnjë printer"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Nuk mund të shtohen printerë"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Zgjidh për të shtuar printer"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Zgjidh për të aktivizuar"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Shërbimet e aktivizuara"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Shërbimet e rekomanduara"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Shërbimet e çaktivizuara"</string> + <string name="all_services_title" msgid="5578662754874906455">"Të gjitha shërbimet"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Po printon <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Po anulon <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printeri ndeshi në gabim gjatë punës: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-sr/strings.xml b/packages/PrintSpooler/res/values-sr/strings.xml index feb2940d7da8..8baa23c3d258 100644 --- a/packages/PrintSpooler/res/values-sr/strings.xml +++ b/packages/PrintSpooler/res/values-sr/strings.xml @@ -62,11 +62,17 @@ </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">"Још информација о овом штампачу"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Неке услуге штампања су онемогућене."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Изаберите услугу штампања"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Неке услуге штампања су онемогућене"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Претрага штампача"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Ниједна услуга штампања није омогућена"</string> <string name="print_no_printers" msgid="4869403323900054866">"Није пронађен ниједан штампач"</string> + <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="recommended_services_title" msgid="3799434882937956924">"Препоручене услуге"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Онемогућене услуге"</string> + <string name="all_services_title" msgid="5578662754874906455">"Све услуге"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Штампа се <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Отказује се <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Грешка штампача <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-sv/strings.xml b/packages/PrintSpooler/res/values-sv/strings.xml index cf398c78fb56..64b6b206ee02 100644 --- a/packages/PrintSpooler/res/values-sv/strings.xml +++ b/packages/PrintSpooler/res/values-sv/strings.xml @@ -61,11 +61,17 @@ </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">"Mer information om den här skrivaren"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Några utskriftstjänster har inaktiverats."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Välj utskriftstjänst"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Några utskriftstjänster har inaktiverats"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Söker efter skrivare"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Inga utskriftstjänster har aktiverats"</string> <string name="print_no_printers" msgid="4869403323900054866">"Det gick inte att hitta några skrivare"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Det går inte att lägga till skrivare"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Lägg till en skrivare"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Välj om du vill aktivera"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Aktiverade tjänster"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Rekommenderade tjänster"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Inaktiverade tjänster"</string> + <string name="all_services_title" msgid="5578662754874906455">"Alla tjänster"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Skriver ut <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Avbryter <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Skrivarfel för <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-sw/strings.xml b/packages/PrintSpooler/res/values-sw/strings.xml index 7e00b7046423..b3ffa71a26d6 100644 --- a/packages/PrintSpooler/res/values-sw/strings.xml +++ b/packages/PrintSpooler/res/values-sw/strings.xml @@ -61,11 +61,17 @@ </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">"Maelezo zaidi kuhusu printa hii"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Baadhi ya huduma za uchapishaji zimezimwa."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Chagua huduma ya printa"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Baadhi ya huduma za uchapishaji haziruhusiwi"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Inatafuta printa"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Huduma za kuchapisha hazijawashwa"</string> <string name="print_no_printers" msgid="4869403323900054866">"Hakuna printa zilizopatikana"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Haiwezi kuongeza printa"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Chagua printa ya kuongeza"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Chagua ili uruhusu"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Huduma zinazoruhusiwa"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Huduma zinazopendekezwa"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Huduma ambazo haziruhusiwi"</string> + <string name="all_services_title" msgid="5578662754874906455">"Huduma zote"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Inachapisha <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Inaghairi <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Hitilafu ya kuchapisha <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-ta-rIN/strings.xml b/packages/PrintSpooler/res/values-ta-rIN/strings.xml index ae0b774a5911..7ae3cbcc065d 100644 --- a/packages/PrintSpooler/res/values-ta-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-ta-rIN/strings.xml @@ -61,11 +61,17 @@ </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">"இந்தப் பிரிண்டர் பற்றிய கூடுதல் தகவல்"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"சில அச்சுப் பொறிகள் முடக்கப்பட்டன."</string> - <string name="choose_print_service" msgid="3740309762324459694">"அச்சுப் பொறியைத் தேர்வுசெய்யவும்"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"சில அச்சுப் பொறிகள் முடக்கப்பட்டன"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"அச்சுப்பொறிகளைத் தேடுகிறது"</string> <string name="print_no_print_services" msgid="8561247706423327966">"அச்சுப் பொறிகள் இல்லை"</string> <string name="print_no_printers" msgid="4869403323900054866">"பிரிண்டர்கள் எதுவுமில்லை"</string> + <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="recommended_services_title" msgid="3799434882937956924">"பரிந்துரைக்கப்படும் அச்சுப் பொறிகள்"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"முடக்கப்பட்ட அச்சுப் பொறிகள்"</string> + <string name="all_services_title" msgid="5578662754874906455">"எல்லா அச்சுப் பொறிகளும்"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ஐ அச்சிடுகிறது"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> ஐ ரத்துசெய்கிறது"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"பிரிண்டர் பிழை <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-te-rIN/strings.xml b/packages/PrintSpooler/res/values-te-rIN/strings.xml index 5fd8d60ba573..9e8dea2a21e6 100644 --- a/packages/PrintSpooler/res/values-te-rIN/strings.xml +++ b/packages/PrintSpooler/res/values-te-rIN/strings.xml @@ -61,11 +61,17 @@ </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">"ఈ ప్రింటర్ గురించి మరింత సమాచారం"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"కొన్ని ముద్రణ సేవలు నిలిపివేయబడ్డాయి."</string> - <string name="choose_print_service" msgid="3740309762324459694">"ముద్రణ సేవను ఎంచుకోండి"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"కొన్ని ముద్రణ సేవలు నిలిపివేయబడ్డాయి"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"ప్రింటర్ల కోసం శోధిస్తోంది"</string> <string name="print_no_print_services" msgid="8561247706423327966">"ముద్రణ సేవలు ఏవీ ప్రారంభించలేదు"</string> <string name="print_no_printers" msgid="4869403323900054866">"ప్రింటర్లు కనుగొనబడలేదు"</string> + <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="recommended_services_title" msgid="3799434882937956924">"సిఫార్సు చేయబడిన సేవలు"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"నిలిపివేసిన సేవలు"</string> + <string name="all_services_title" msgid="5578662754874906455">"అన్ని సేవలు"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ను ముద్రిస్తోంది"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>ను రద్దు చేస్తోంది"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"ప్రింటర్ లోపం <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-th/strings.xml b/packages/PrintSpooler/res/values-th/strings.xml index ebd5e2a9c7a8..c623dd79c724 100644 --- a/packages/PrintSpooler/res/values-th/strings.xml +++ b/packages/PrintSpooler/res/values-th/strings.xml @@ -61,11 +61,17 @@ </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">"ข้อมูลเพิ่มเติมเกี่ยวกับเครื่องพิมพ์นี้"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"บริการพิมพ์บางอย่างถูกปิดใช้"</string> - <string name="choose_print_service" msgid="3740309762324459694">"เลือกบริการพิมพ์"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"บริการพิมพ์บางอย่างปิดใช้อยู่"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"กำลังค้นหาเครื่องพิมพ์"</string> <string name="print_no_print_services" msgid="8561247706423327966">"ไม่ได้เปิดใช้บริการพิมพ์"</string> <string name="print_no_printers" msgid="4869403323900054866">"ไม่พบเครื่องพิมพ์"</string> + <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="recommended_services_title" msgid="3799434882937956924">"บริการที่แนะนำ"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"บริการที่ปิดใช้"</string> + <string name="all_services_title" msgid="5578662754874906455">"บริการทั้งหมด"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"กำลังพิมพ์ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"กำลังยกเลิก <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"ข้อผิดพลาดเครื่องพิมพ์ <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-tl/strings.xml b/packages/PrintSpooler/res/values-tl/strings.xml index ebe869bc0ab2..0494cf698890 100644 --- a/packages/PrintSpooler/res/values-tl/strings.xml +++ b/packages/PrintSpooler/res/values-tl/strings.xml @@ -61,11 +61,17 @@ </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">"Higit pang impormasyon tungkol sa printer na ito"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Naka-disable ang ilang serbisyo sa pag-print."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Pumili ng serbisyo ng pag-print"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Naka-disable ang ilang serbisyo sa pag-print"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Naghahanap ng mga printer"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Walang mga naka-enable na serbisyo sa pag-print"</string> <string name="print_no_printers" msgid="4869403323900054866">"Walang mga printer na nakita"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Hindi makapagdagdag ng mga printer"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Piliin upang magdagdag ng printer"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Piliin upang i-enable"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Mga naka-enable na serbisyo"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Mga inirerekomendang serbisyo"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Mga naka-disable na serbisyo"</string> + <string name="all_services_title" msgid="5578662754874906455">"Lahat ng serbisyo"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Pini-print ang <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Kinakansela ang <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Error sa printer <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-tr/strings.xml b/packages/PrintSpooler/res/values-tr/strings.xml index 9cd42abd42bf..2818f36c59b0 100644 --- a/packages/PrintSpooler/res/values-tr/strings.xml +++ b/packages/PrintSpooler/res/values-tr/strings.xml @@ -61,11 +61,17 @@ </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">"Bu yazıcıyla ilgili daha fazla bilgi"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Bazı yazdırma hizmetleri devre dışı."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Yazdırma hizmetini seçin"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Bazı yazdırma hizmetleri devre dışı bırakıldı"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Yazıcılar aranıyor"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Etkin yazıcı hizmeti yok"</string> <string name="print_no_printers" msgid="4869403323900054866">"Yazıcı bulunamadı"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Yazıcı eklenemiyor"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Yazıcı eklemek için seçin"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Etkinleştirmek için seçin"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Etkin hizmetler"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Önerilen hizmetler"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Devre dışı bırakılmış hizmetler"</string> + <string name="all_services_title" msgid="5578662754874906455">"Tüm hizmetler"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> yazdırılıyor"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> iptal ediliyor"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Yazıcı hatası: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-uk/strings.xml b/packages/PrintSpooler/res/values-uk/strings.xml index 1082147d3b6d..41051afa0227 100644 --- a/packages/PrintSpooler/res/values-uk/strings.xml +++ b/packages/PrintSpooler/res/values-uk/strings.xml @@ -63,11 +63,17 @@ </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">"Докладніше про цей принтер"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Деякі служби друку вимкнено."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Вибрати службу друку"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Деякі служби друку вимкнено"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Пошук принтерів"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Немає служб друку"</string> <string name="print_no_printers" msgid="4869403323900054866">"Принтери не знайдено"</string> + <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="recommended_services_title" msgid="3799434882937956924">"Рекомендовані служби"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Вимкнені служби"</string> + <string name="all_services_title" msgid="5578662754874906455">"Усі служби"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" друкується"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\" скасовується"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Помилка завдання \"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>\""</string> diff --git a/packages/PrintSpooler/res/values-ur-rPK/strings.xml b/packages/PrintSpooler/res/values-ur-rPK/strings.xml index 56f1093ba71e..a94b16f9ebc7 100644 --- a/packages/PrintSpooler/res/values-ur-rPK/strings.xml +++ b/packages/PrintSpooler/res/values-ur-rPK/strings.xml @@ -61,11 +61,17 @@ </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">"اس پرنٹر کے بارے میں مزید معلومات"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"پرنٹ کی کچھ سروسز غیر فعال ہیں۔"</string> - <string name="choose_print_service" msgid="3740309762324459694">"پرنٹ سروس منتخب کریں"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"پرنٹ کی کچھ سروسز غیر فعال ہیں"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"پرنٹرز تلاش کر رہا ہے"</string> <string name="print_no_print_services" msgid="8561247706423327966">"کوئی پرنٹ سروس فعال نہیں"</string> <string name="print_no_printers" msgid="4869403323900054866">"کوئی پرنٹرز نہيں ملے"</string> + <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="recommended_services_title" msgid="3799434882937956924">"تجویز کردہ سروسز"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"غیر فعال کردہ سروسز"</string> + <string name="all_services_title" msgid="5578662754874906455">"تمام سروسز"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> پرنٹ کررہا ہے"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g> کو منسوخ کر رہا ہے"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"پرنٹر کی خرابی <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml index 30b218e420d1..a6af5bd4ab31 100644 --- a/packages/PrintSpooler/res/values-uz-rUZ/strings.xml +++ b/packages/PrintSpooler/res/values-uz-rUZ/strings.xml @@ -61,11 +61,17 @@ </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="1205302482388937547">"Bir qancha chop etish xizmatlari o‘chirilgan."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Chop etish xizmatini tanlang"</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> + <string name="cannot_add_printer" msgid="7840348733668023106">"Printerlarni qo‘shib bo‘lmaydi"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Printer qo‘shish uchun tanlang"</string> + <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‘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> <string name="failed_notification_title_template" msgid="2256217208186530973">"Printerda xatolik: <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-vi/strings.xml b/packages/PrintSpooler/res/values-vi/strings.xml index 32aaf6396de1..df9e1a4f824d 100644 --- a/packages/PrintSpooler/res/values-vi/strings.xml +++ b/packages/PrintSpooler/res/values-vi/strings.xml @@ -61,11 +61,17 @@ </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">"Thông tin khác về máy in này"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Một số dịch vụ in bị vô hiệu hóa."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Chọn dịch vụ in"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Một số dịch vụ in đã bị tắt"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Đang tìm kiếm máy in"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Chưa kích hoạt dịch vụ in nào"</string> <string name="print_no_printers" msgid="4869403323900054866">"Không tìm thấy máy in"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Không thể thêm máy in"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Chọn để thêm máy in"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Chọn để bật"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Dịch vụ đã bật"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Dịch vụ được đề xuất"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Dịch vụ đã tắt"</string> + <string name="all_services_title" msgid="5578662754874906455">"Tất cả dịch vụ"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"In <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Hủy <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Lỗi máy in <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-zh-rCN/strings.xml b/packages/PrintSpooler/res/values-zh-rCN/strings.xml index 42cf3b14bf47..fb30e445741e 100644 --- a/packages/PrintSpooler/res/values-zh-rCN/strings.xml +++ b/packages/PrintSpooler/res/values-zh-rCN/strings.xml @@ -61,11 +61,17 @@ </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">"关于此打印机的更多信息"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"部分打印服务已停用。"</string> - <string name="choose_print_service" msgid="3740309762324459694">"选择打印服务"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"部分打印服务已停用"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"正在搜索打印机"</string> <string name="print_no_print_services" msgid="8561247706423327966">"未启用任何打印服务"</string> <string name="print_no_printers" msgid="4869403323900054866">"找不到打印机"</string> + <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="recommended_services_title" msgid="3799434882937956924">"推荐的服务"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"已停用的服务"</string> + <string name="all_services_title" msgid="5578662754874906455">"所有服务"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"正在打印“<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>”"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"正在取消打印“<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>”"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"打印机在打印“<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>”时出错"</string> diff --git a/packages/PrintSpooler/res/values-zh-rHK/strings.xml b/packages/PrintSpooler/res/values-zh-rHK/strings.xml index 0a458ada1fcf..f7c8fc911b7e 100644 --- a/packages/PrintSpooler/res/values-zh-rHK/strings.xml +++ b/packages/PrintSpooler/res/values-zh-rHK/strings.xml @@ -61,11 +61,17 @@ </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">"此打印機詳情"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"已停用部分列印服務。"</string> - <string name="choose_print_service" msgid="3740309762324459694">"選擇列印服務"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"部分列印服務已停用"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"正在搜尋打印機"</string> <string name="print_no_print_services" msgid="8561247706423327966">"沒有已啟用的列印服務"</string> <string name="print_no_printers" msgid="4869403323900054866">"找不到打印機"</string> + <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="recommended_services_title" msgid="3799434882937956924">"推薦服務"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"已停用的服務"</string> + <string name="all_services_title" msgid="5578662754874906455">"所有服務"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"正在列印 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"正在取消 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"打印機錯誤:<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-zh-rTW/strings.xml b/packages/PrintSpooler/res/values-zh-rTW/strings.xml index 7a30011ac02b..aa18f3c7f145 100644 --- a/packages/PrintSpooler/res/values-zh-rTW/strings.xml +++ b/packages/PrintSpooler/res/values-zh-rTW/strings.xml @@ -61,11 +61,17 @@ </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">"查看這台印表機的詳細資訊"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"部分列印服務已停用。"</string> - <string name="choose_print_service" msgid="3740309762324459694">"選擇列印服務"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"已停用部分列印服務"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"正在搜尋印表機"</string> <string name="print_no_print_services" msgid="8561247706423327966">"未啟用任何列印服務"</string> <string name="print_no_printers" msgid="4869403323900054866">"找不到印表機"</string> + <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="recommended_services_title" msgid="3799434882937956924">"建議的列印服務"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"已停用的列印服務"</string> + <string name="all_services_title" msgid="5578662754874906455">"所有列印服務"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"正在列印 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"正在取消 <xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"印表機發生錯誤:<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/PrintSpooler/res/values-zu/strings.xml b/packages/PrintSpooler/res/values-zu/strings.xml index f57b58c87609..9cfcb33be440 100644 --- a/packages/PrintSpooler/res/values-zu/strings.xml +++ b/packages/PrintSpooler/res/values-zu/strings.xml @@ -61,11 +61,17 @@ </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">"Olunye ulwazi mayelana nale phrinta"</string> - <string name="print_services_disabled_toast" msgid="1205302482388937547">"Amanye amasevisi wokuphrinta akhutshaziwe."</string> - <string name="choose_print_service" msgid="3740309762324459694">"Khetha isevisi yephrinta"</string> + <string name="print_services_disabled_toast" msgid="9089060734685174685">"Amanye amasevisi okuphrinta akhutshaziwe"</string> <string name="print_searching_for_printers" msgid="6550424555079932867">"Isesha amaphrinta"</string> <string name="print_no_print_services" msgid="8561247706423327966">"Amasevisi ephrinta akavuliwe."</string> <string name="print_no_printers" msgid="4869403323900054866">"Awekho amaphrinta atholiwe"</string> + <string name="cannot_add_printer" msgid="7840348733668023106">"Ayikwazi ukungeza amaphrinta"</string> + <string name="select_to_add_printers" msgid="3800709038689830974">"Khetha ukuze ungeze iphrinta"</string> + <string name="enable_print_service" msgid="3482815747043533842">"Khetha ukuze unike amandla"</string> + <string name="enabled_services_title" msgid="7036986099096582296">"Amasevisi anikwe amandla"</string> + <string name="recommended_services_title" msgid="3799434882937956924">"Amasevisi anconyiwe"</string> + <string name="disabled_services_title" msgid="7313253167968363211">"Amasevisi akhutshaziwe"</string> + <string name="all_services_title" msgid="5578662754874906455">"Onke amasevisi"</string> <string name="printing_notification_title_template" msgid="295903957762447362">"Iphrinta i-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="cancelling_notification_title_template" msgid="1821759594704703197">"Ikhansela i-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> <string name="failed_notification_title_template" msgid="2256217208186530973">"Iphutha lephrinta ye-<xliff:g id="PRINT_JOB_NAME">%1$s</xliff:g>"</string> diff --git a/packages/SettingsLib/res/layout/restricted_icon.xml b/packages/SettingsLib/res/layout/restricted_icon.xml index d57fb80c14b6..724a524ad46a 100644 --- a/packages/SettingsLib/res/layout/restricted_icon.xml +++ b/packages/SettingsLib/res/layout/restricted_icon.xml @@ -17,5 +17,4 @@ android:id="@+id/restricted_icon" android:layout_width="@dimen/restricted_icon_size" android:layout_height="@dimen/restricted_icon_size" - android:src="@drawable/ic_info" - android:gravity="end|center_vertical" />
\ No newline at end of file + android:src="@drawable/ic_info" />
\ No newline at end of file diff --git a/packages/SettingsLib/res/layout/usage_view.xml b/packages/SettingsLib/res/layout/usage_view.xml index 28981f87978f..aa1a046974f0 100644 --- a/packages/SettingsLib/res/layout/usage_view.xml +++ b/packages/SettingsLib/res/layout/usage_view.xml @@ -22,7 +22,8 @@ <LinearLayout android:id="@+id/graph_label_group" android:layout_width="match_parent" - android:layout_height="@dimen/usage_graph_area_height" + android:layout_height="0dp" + android:layout_weight="1" android:orientation="horizontal" android:clipChildren="false" android:clipToPadding="false"> @@ -37,6 +38,7 @@ layout="@layout/usage_side_label" /> <Space + android:id="@+id/space1" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" /> @@ -45,6 +47,7 @@ layout="@layout/usage_side_label" /> <Space + android:id="@+id/space2" android:layout_width="wrap_content" android:layout_height="0dp" android:layout_weight="1" /> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index ef397f664407..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> @@ -775,7 +775,7 @@ <!-- Summary for switch preference to denote it is switched on [CHAR LIMIT=50] --> <string name="enabled_by_admin">Enabled by administrator</string> - <!-- Summary for switch preference to denote it is switched on [CHAR LIMIT=50] --> + <!-- Summary for switch preference to denote it is switched off [CHAR LIMIT=50] --> <string name="disabled_by_admin">Disabled by administrator</string> <!-- Option in navigation drawer that leads to Settings main screen [CHAR LIMIT=30] --> diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java index d0c249f94740..1f1a9b81ed48 100644 --- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java @@ -651,8 +651,11 @@ public class RestrictedLockUtils { final int disabledColor = context.getColor(R.color.disabled_text_color); sb.setSpan(new ForegroundColorSpan(disabledColor), 0, sb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - final ImageSpan image = new RestrictedLockImageSpan(context); - sb.append(" ", image, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); + textView.setCompoundDrawables(null, null, getRestrictedPadlock(context), null); + textView.setCompoundDrawablePadding(context.getResources().getDimensionPixelSize( + R.dimen.restricted_icon_padding)); + } else { + textView.setCompoundDrawables(null, null, null, null); } textView.setText(sb); } diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java index 0c0af243ff7b..47023c108eab 100644 --- a/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java +++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedPreferenceHelper.java @@ -22,9 +22,6 @@ import android.graphics.drawable.Drawable; import android.os.UserHandle; import android.support.v7.preference.Preference; import android.support.v7.preference.PreferenceViewHolder; -import android.text.Spanned; -import android.text.SpannableStringBuilder; -import android.text.style.ImageSpan; import android.util.AttributeSet; import android.util.TypedValue; import android.view.View; @@ -39,8 +36,6 @@ import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin; public class RestrictedPreferenceHelper { private final Context mContext; private final Preference mPreference; - private final Drawable mRestrictedPadlock; - private final int mRestrictedPadlockPadding; private boolean mDisabledByAdmin; private EnforcedAdmin mEnforcedAdmin; @@ -52,10 +47,6 @@ public class RestrictedPreferenceHelper { mContext = context; mPreference = preference; - mRestrictedPadlock = RestrictedLockUtils.getRestrictedPadlock(mContext); - mRestrictedPadlockPadding = mContext.getResources().getDimensionPixelSize( - R.dimen.restricted_icon_padding); - if (attrs != null) { final TypedArray attributes = context.obtainStyledAttributes(attrs, R.styleable.RestrictedPreference); @@ -154,10 +145,10 @@ public class RestrictedPreferenceHelper { */ public boolean setDisabledByAdmin(EnforcedAdmin admin) { final boolean disabled = (admin != null ? true : false); - mEnforcedAdmin = (disabled ? admin : null); + mEnforcedAdmin = admin; + mPreference.setEnabled(!disabled); if (mDisabledByAdmin != disabled) { mDisabledByAdmin = disabled; - mPreference.setEnabled(!disabled); return true; } return false; diff --git a/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java b/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java index 92689941f222..fcff305e2daa 100644 --- a/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/accessibility/AccessibilityUtils.java @@ -145,11 +145,6 @@ public class AccessibilityUtils { Settings.Secure.putStringForUser(context.getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, enabledServicesBuilder.toString(), userId); - - // Update accessibility enabled. - Settings.Secure.putIntForUser(context.getContentResolver(), - Settings.Secure.ACCESSIBILITY_ENABLED, accessibilityEnabled ? 1 : 0, - userId); } private static Set<ComponentName> getInstalledServices(Context context) { diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java b/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java index 530ec16d5cca..1fff0fbb3f61 100644 --- a/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java +++ b/packages/SettingsLib/src/com/android/settingslib/graph/UsageGraph.java @@ -43,6 +43,7 @@ public class UsageGraph extends View { private final Paint mDottedPaint; private final Drawable mDivider; + private final Drawable mTintedDivider; private final int mDividerSize; private final Path mPath = new Path(); @@ -51,6 +52,7 @@ public class UsageGraph extends View { private final SparseIntArray mPaths = new SparseIntArray(); // Paths in local coordinates for drawing. private final SparseIntArray mLocalPaths = new SparseIntArray(); + private final int mCornerRadius; private int mAccentColor; private boolean mShowProjection; @@ -59,6 +61,10 @@ public class UsageGraph extends View { private float mMaxX = 100; private float mMaxY = 100; + private float mMiddleDividerLoc = .5f; + private int mMiddleDividerTint = -1; + private int mTopDividerTint = -1; + public UsageGraph(Context context, @Nullable AttributeSet attrs) { super(context, attrs); final Resources resources = context.getResources(); @@ -68,8 +74,8 @@ public class UsageGraph extends View { mLinePaint.setStrokeCap(Cap.ROUND); mLinePaint.setStrokeJoin(Join.ROUND); mLinePaint.setAntiAlias(true); - mLinePaint.setPathEffect(new CornerPathEffect(resources.getDimensionPixelSize( - R.dimen.usage_graph_line_corner_radius))); + mCornerRadius = resources.getDimensionPixelSize(R.dimen.usage_graph_line_corner_radius); + mLinePaint.setPathEffect(new CornerPathEffect(mCornerRadius)); mLinePaint.setStrokeWidth(resources.getDimensionPixelSize(R.dimen.usage_graph_line_width)); mFillPaint = new Paint(mLinePaint); @@ -86,6 +92,7 @@ public class UsageGraph extends View { TypedValue v = new TypedValue(); context.getTheme().resolveAttribute(com.android.internal.R.attr.listDivider, v, true); mDivider = context.getDrawable(v.resourceId); + mTintedDivider = context.getDrawable(v.resourceId); mDividerSize = resources.getDimensionPixelSize(R.dimen.usage_graph_divider_size); } @@ -98,6 +105,15 @@ public class UsageGraph extends View { mMaxY = maxY; } + void setDividerLoc(int height) { + mMiddleDividerLoc = 1 - height / mMaxY; + } + + void setDividerColors(int middleColor, int topColor) { + mMiddleDividerTint = middleColor; + mTopDividerTint = topColor; + } + public void addPath(SparseIntArray points) { for (int i = 0; i < points.size(); i++) { mPaths.put(points.keyAt(i), points.valueAt(i)); @@ -150,7 +166,7 @@ public class UsageGraph extends View { if (mLocalPaths.size() > 0) { int lastX = mLocalPaths.keyAt(mLocalPaths.size() - 1); int lastY = mLocalPaths.valueAt(mLocalPaths.size() - 1); - if (lastY != PATH_DELIM && (lastX == lx || lastY == ly)) { + if (lastY != PATH_DELIM && !hasDiff(lastX, lx) && !hasDiff(lastY, ly)) { pendingYLoc = ly; continue; } @@ -160,6 +176,10 @@ public class UsageGraph extends View { } } + private boolean hasDiff(int x1, int x2) { + return Math.abs(x2 - x1) >= mCornerRadius; + } + private int getX(float x) { return (int) (x / mMaxX * getWidth()); } @@ -180,9 +200,12 @@ public class UsageGraph extends View { @Override protected void onDraw(Canvas canvas) { // Draw lines across the top, middle, and bottom. - drawDivider(0, canvas); - drawDivider((canvas.getHeight() - mDividerSize) / 2, canvas); - drawDivider(canvas.getHeight() - mDividerSize, canvas); + if (mMiddleDividerLoc != 0) { + drawDivider(0, canvas, mTopDividerTint); + } + drawDivider((int) ((canvas.getHeight() - mDividerSize) * mMiddleDividerLoc), canvas, + mMiddleDividerTint); + drawDivider(canvas.getHeight() - mDividerSize, canvas, -1); if (mLocalPaths.size() == 0) { return; @@ -242,8 +265,13 @@ public class UsageGraph extends View { canvas.drawPath(mPath, mFillPaint); } - private void drawDivider(int y, Canvas canvas) { - mDivider.setBounds(0, y, canvas.getWidth(), y + mDividerSize); - mDivider.draw(canvas); + private void drawDivider(int y, Canvas canvas, int tintColor) { + Drawable d = mDivider; + if (tintColor != -1) { + mTintedDivider.setTint(tintColor); + d = mTintedDivider; + } + d.setBounds(0, y, canvas.getWidth(), y + mDividerSize); + d.draw(canvas); } } diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java b/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java index f95a97ad0072..ee1821dc6bbe 100644 --- a/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java +++ b/packages/SettingsLib/src/com/android/settingslib/graph/UsageView.java @@ -20,6 +20,7 @@ import android.util.AttributeSet; import android.util.SparseIntArray; import android.view.Gravity; import android.view.LayoutInflater; +import android.view.View; import android.widget.FrameLayout; import android.widget.LinearLayout; import android.widget.TextView; @@ -98,6 +99,26 @@ public class UsageView extends FrameLayout { mUsageGraph.setAccentColor(color); } + public void setDividerLoc(int dividerLoc) { + mUsageGraph.setDividerLoc(dividerLoc); + } + + public void setDividerColors(int middleColor, int topColor) { + mUsageGraph.setDividerColors(middleColor, topColor); + } + + public void setSideLabelWeights(float before, float after) { + setWeight(R.id.space1, before); + setWeight(R.id.space2, after); + } + + private void setWeight(int id, float weight) { + View v = findViewById(id); + LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) v.getLayoutParams(); + params.weight = weight; + v.setLayoutParams(params); + } + public void setSideLabels(CharSequence[] labels) { if (labels.length != mLabels.length) { throw new IllegalArgumentException("Invalid number of labels"); diff --git a/packages/SettingsProvider/res/values-bs-rBA/defaults.xml b/packages/SettingsProvider/res/values-bs-rBA/defaults.xml index 5650077f403f..4a87a1250404 100644 --- a/packages/SettingsProvider/res/values-bs-rBA/defaults.xml +++ b/packages/SettingsProvider/res/values-bs-rBA/defaults.xml @@ -19,9 +19,7 @@ <resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- no translation found for def_device_name (6309317409634339402) --> - <skip /> - <!-- no translation found for def_device_name_simple (9037785625140748221) --> - <skip /> + <string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string> + <string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string> <string name="def_nfc_payment_component" msgid="5861297439873026958"></string> </resources> diff --git a/packages/Shell/res/values-af/strings.xml b/packages/Shell/res/values-af/strings.xml index f86b551f90e3..8dbe3cdc1e7b 100644 --- a/packages/Shell/res/values-af/strings.xml +++ b/packages/Shell/res/values-af/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Tuisskerm"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Foutverslag <xliff:g id="ID">#%d</xliff:g> word tans geskep"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Foutverslag <xliff:g id="ID">#%d</xliff:g> is vasgevang"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Foutverslag <xliff:g id="ID">#%d</xliff:g> vasgevang, maar skermkiekie hangende"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Voeg tans besonderhede by die foutverslag"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Wag asseblief …"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Swiep na links om jou foutverslag te deel"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tik om jou foutverslag te deel"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Tik om jou foutverslag sonder \'n skermkiekie te deel, of wag totdat die skermkiekie gereed is"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Tik om jou foutverslag sonder \'n skermkiekie te deel, of wag totdat die skermkiekie gereed is"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Foutverslae bevat data van die stelsel se verskillende loglêers af, insluitend persoonlike en private inligting. Deel foutverslae net met programme en mense wat jy vertrou."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Wys hierdie boodskap volgende keer"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Foutverslae"</string> diff --git a/packages/Shell/res/values-am/strings.xml b/packages/Shell/res/values-am/strings.xml index 55c5390cebf3..b0d3de08fe42 100644 --- a/packages/Shell/res/values-am/strings.xml +++ b/packages/Shell/res/values-am/strings.xml @@ -19,10 +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_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_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-ar/strings.xml b/packages/Shell/res/values-ar/strings.xml index f0af8ce9dbfb..818c3682b790 100644 --- a/packages/Shell/res/values-ar/strings.xml +++ b/packages/Shell/res/values-ar/strings.xml @@ -19,10 +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> + <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_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 6d375fe78c67..22791a6ef639 100644 --- a/packages/Shell/res/values-az-rAZ/strings.xml +++ b/packages/Shell/res/values-az-rAZ/strings.xml @@ -19,10 +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> + <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> + <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-b+sr+Latn/strings.xml b/packages/Shell/res/values-b+sr+Latn/strings.xml index ad8494100534..bc5ce26bff18 100644 --- a/packages/Shell/res/values-b+sr+Latn/strings.xml +++ b/packages/Shell/res/values-b+sr+Latn/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Izveštaj o grešci <xliff:g id="ID">#%d</xliff:g> se generiše"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Izveštaj o grešci <xliff:g id="ID">#%d</xliff:g> je snimljen"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Izveštaj o grešci <xliff:g id="ID">#%d</xliff:g> snimljen; snimak ekrana se čeka"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodaju se detalji u izveštaj o grešci"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Sačekajte..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Prevucite ulevo da biste delili izveštaj o greškama"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste delili izveštaj o grešci"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite za deljenje izveštaja o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite za deljenje izveštaja o grešci bez snimka ekrana ili sačekajte da se napravi snimak ekrana"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Izveštaji o greškama sadrže podatke iz različitih sistemskih datoteka evidencije, uključujući lične i privatne podatke. Delite izveštaje o greškama samo sa aplikacijama i ljudima u koje imate poverenja."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Prikaži ovu poruku sledeći put"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Izveštaji o greškama"</string> diff --git a/packages/Shell/res/values-bg/strings.xml b/packages/Shell/res/values-bg/strings.xml index e5438395c487..0f8676f1787c 100644 --- a/packages/Shell/res/values-bg/strings.xml +++ b/packages/Shell/res/values-bg/strings.xml @@ -19,10 +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_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_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-bn-rBD/strings.xml b/packages/Shell/res/values-bn-rBD/strings.xml index bba778d6a0c0..c632b10b49d9 100644 --- a/packages/Shell/res/values-bn-rBD/strings.xml +++ b/packages/Shell/res/values-bn-rBD/strings.xml @@ -19,10 +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_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_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 54be9551195f..f4d71e910676 100644 --- a/packages/Shell/res/values-bs-rBA/strings.xml +++ b/packages/Shell/res/values-bs-rBA/strings.xml @@ -19,10 +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> + <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> + <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 a92177e2b072..3efb53b99cc3 100644 --- a/packages/Shell/res/values-ca/strings.xml +++ b/packages/Shell/res/values-ca/strings.xml @@ -19,10 +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> + <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> + <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 6f7549ac817e..afb6f9e8b5cb 100644 --- a/packages/Shell/res/values-cs/strings.xml +++ b/packages/Shell/res/values-cs/strings.xml @@ -19,10 +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> + <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> + <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-da/strings.xml b/packages/Shell/res/values-da/strings.xml index 72a9a99680ce..0f7b784741fa 100644 --- a/packages/Shell/res/values-da/strings.xml +++ b/packages/Shell/res/values-da/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Fejlrapporten <xliff:g id="ID">#%d</xliff:g> genereres"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Fejrapporten <xliff:g id="ID">#%d</xliff:g> blev gemt"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Fejlrapport <xliff:g id="ID">#%d</xliff:g> blev gemt, men skærmbilledet afventer"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Tilføjelse af oplysninger til fejlrapporten"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Vent et øjeblik…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Stryg til venstre for at dele din fejlrapport"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tryk for at dele din fejlrapport"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Tryk for at dele din fejlrapport uden et skærmbillede, eller vent på, at skærmbilledet fuldføres"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Tryk for at dele din fejlrapport uden et skærmbillede, eller vent på, at skærmbilledet fuldføres"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Fejlrapporter indeholder data fra systemets forskellige logfiler, f.eks. personlige og private oplysninger. Del kun fejlrapporter med apps og personer, du har tillid til."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Vis denne underretning næste gang"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Fejlrapporter"</string> diff --git a/packages/Shell/res/values-de/strings.xml b/packages/Shell/res/values-de/strings.xml index f848c9d32a2a..8f87fed652dc 100644 --- a/packages/Shell/res/values-de/strings.xml +++ b/packages/Shell/res/values-de/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Fehlerbericht <xliff:g id="ID">#%d</xliff:g> wird generiert"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Fehlerbericht <xliff:g id="ID">#%d</xliff:g> erfasst"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Fehlerbericht <xliff:g id="ID">#%d</xliff:g> erfasst, aber Screenshot ausstehend"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Informationen werden zum Fehlerbericht hinzugefügt"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Bitte warten…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Wische nach links, um deinen Fehlerbericht zu teilen."</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Zum Teilen des Fehlerberichts tippen"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Tippe, um den Fehlerbericht ohne Screenshot zu teilen, oder warte auf den Screenshot"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Tippe, um den Fehlerbericht ohne Screenshot zu teilen, oder warte auf den Screenshot"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Fehlerberichte enthalten Daten aus verschiedenen Protokolldateien des Systems, darunter auch personenbezogene und private Daten. Teile Fehlerberichte nur mit Apps und Personen, denen du vertraust."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Diese Nachricht nächstes Mal zeigen"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Fehlerberichte"</string> diff --git a/packages/Shell/res/values-el/strings.xml b/packages/Shell/res/values-el/strings.xml index 0c04809dc1e6..517d83af8d5d 100644 --- a/packages/Shell/res/values-el/strings.xml +++ b/packages/Shell/res/values-el/strings.xml @@ -19,10 +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_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_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-en-rAU/strings.xml b/packages/Shell/res/values-en-rAU/strings.xml index ad637f530cba..2349ec598313 100644 --- a/packages/Shell/res/values-en-rAU/strings.xml +++ b/packages/Shell/res/values-en-rAU/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Bug report <xliff:g id="ID">#%d</xliff:g> is being generated"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Bug report <xliff:g id="ID">#%d</xliff:g> captured"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Bug report <xliff:g id="ID">#%d</xliff:g> captured but screenshot pending"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Adding details to the bug report"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Please wait…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Swipe left to share your bug report"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tap to share your bug report"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Tap to share your bug report without a screenshot or wait for the screenshot to finish"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Tap to share your bug report without a screenshot or wait for the screenshot to finish"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Bug reports contain data from the system\'s various log files, including personal and private information. Only share bug reports with apps and people that you trust."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Show this message next time"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Bug reports"</string> diff --git a/packages/Shell/res/values-en-rGB/strings.xml b/packages/Shell/res/values-en-rGB/strings.xml index ad637f530cba..2349ec598313 100644 --- a/packages/Shell/res/values-en-rGB/strings.xml +++ b/packages/Shell/res/values-en-rGB/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Bug report <xliff:g id="ID">#%d</xliff:g> is being generated"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Bug report <xliff:g id="ID">#%d</xliff:g> captured"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Bug report <xliff:g id="ID">#%d</xliff:g> captured but screenshot pending"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Adding details to the bug report"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Please wait…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Swipe left to share your bug report"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tap to share your bug report"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Tap to share your bug report without a screenshot or wait for the screenshot to finish"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Tap to share your bug report without a screenshot or wait for the screenshot to finish"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Bug reports contain data from the system\'s various log files, including personal and private information. Only share bug reports with apps and people that you trust."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Show this message next time"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Bug reports"</string> diff --git a/packages/Shell/res/values-en-rIN/strings.xml b/packages/Shell/res/values-en-rIN/strings.xml index ad637f530cba..2349ec598313 100644 --- a/packages/Shell/res/values-en-rIN/strings.xml +++ b/packages/Shell/res/values-en-rIN/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Bug report <xliff:g id="ID">#%d</xliff:g> is being generated"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Bug report <xliff:g id="ID">#%d</xliff:g> captured"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Bug report <xliff:g id="ID">#%d</xliff:g> captured but screenshot pending"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Adding details to the bug report"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Please wait…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Swipe left to share your bug report"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tap to share your bug report"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Tap to share your bug report without a screenshot or wait for the screenshot to finish"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Tap to share your bug report without a screenshot or wait for the screenshot to finish"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Bug reports contain data from the system\'s various log files, including personal and private information. Only share bug reports with apps and people that you trust."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Show this message next time"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Bug reports"</string> diff --git a/packages/Shell/res/values-es-rUS/strings.xml b/packages/Shell/res/values-es-rUS/strings.xml index a9a1e08c12b8..307548a75140 100644 --- a/packages/Shell/res/values-es-rUS/strings.xml +++ b/packages/Shell/res/values-es-rUS/strings.xml @@ -19,10 +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> + <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> + <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-es/strings.xml b/packages/Shell/res/values-es/strings.xml index b82d372f408a..68abf83b4ed8 100644 --- a/packages/Shell/res/values-es/strings.xml +++ b/packages/Shell/res/values-es/strings.xml @@ -19,10 +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">"Informe de errores <xliff:g id="ID">#%d</xliff:g> capturado"</string> + <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">"Añadiendo 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 error"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toca para compartir el informe de errores"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toca para compartir informe de errores sin captura de pantalla o espera a que se haga la captura."</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toca para compartir informe de errores sin captura de pantalla o espera a que se haga la captura."</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Los informes de errores contienen datos de los distintos archivos de registro del sistema, incluida información personal y privada. Comparte los informes de errores únicamente con aplicaciones y usuarios en los 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 error"</string> diff --git a/packages/Shell/res/values-et-rEE/strings.xml b/packages/Shell/res/values-et-rEE/strings.xml index cdb774a04eaf..028e2bdce55f 100644 --- a/packages/Shell/res/values-et-rEE/strings.xml +++ b/packages/Shell/res/values-et-rEE/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Kest"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Luuakse veaaruannet <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Jäädvustati veaaruanne <xliff:g id="ID">#%d</xliff:g>"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Jäädvustati veaaruanne <xliff:g id="ID">#%d</xliff:g>, kuid ekraanipilt on ootel"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Üksikasjade lisamine veaaruandesse"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Oodake …"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Veaaruande jagamiseks pühkige vasakule"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Veaaruande jagamiseks puudutage"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Puudutage, et veaaruannet ilma ekraanipildita jagada, või oodake, kuni ekraanipilt tehtud saab."</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Puudutage, et veaaruannet ilma ekraanipildita jagada, või oodake, kuni ekraanipilt tehtud saab."</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Veaaruanded sisaldavad andmeid erinevatest süsteemi logifailidest, sh isiklikku ja privaatset teavet. Jagage veaaruandeid ainult usaldusväärsete rakenduste ja inimestega."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Kuva see sõnum järgmisel korral"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Veaaruanded"</string> diff --git a/packages/Shell/res/values-eu-rES/strings.xml b/packages/Shell/res/values-eu-rES/strings.xml index 42dfe276640c..7946f67aee92 100644 --- a/packages/Shell/res/values-eu-rES/strings.xml +++ b/packages/Shell/res/values-eu-rES/strings.xml @@ -19,10 +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> + <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> + <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 e825f3a41916..ecadf1a8fac6 100644 --- a/packages/Shell/res/values-fa/strings.xml +++ b/packages/Shell/res/values-fa/strings.xml @@ -19,10 +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> + <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_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 8c67c664f90a..b5ae006a8487 100644 --- a/packages/Shell/res/values-fi/strings.xml +++ b/packages/Shell/res/values-fi/strings.xml @@ -19,10 +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> + <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> + <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 3daa12034e9d..6c40edd4cea3 100644 --- a/packages/Shell/res/values-fr-rCA/strings.xml +++ b/packages/Shell/res/values-fr-rCA/strings.xml @@ -19,10 +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> + <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> + <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 c512aca85155..54f0b98c08f3 100644 --- a/packages/Shell/res/values-fr/strings.xml +++ b/packages/Shell/res/values-fr/strings.xml @@ -19,10 +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> + <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> + <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-gl-rES/strings.xml b/packages/Shell/res/values-gl-rES/strings.xml index ea95c970b3c3..e462ceefcfe2 100644 --- a/packages/Shell/res/values-gl-rES/strings.xml +++ b/packages/Shell/res/values-gl-rES/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Estase xerando o informe de erros <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Rexistrouse o informe de erros <xliff:g id="ID">#%d</xliff:g>"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Inf. erros rexistrado <xliff:g id="ID">#%d</xliff:g> e captura pantalla pendente"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Engadindo detalles ao informe de erro"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Agarda..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Pasa o dedo á esquerda para compartir o teu informe de erros"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toca para compartir o teu informe de erros"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toca para compartir o informe de erros sen captura de pantalla ou agarda a que finalice a captura"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toca para compartir o informe de erros sen captura de pantalla ou agarda a que finalice a captura"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Os informes de erros conteñen datos dos distintos ficheiros de rexistro do sistema, incluída información persoal e privada. Comparte os informes de erros unicamente con aplicacións e persoas de confianza."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostrar esta mensaxe a próxima vez"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Informes de erros"</string> diff --git a/packages/Shell/res/values-gu-rIN/strings.xml b/packages/Shell/res/values-gu-rIN/strings.xml index 1436c3d70399..f99167dd34b3 100644 --- a/packages/Shell/res/values-gu-rIN/strings.xml +++ b/packages/Shell/res/values-gu-rIN/strings.xml @@ -19,10 +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_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_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-hi/strings.xml b/packages/Shell/res/values-hi/strings.xml index 9a735f2451b5..aedec0482a5b 100644 --- a/packages/Shell/res/values-hi/strings.xml +++ b/packages/Shell/res/values-hi/strings.xml @@ -19,10 +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_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_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-hr/strings.xml b/packages/Shell/res/values-hr/strings.xml index 71d50b8a5589..462eb2a1313c 100644 --- a/packages/Shell/res/values-hr/strings.xml +++ b/packages/Shell/res/values-hr/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Ljuska"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Generira se izvješće o programskoj pogrešci <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Izvješće o programskoj pogrešci <xliff:g id="ID">#%d</xliff:g> snimljeno"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Izvješće o pogrešci <xliff:g id="ID">#%d</xliff:g> snimljeno, ali se čeka snimka"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodavanje pojedinosti u izvješće o progr. pogrešci"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Pričekajte..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Prijeđite prstom ulijevo da biste poslali izvješće o programskim pogreškama"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Dodirnite da biste podijelili izvješće o programskoj pogrešci"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Dodirnite za dijeljenje izvješća o pogrešci bez snimke zaslona ili pričekajte da se izradi snimka"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Dodirnite za dijeljenje izvješća o pogrešci bez snimke zaslona ili pričekajte da se izradi snimka"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Prijave programskih pogrešaka sadržavaju podatke iz različitih datoteka zapisnika sustava, uključujući osobne i privatne informacije. Prijave programskih pogrešaka dijelite samo s aplikacijama i osobama koje smatrate pouzdanima."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Prikaži tu poruku sljedeći put"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Izvj. o prog. pogreš."</string> diff --git a/packages/Shell/res/values-hu/strings.xml b/packages/Shell/res/values-hu/strings.xml index cf1031569379..1f7f1fac4d5a 100644 --- a/packages/Shell/res/values-hu/strings.xml +++ b/packages/Shell/res/values-hu/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Héj"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Hibajelentés (<xliff:g id="ID">#%d</xliff:g>) létrehozása folyamatban"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Hibajelentés (<xliff:g id="ID">#%d</xliff:g>) rögzítve"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Hibajelentés (<xliff:g id="ID">#%d</xliff:g>) rögzítve – képernyőkép függőben"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Információk hozzáadása a hibajelentéshez"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Kérjük, várjon..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Húzza ujját balra a hibajelentés megosztásához"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Koppintson a hibajelentés megosztásához"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Koppintson ide, ha képernyőkép nélkül osztaná meg a hibajelentést, vagy várjon a képernyőképre."</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Koppintson ide, ha képernyőkép nélkül osztaná meg a hibajelentést, vagy várjon a képernyőképre."</string> <string name="bugreport_confirm" msgid="5130698467795669780">"A programhiba-jelentések a rendszer különféle naplófájljaiból származó adatokat tartalmaznak, köztük személyes és magánjellegű információkat is. Csak olyan alkalmazásokkal és személyekkel osszon meg programhiba-jelentéseket, amelyekben vagy akikben megbízik."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Üzenet mutatása legközelebb"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Hibajelentések"</string> diff --git a/packages/Shell/res/values-hy-rAM/strings.xml b/packages/Shell/res/values-hy-rAM/strings.xml index 1cf5c944ebe8..c9351c2de692 100644 --- a/packages/Shell/res/values-hy-rAM/strings.xml +++ b/packages/Shell/res/values-hy-rAM/strings.xml @@ -19,10 +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_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_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-in/strings.xml b/packages/Shell/res/values-in/strings.xml index 1e8fe872a2d5..4bca166518c9 100644 --- a/packages/Shell/res/values-in/strings.xml +++ b/packages/Shell/res/values-in/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Kerangka"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Laporan bug <xliff:g id="ID">#%d</xliff:g> sedang dibuat"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Laporan bug <xliff:g id="ID">#%d</xliff:g> dijepret"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Laporan bug <xliff:g id="ID">#%d</xliff:g> dijepret, tetapi tangkapan layar belum selesai"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Menambahkan detail ke laporan bug"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Harap tunggu..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Gesek ke kiri untuk membagikan laporan bug Anda"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Ketuk untuk membagikan laporan bug"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Ketuk untuk membagikan laporan bug tanpa tangkapan layar atau menunggu tangkapan layar selesai"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Ketuk untuk membagikan laporan bug tanpa tangkapan layar atau menunggu tangkapan layar selesai"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Laporan bug berisi data dari berbagai file log sistem, termasuk informasi pribadi dan rahasia. Hanya bagikan laporan bug dengan aplikasi dan orang yang Anda percaya."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Tampilkan pesan ini lain kali"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Laporan bug"</string> diff --git a/packages/Shell/res/values-is-rIS/strings.xml b/packages/Shell/res/values-is-rIS/strings.xml index afcea592c24d..aedf3bc3454d 100644 --- a/packages/Shell/res/values-is-rIS/strings.xml +++ b/packages/Shell/res/values-is-rIS/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Skipanalína"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Verið er að búa til villutilkynningu <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Villutilkynning <xliff:g id="ID">#%d</xliff:g> búin til"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Villuskýrsla <xliff:g id="ID">#%d</xliff:g> tilbúin en skjámynd í vinnslu"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Bætir upplýsingum við villutilkynningu"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Augnablik..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Strjúktu til vinstri til að deila villuskýrslunni"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Ýttu til að deila villutilkynningunni"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Ýttu til að deila villutilkynningunni án skjámyndar eða hinkraðu þangað til skjámyndin er tilbúin"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Ýttu til að deila villutilkynningunni án skjámyndar eða hinkraðu þangað til skjámyndin er tilbúin"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Villutilkynningar innihalda gögn úr hinum ýmsu annálsskrám kerfisins, þ. á m. persónuleg gögn og trúnaðarupplýsingar. Deildu villutilkynningum eingöngu með forritum og fólki sem þú treystir."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Sýna þessi skilaboð næst"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Villutilkynningar"</string> diff --git a/packages/Shell/res/values-it/strings.xml b/packages/Shell/res/values-it/strings.xml index d7ac9a52fbf2..d7d62e298680 100644 --- a/packages/Shell/res/values-it/strings.xml +++ b/packages/Shell/res/values-it/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Generazione segnalazione di bug <xliff:g id="ID">#%d</xliff:g> in corso"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Segnalazione di bug <xliff:g id="ID">#%d</xliff:g> acquisita"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Segnalazione di bug <xliff:g id="ID">#%d</xliff:g> acquisita, screenshot in attesa"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Aggiunta di dettagli alla segnalazione di bug"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Attendi..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Scorri verso sinistra per condividere il rapporto sui bug"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tocca per condividere la segnalazione di bug"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Tocca per condividere la segnalazione di bug senza screenshot o attendi che lo screenshot sia completo"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Tocca per condividere la segnalazione di bug senza screenshot o attendi che lo screenshot sia completo"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Le segnalazioni di bug contengono dati da vari file di log del sistema, incluse informazioni personali e private. Condividi le segnalazioni di bug solo con app e persone attendibili."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Mostra questo messaggio la prossima volta"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Rapporti sui bug"</string> diff --git a/packages/Shell/res/values-iw/strings.xml b/packages/Shell/res/values-iw/strings.xml index fd64ee1991a2..6589c8b63019 100644 --- a/packages/Shell/res/values-iw/strings.xml +++ b/packages/Shell/res/values-iw/strings.xml @@ -19,10 +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_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_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 050c5dfa093a..a6ff33eef24f 100644 --- a/packages/Shell/res/values-ja/strings.xml +++ b/packages/Shell/res/values-ja/strings.xml @@ -19,10 +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_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_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 8c5c6fbcb2aa..119c360e2c06 100644 --- a/packages/Shell/res/values-ka-rGE/strings.xml +++ b/packages/Shell/res/values-ka-rGE/strings.xml @@ -19,10 +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_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_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 edb2dd0107f6..9c2e4e73f346 100644 --- a/packages/Shell/res/values-kk-rKZ/strings.xml +++ b/packages/Shell/res/values-kk-rKZ/strings.xml @@ -19,10 +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_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_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 ba0de9f4e097..d5fc400c46bb 100644 --- a/packages/Shell/res/values-km-rKH/strings.xml +++ b/packages/Shell/res/values-km-rKH/strings.xml @@ -19,10 +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_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_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-kn-rIN/strings.xml b/packages/Shell/res/values-kn-rIN/strings.xml index b041f3534d85..1331f7e86eb0 100644 --- a/packages/Shell/res/values-kn-rIN/strings.xml +++ b/packages/Shell/res/values-kn-rIN/strings.xml @@ -19,10 +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_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_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 2a863608e2fd..4c0a16988eff 100644 --- a/packages/Shell/res/values-ko/strings.xml +++ b/packages/Shell/res/values-ko/strings.xml @@ -19,10 +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_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_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 c701b7e7cf78..e4039fe8c78e 100644 --- a/packages/Shell/res/values-ky-rKG/strings.xml +++ b/packages/Shell/res/values-ky-rKG/strings.xml @@ -19,10 +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_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_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 43482502ea2b..28045286ec89 100644 --- a/packages/Shell/res/values-lo-rLA/strings.xml +++ b/packages/Shell/res/values-lo-rLA/strings.xml @@ -19,10 +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> + <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_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 a714efc30f3e..a8468cfadcee 100644 --- a/packages/Shell/res/values-lt/strings.xml +++ b/packages/Shell/res/values-lt/strings.xml @@ -19,10 +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> + <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> + <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 880d65195f24..08e25be530da 100644 --- a/packages/Shell/res/values-lv/strings.xml +++ b/packages/Shell/res/values-lv/strings.xml @@ -19,10 +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> + <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> + <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 478c189ee4dd..3f879b7e7c43 100644 --- a/packages/Shell/res/values-mk-rMK/strings.xml +++ b/packages/Shell/res/values-mk-rMK/strings.xml @@ -19,10 +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_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_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 70e63332a4d4..3bb715d822d1 100644 --- a/packages/Shell/res/values-ml-rIN/strings.xml +++ b/packages/Shell/res/values-ml-rIN/strings.xml @@ -19,10 +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_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_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 49196a286a57..296afabf8ff5 100644 --- a/packages/Shell/res/values-mn-rMN/strings.xml +++ b/packages/Shell/res/values-mn-rMN/strings.xml @@ -19,10 +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_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_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-mr-rIN/strings.xml b/packages/Shell/res/values-mr-rIN/strings.xml index 19a8706d77e4..8eb56866969c 100644 --- a/packages/Shell/res/values-mr-rIN/strings.xml +++ b/packages/Shell/res/values-mr-rIN/strings.xml @@ -19,10 +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_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_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 c9f53753325f..e758745f4e78 100644 --- a/packages/Shell/res/values-ms-rMY/strings.xml +++ b/packages/Shell/res/values-ms-rMY/strings.xml @@ -19,10 +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> + <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> + <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 4250edae8579..6f02e70a3cdc 100644 --- a/packages/Shell/res/values-my-rMM/strings.xml +++ b/packages/Shell/res/values-my-rMM/strings.xml @@ -19,10 +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_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_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-nb/strings.xml b/packages/Shell/res/values-nb/strings.xml index aa86ae4de5a5..0605e0e821ae 100644 --- a/packages/Shell/res/values-nb/strings.xml +++ b/packages/Shell/res/values-nb/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Kommandoliste"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Feilrapporten <xliff:g id="ID">#%d</xliff:g> blir generert"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Feilrapporten <xliff:g id="ID">#%d</xliff:g> er fullført"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Feilrapporten <xliff:g id="ID">#%d</xliff:g> er hentet. Venter på skjermdumpen"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Legger til detaljer i feilrapporten"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Vent litt"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Sveip til venstre for å dele feilrapporten din"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Trykk for å dele feilrapporten"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Trykk for å dele feilrapporten uten noen skjermdump, eller vent til skjermdumpen er klar"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Trykk for å dele feilrapporten uten noen skjermdump, eller vent til skjermdumpen er klar"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Feilrapporter inkluderer data fra systemets forskjellige loggfiler. Dette omfatter personlig og privat informasjon. Du bør bare dele feilrapporter med apper og folk du stoler på."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Vis denne meldingen neste gang"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Feilrapporter"</string> diff --git a/packages/Shell/res/values-ne-rNP/strings.xml b/packages/Shell/res/values-ne-rNP/strings.xml index 43c2a5ca37fc..9fb1bcbb2bdd 100644 --- a/packages/Shell/res/values-ne-rNP/strings.xml +++ b/packages/Shell/res/values-ne-rNP/strings.xml @@ -19,10 +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_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_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-nl/strings.xml b/packages/Shell/res/values-nl/strings.xml index 01fd57700e62..3022691520f4 100644 --- a/packages/Shell/res/values-nl/strings.xml +++ b/packages/Shell/res/values-nl/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Bugrapport <xliff:g id="ID">#%d</xliff:g> wordt gegenereerd"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Bugrapport <xliff:g id="ID">#%d</xliff:g> is vastgelegd"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Bugrapport <xliff:g id="ID">#%d</xliff:g> vastgelegd, screenshot in behandeling"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Details toevoegen aan het bugrapport"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Even geduld…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Veeg naar links om je bugmelding te delen"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tik om je bugrapport te delen"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Tik om je bugrapport te delen zonder screenshot of wacht tot het screenshot is voltooid"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Tik om je bugrapport te delen zonder screenshot of wacht tot het screenshot is voltooid"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Foutenrapporten bevatten gegevens uit de verschillende logbestanden van het systeem, waaronder persoonlijke en privégegevens. Deel foutenrapporten alleen met apps en mensen die u vertrouwt."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Dit bericht de volgende keer weergeven"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Foutenrapporten"</string> diff --git a/packages/Shell/res/values-pa-rIN/strings.xml b/packages/Shell/res/values-pa-rIN/strings.xml index 34941999a1a5..d44daf7c5963 100644 --- a/packages/Shell/res/values-pa-rIN/strings.xml +++ b/packages/Shell/res/values-pa-rIN/strings.xml @@ -19,10 +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_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_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-pl/strings.xml b/packages/Shell/res/values-pl/strings.xml index 91934c9689fa..b4977a4a21bf 100644 --- a/packages/Shell/res/values-pl/strings.xml +++ b/packages/Shell/res/values-pl/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Powłoka"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Generuję raport o błędzie <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Raport o błędzie <xliff:g id="ID">#%d</xliff:g> został zapisany"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Raport <xliff:g id="ID">#%d</xliff:g> zapisany. Zrzut nie jest jeszcze gotowy"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Dodaję szczegóły do raportu o błędzie"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Czekaj..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Przesuń palcem w lewo, by udostępnić swoje zgłoszenie błędu"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Kliknij, by udostępnić raport o błędzie"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Kliknij, by udostępnić raport o błędzie bez zrzutu ekranu, lub poczekaj, aż zostanie on wygenerowany"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Kliknij, by udostępnić raport o błędzie bez zrzutu ekranu, lub poczekaj, aż zostanie on wygenerowany"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Raporty o błędach zawierają dane z różnych plików dzienników systemu, w tym dane osobowe i prywatne. Udostępniaj je tylko aplikacjom i osobom, którym ufasz."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Pokaż ten komunikat następnym razem"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Raporty o błędach"</string> diff --git a/packages/Shell/res/values-pt-rBR/strings.xml b/packages/Shell/res/values-pt-rBR/strings.xml index 41f4e249445b..2306c39ac414 100644 --- a/packages/Shell/res/values-pt-rBR/strings.xml +++ b/packages/Shell/res/values-pt-rBR/strings.xml @@ -19,10 +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> + <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> + <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-rPT/strings.xml b/packages/Shell/res/values-pt-rPT/strings.xml index 416db8086f09..7daed8b0ee8c 100644 --- a/packages/Shell/res/values-pt-rPT/strings.xml +++ b/packages/Shell/res/values-pt-rPT/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"O relatório de erro <xliff:g id="ID">#%d</xliff:g> está a ser criado"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Relatório de erro <xliff:g id="ID">#%d</xliff:g> criado"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Rel. de erro <xliff:g id="ID">#%d</xliff:g> capturado, captura de ecrã pendente"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"A adicionar detalhes ao relatório de erro"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Aguarde..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Deslizar rapidamente para a esquerda para partilhar o seu relatório de erros"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Toque para partilhar o relatório de erro"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Toque para partilhar o relatório de erro sem uma captura de ecrã ou aguarde a conclusão da mesma"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Toque para partilhar o relatório de erro sem uma captura de ecrã ou aguarde a conclusão da mesma"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Os relatórios de erros incluem dados de vários ficheiros de registo do sistema, nomeadamente informações pessoais e privadas. Partilhe relatórios de erros apenas com aplicações e pessoas fidedignas."</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 erros"</string> diff --git a/packages/Shell/res/values-pt/strings.xml b/packages/Shell/res/values-pt/strings.xml index 41f4e249445b..2306c39ac414 100644 --- a/packages/Shell/res/values-pt/strings.xml +++ b/packages/Shell/res/values-pt/strings.xml @@ -19,10 +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> + <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> + <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 4112e6071c79..9529ade5295a 100644 --- a/packages/Shell/res/values-ro/strings.xml +++ b/packages/Shell/res/values-ro/strings.xml @@ -19,10 +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> + <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> + <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 ffd2e66349d9..4aafbba425b9 100644 --- a/packages/Shell/res/values-ru/strings.xml +++ b/packages/Shell/res/values-ru/strings.xml @@ -19,10 +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_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_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-si-rLK/strings.xml b/packages/Shell/res/values-si-rLK/strings.xml index 807ebb14ac62..1ea758608a6d 100644 --- a/packages/Shell/res/values-si-rLK/strings.xml +++ b/packages/Shell/res/values-si-rLK/strings.xml @@ -19,10 +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_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_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-sk/strings.xml b/packages/Shell/res/values-sk/strings.xml index a62a6eb23019..fa1732628867 100644 --- a/packages/Shell/res/values-sk/strings.xml +++ b/packages/Shell/res/values-sk/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Prostredie"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Generuje sa hlásenie chyby <xliff:g id="ID">#%d</xliff:g>"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Hlásenie chyby <xliff:g id="ID">#%d</xliff:g> bolo zaznamenané"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Hlásenie chyby <xliff:g id="ID">#%d</xliff:g> bolo zaznamenané, ale čaká sa na snímku obrazovky"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Pridanie podrobností o hlásení chyby"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Čakajte prosím…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Ak chcete hlásenie o chybe zdieľať, prejdite prstom doľava."</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Hlásenie chyby môžete zdieľať klepnutím"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Klepnutím zdieľajte hlásenie chyby bez snímky obrazovky alebo počkajte na dokončenie snímky obrazovky"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Klepnutím zdieľajte hlásenie chyby bez snímky obrazovky alebo počkajte na dokončenie snímky obrazovky"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Správy o chybách obsahujú údaje z rôznych súborov denníkov systému vrátane osobných a súkromných informácií. Zdieľajte ich iba s dôveryhodnými aplikáciami a ľuďmi."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Zobraziť túto správu nabudúce"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Hlásenia chýb"</string> diff --git a/packages/Shell/res/values-sl/strings.xml b/packages/Shell/res/values-sl/strings.xml index 6d1be5ad3b88..fdf34468c060 100644 --- a/packages/Shell/res/values-sl/strings.xml +++ b/packages/Shell/res/values-sl/strings.xml @@ -19,10 +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> + <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> + <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 ce990e949b45..f43ce9fdab0f 100644 --- a/packages/Shell/res/values-sq-rAL/strings.xml +++ b/packages/Shell/res/values-sq-rAL/strings.xml @@ -19,10 +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> + <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> + <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-sr/strings.xml b/packages/Shell/res/values-sr/strings.xml index 0157a252e2c9..3bea4f35e370 100644 --- a/packages/Shell/res/values-sr/strings.xml +++ b/packages/Shell/res/values-sr/strings.xml @@ -19,10 +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> + <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_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-sv/strings.xml b/packages/Shell/res/values-sv/strings.xml index 88af0db1836c..a8cb64deba0d 100644 --- a/packages/Shell/res/values-sv/strings.xml +++ b/packages/Shell/res/values-sv/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Skal"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Felrapporten <xliff:g id="ID">#%d</xliff:g> genereras"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Felrapporten <xliff:g id="ID">#%d</xliff:g> har skapats"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Felrapporten <xliff:g id="ID">#%d</xliff:g> har skapats, väntar på skärmdumpen"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Lägger till information i felrapporten"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Vänta …"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Svep åt vänster om du vill dela felrapporten"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Tryck om du vill dela felrapporten"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Tryck om du vill dela felrapporten utan en skärmdump eller vänta tills skärmdumpen är klar"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Tryck om du vill dela felrapporten utan en skärmdump eller vänta tills skärmdumpen är klar"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Felrapporter innehåller data från systemets olika loggfiler, inklusive personliga och privata uppgifter. Dela bara felrapporter med personer du litar på."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Visa det här meddelandet nästa gång"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Felrapporter"</string> diff --git a/packages/Shell/res/values-sw/strings.xml b/packages/Shell/res/values-sw/strings.xml index 01df55ec63df..945bb600e138 100644 --- a/packages/Shell/res/values-sw/strings.xml +++ b/packages/Shell/res/values-sw/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"Ganda"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Ripoti ya hitilafu ya <xliff:g id="ID">#%d</xliff:g> inatayarishwa"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Ripoti ya hitilafu ya <xliff:g id="ID">#%d</xliff:g> imerekodiwa"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Ripoti ya hitilafu ya <xliff:g id="ID">#%d</xliff:g> imerekodiwa lakini picha ya skrini bado haijakamilishwa"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Inaongeza maelezo kwenye ripoti ya hitilafu"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Tafadhali subiri…"</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Telezesha kidole kushoto ili ushiriki ripoti yako ya hitilafu"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Gonga ili ushiriki ripoti yako ya hitilafu"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Gonga ili ushiriki ripoti yako ya hitilafu bila picha ya skrini au usubiri picha ya skrini itayarishwe"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Gonga ili ushiriki ripoti yako ya hitilafu bila picha ya skrini au usubiri picha ya skrini itayarishwe"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Ripoti ya hitilafu ina data kutoka kwenye faili za kumbukumbu mbalimbali za mfumo, pamoja na maelezo ya kibinafsi na faragha. Shiriki ripoti ya hitilafu na programu na watu unaowaamini pekee."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Onyesha ujumbe huu wakati mwingine"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Ripoti za hitilafu"</string> diff --git a/packages/Shell/res/values-ta-rIN/strings.xml b/packages/Shell/res/values-ta-rIN/strings.xml index c14da562ef35..a50176471000 100644 --- a/packages/Shell/res/values-ta-rIN/strings.xml +++ b/packages/Shell/res/values-ta-rIN/strings.xml @@ -19,10 +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_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_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-te-rIN/strings.xml b/packages/Shell/res/values-te-rIN/strings.xml index 3ed1f9595360..f4068698e2a7 100644 --- a/packages/Shell/res/values-te-rIN/strings.xml +++ b/packages/Shell/res/values-te-rIN/strings.xml @@ -19,10 +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_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_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-th/strings.xml b/packages/Shell/res/values-th/strings.xml index f28bac6287d8..db7f823230c7 100644 --- a/packages/Shell/res/values-th/strings.xml +++ b/packages/Shell/res/values-th/strings.xml @@ -19,10 +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> + <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_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 d27040154f40..f99a1b8fcb67 100644 --- a/packages/Shell/res/values-tl/strings.xml +++ b/packages/Shell/res/values-tl/strings.xml @@ -19,10 +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> + <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> + <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 6da3490e1b5f..be448afa0fc9 100644 --- a/packages/Shell/res/values-tr/strings.xml +++ b/packages/Shell/res/values-tr/strings.xml @@ -19,10 +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> + <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> + <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-uk/strings.xml b/packages/Shell/res/values-uk/strings.xml index 00a77938b840..c35c61ccc177 100644 --- a/packages/Shell/res/values-uk/strings.xml +++ b/packages/Shell/res/values-uk/strings.xml @@ -19,10 +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_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_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-ur-rPK/strings.xml b/packages/Shell/res/values-ur-rPK/strings.xml index abf6940934a4..ef6801fefcb1 100644 --- a/packages/Shell/res/values-ur-rPK/strings.xml +++ b/packages/Shell/res/values-ur-rPK/strings.xml @@ -19,10 +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_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_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 7782b420e7cc..c1a19480c0df 100644 --- a/packages/Shell/res/values-uz-rUZ/strings.xml +++ b/packages/Shell/res/values-uz-rUZ/strings.xml @@ -19,10 +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> + <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> + <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 27a9c7f6da3b..22299916c149 100644 --- a/packages/Shell/res/values-vi/strings.xml +++ b/packages/Shell/res/values-vi/strings.xml @@ -19,10 +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> + <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> + <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 65cfbbcc51de..b09a7d0b783b 100644 --- a/packages/Shell/res/values-zh-rCN/strings.xml +++ b/packages/Shell/res/values-zh-rCN/strings.xml @@ -19,10 +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> + <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_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 34a849e7610d..384eee70caea 100644 --- a/packages/Shell/res/values-zh-rHK/strings.xml +++ b/packages/Shell/res/values-zh-rHK/strings.xml @@ -19,10 +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_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_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 fff73bbc1471..2702bad05e87 100644 --- a/packages/Shell/res/values-zh-rTW/strings.xml +++ b/packages/Shell/res/values-zh-rTW/strings.xml @@ -19,10 +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_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_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-zu/strings.xml b/packages/Shell/res/values-zu/strings.xml index 868de3eefe8f..561ac0afb314 100644 --- a/packages/Shell/res/values-zu/strings.xml +++ b/packages/Shell/res/values-zu/strings.xml @@ -19,10 +19,13 @@ <string name="app_label" msgid="3701846017049540910">"I-Shell"</string> <string name="bugreport_in_progress_title" msgid="4311705936714972757">"Umbiko wesiphazamisi ongu-<xliff:g id="ID">#%d</xliff:g> uyacutshungulwa"</string> <string name="bugreport_finished_title" msgid="4429132808670114081">"Umbiko wesiphazamisi ongu-<xliff:g id="ID">#%d</xliff:g> uthwetshuliwe"</string> + <string name="bugreport_finished_pending_screenshot_title" msgid="5460883450679439591">"Umbiko wesiphazamisi esingu-<xliff:g id="ID">#%d</xliff:g> uthwetshuliwe kodwa isithombe-skrini silindile"</string> <string name="bugreport_updating_title" msgid="4423539949559634214">"Ingeza imininingwane kumbiko wesiphazamisi"</string> <string name="bugreport_updating_wait" msgid="3322151947853929470">"Sicela ulinde..."</string> <string name="bugreport_finished_text" product="watch" msgid="8389172248433597683">"Swayiphela kwesokunxele ukuze wabelane umbiko wesiphazamiso sakho"</string> <string name="bugreport_finished_text" product="default" msgid="8353769438382138847">"Thepha ukuze wabelane ngombiko wakho wesiphazamisi"</string> + <string name="bugreport_finished_pending_screenshot_text" product="watch" msgid="1474435374470177193">"Thepha ukuze wabelane ngombiko wesiphazamisi ngaphandle kwesithombe-skrini noma ulinde isithombe-skrini ukuthi siqede"</string> + <string name="bugreport_finished_pending_screenshot_text" product="default" msgid="1474435374470177193">"Thepha ukuze wabelane ngombiko wesiphazamisi ngaphandle kwesithombe-skrini noma ulinde isithombe-skrini ukuthi siqede"</string> <string name="bugreport_confirm" msgid="5130698467795669780">"Imibiko yeziphazamisi iqukethe idatha yamafayela wokungena ahlukile wesistimu, afaka ulwazi lomuntu siqu noma lobumfihlo. Yabelana kuphela ngemibiko yeziphazamisi nezinhlelo zokusebenza nabantu obathembayo."</string> <string name="bugreport_confirm_repeat" msgid="4926842460688645058">"Bonisa lo mlayezo ngesikhathi esilandelayo"</string> <string name="bugreport_storage_title" msgid="5332488144740527109">"Imibiko yeziphazamiso"</string> diff --git a/packages/Shell/res/values/strings.xml b/packages/Shell/res/values/strings.xml index 38ea8804a2d8..5d901896cc4a 100644 --- a/packages/Shell/res/values/strings.xml +++ b/packages/Shell/res/values/strings.xml @@ -20,6 +20,8 @@ <string name="bugreport_in_progress_title">Bug report <xliff:g id="id">#%d</xliff:g> is being generated</string> <!-- Title of notification indicating a bugreport has been successfully captured. [CHAR LIMIT=50] --> <string name="bugreport_finished_title">Bug report <xliff:g id="id">#%d</xliff:g> captured</string> + <!-- Title of notification indicating a bugreport has been successfully captured, but screenshot is not finished yet. [CHAR LIMIT=50] --> + <string name="bugreport_finished_pending_screenshot_title">Bug report <xliff:g id="id">#%d</xliff:g> captured but screenshot pending</string> <!-- Title of notification indicating a bugreport is being updated before it can be shared. [CHAR LIMIT=50] --> <string name="bugreport_updating_title">Adding details to the bug report</string> <!-- Content notification indicating a bugreport is being updated before it can be shared, asking the user to wait [CHAR LIMIT=50] --> @@ -29,7 +31,10 @@ <string name="bugreport_finished_text" product="watch">Swipe left to share your bug report</string> <!-- Text of notification indicating that tapping will share the captured bugreport. [CHAR LIMIT=100] --> <string name="bugreport_finished_text" product="default">Tap to share your bug report</string> - + <!-- Text of notification indicating that swipe left will share the captured bugreport, but giving user the option to wait for the screenshot. [CHAR LIMIT=100] --> + <string name="bugreport_finished_pending_screenshot_text" product="watch">Tap to share your bug report without a screenshot or wait for the screenshot to finish</string> + <!-- Text of notification indicating that tapping will share the captured bugreport, but giving user the option to wait for the screenshot. [CHAR LIMIT=100] --> + <string name="bugreport_finished_pending_screenshot_text" product="default">Tap to share your bug report without a screenshot or wait for the screenshot to finish</string> <!-- Body of dialog informing user about contents of a bugreport. [CHAR LIMIT=NONE] --> <string name="bugreport_confirm">Bug reports contain data from the system\'s various log files, including personal and private information. Only share bug reports with apps and people you trust.</string> diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java index 1c6a0710d18f..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 @@ -714,7 +718,7 @@ public class BugreportProgressService extends Service { if (info.finished) { Log.d(TAG, "Screenshot finished after bugreport; updating share notification"); info.renameScreenshots(mScreenshotsDir); - sendBugreportNotification(mContext, info); + sendBugreportNotification(mContext, info, mTakingScreenshot); } msg = mContext.getString(R.string.bugreport_screenshot_taken); } else { @@ -803,10 +807,10 @@ public class BugreportProgressService extends Service { boolean isPlainText = info.bugreportFile.getName().toLowerCase().endsWith(".txt"); if (!isPlainText) { // Already zipped, send it right away. - sendBugreportNotification(context, info); + sendBugreportNotification(context, info, mTakingScreenshot); } else { // Asynchronously zip the file first, then send it. - sendZippedBugreportNotification(context, info); + sendZippedBugreportNotification(context, info, mTakingScreenshot); } } @@ -903,7 +907,8 @@ public class BugreportProgressService extends Service { /** * Sends a notification indicating the bugreport has finished so use can share it. */ - private static void sendBugreportNotification(Context context, BugreportInfo info) { + private static void sendBugreportNotification(Context context, BugreportInfo info, + boolean takingScreenshot) { // Since adding the details can take a while, do it before notifying user. addDetailsToZipFile(context, info); @@ -914,12 +919,20 @@ public class BugreportProgressService extends Service { shareIntent.putExtra(EXTRA_ID, info.id); shareIntent.putExtra(EXTRA_INFO, info); - final String title = context.getString(R.string.bugreport_finished_title, info.id); + final String title, content; + if (takingScreenshot) { + title = context.getString(R.string.bugreport_finished_pending_screenshot_title, + info.id); + content = context.getString(R.string.bugreport_finished_pending_screenshot_text); + } else { + title = context.getString(R.string.bugreport_finished_title, info.id); + content = context.getString(R.string.bugreport_finished_text); + } final Notification.Builder builder = new Notification.Builder(context) .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb) .setContentTitle(title) .setTicker(title) - .setContentText(context.getString(R.string.bugreport_finished_text)) + .setContentText(content) .setContentIntent(PendingIntent.getService(context, info.id, shareIntent, PendingIntent.FLAG_UPDATE_CURRENT)) .setDeleteIntent(newCancelIntent(context, info)) @@ -958,12 +971,12 @@ public class BugreportProgressService extends Service { * Sends a zipped bugreport notification. */ private static void sendZippedBugreportNotification(final Context context, - final BugreportInfo info) { + final BugreportInfo info, final boolean takingScreenshot) { new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { zipBugreport(info); - sendBugreportNotification(context, info); + sendBugreportNotification(context, info, takingScreenshot); return null; } }.execute(); @@ -1181,14 +1194,13 @@ public class BugreportProgressService extends Service { * Takes a screenshot and save it to the given location. */ private static boolean takeScreenshot(Context context, String screenshotFile) { - ((Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE)) - .vibrate(150); final ProcessBuilder screencap = new ProcessBuilder() .command("/system/bin/screencap", "-p", screenshotFile); Log.d(TAG, "Taking screenshot using " + screencap.command()); try { final int exitValue = screencap.start().waitFor(); if (exitValue == 0) { + ((Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE)).vibrate(150); return true; } Log.e(TAG, "screencap (" + screencap.command() + ") failed: " + exitValue); diff --git a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java index a629aac33d25..47e3b3b8f8f3 100644 --- a/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java +++ b/packages/Shell/tests/src/com/android/shell/BugreportReceiverTest.java @@ -130,6 +130,9 @@ public class BugreportReceiverTest extends InstrumentationTestCase { private static final boolean RENAMED_SCREENSHOTS = true; private static final boolean DIDNT_RENAME_SCREENSHOTS = false; + private static final boolean PENDING_SCREENSHOT = true; + private static final boolean NOT_PENDING_SCREENSHOT = false; + private String mDescription; private String mPlainTextPath; @@ -409,9 +412,8 @@ public class BugreportReceiverTest extends InstrumentationTestCase { sendBugreportStarted(ID2, PID2, NAME2, 1000); - Bundle extras = sendBugreportFinishedAndGetSharedIntent(ID, mZipPath, mScreenshotPath); - assertActionSendMultiple(extras, BUGREPORT_CONTENT, SCREENSHOT_CONTENT, ID, PID, TITLE, - NEW_NAME, TITLE, DESCRIPTION, 1, RENAMED_SCREENSHOTS); + sendBugreportFinished(ID, mZipPath, mScreenshotPath); + Bundle extras = acceptBugreportAndGetSharedIntent(ID, PENDING_SCREENSHOT); detailsUi = new DetailsUi(mUiBot, ID2); detailsUi.assertName(NAME2); @@ -602,7 +604,7 @@ public class BugreportReceiverTest extends InstrumentationTestCase { private Bundle sendBugreportFinishedAndGetSharedIntent(int id, String bugreportPath, String screenshotPath) { sendBugreportFinished(id, bugreportPath, screenshotPath); - return acceptBugreportAndGetSharedIntent(id); + return acceptBugreportAndGetSharedIntent(id, NOT_PENDING_SCREENSHOT); } /** @@ -611,7 +613,11 @@ public class BugreportReceiverTest extends InstrumentationTestCase { * @return extras sent in the shared intent. */ private Bundle acceptBugreportAndGetSharedIntent(int id) { - acceptBugreport(id); + return acceptBugreportAndGetSharedIntent(id, NOT_PENDING_SCREENSHOT); + } + + private Bundle acceptBugreportAndGetSharedIntent(int id, boolean pendingScreenshot) { + acceptBugreport(id, pendingScreenshot); mUiBot.chooseActivity(UI_NAME); return mListener.getExtras(); } @@ -627,7 +633,13 @@ public class BugreportReceiverTest extends InstrumentationTestCase { * Accepts the notification to share the finished bugreport. */ private void acceptBugreport(int id) { - mUiBot.clickOnNotification(mContext.getString(R.string.bugreport_finished_title, id)); + acceptBugreport(id, NOT_PENDING_SCREENSHOT); + } + + private void acceptBugreport(int id, boolean pendingScreenshot) { + final int res = pendingScreenshot ? R.string.bugreport_finished_pending_screenshot_title + : R.string.bugreport_finished_title; + mUiBot.clickOnNotification(mContext.getString(res, id)); } /** 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/battery_detail.xml b/packages/SystemUI/res/layout/battery_detail.xml index 99121a9966d6..af3e3796d157 100644 --- a/packages/SystemUI/res/layout/battery_detail.xml +++ b/packages/SystemUI/res/layout/battery_detail.xml @@ -33,7 +33,7 @@ <com.android.settingslib.graph.UsageView android:id="@+id/battery_usage" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="141dp" android:layout_marginStart="16dp" android:layout_marginEnd="24dp" systemui:sideLabels="@array/battery_labels" 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 30d9ed7ff201..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> @@ -220,6 +221,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Werkmodus is aan."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Werkmodus is afgeskakel."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Werkmodus is aangeskakel."</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_brightness" msgid="8003681285547803095">"Skermhelderheid"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G-data is laat wag"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data is laat wag"</string> diff --git a/packages/SystemUI/res/values-af/strings_tv.xml b/packages/SystemUI/res/values-af/strings_tv.xml new file mode 100644 index 000000000000..adc1306b0af6 --- /dev/null +++ b/packages/SystemUI/res/values-af/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Maak PIP toe"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Volskerm"</string> + <string name="pip_play" msgid="674145557658227044">"Speel"</string> + <string name="pip_pause" msgid="8412075640017218862">"Laat wag"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Hou "<b>"TUIS"</b>" om PIP te beheer"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Druk en hou die TUIS-\nknoppie om PIP te beheer"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Het dit"</string> +</resources> diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml index 9692ae8a73db..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> @@ -220,6 +221,10 @@ <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_brightness" msgid="8003681285547803095">"ብሩህነት ያሳዩ"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2ጂ-3ጂ ውሂብ ላፍታ ቆሟል"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4ጂ ውሂብ ላፍታ ቆሟል"</string> diff --git a/packages/SystemUI/res/values-am/strings_tv.xml b/packages/SystemUI/res/values-am/strings_tv.xml new file mode 100644 index 000000000000..544ae0739a1e --- /dev/null +++ b/packages/SystemUI/res/values-am/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIPን ዝጋ"</string> + <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_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 181f68be1384..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> @@ -224,6 +225,10 @@ <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_brightness" msgid="8003681285547803095">"سطوع الشاشة"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"بيانات شبكات الجيل الثاني والثالث متوقفة مؤقتًا"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"تم إيقاف بيانات شبكة الجيل الرابع مؤقتًا"</string> diff --git a/packages/SystemUI/res/values-ar/strings_tv.xml b/packages/SystemUI/res/values-ar/strings_tv.xml new file mode 100644 index 000000000000..99c413cf6bf8 --- /dev/null +++ b/packages/SystemUI/res/values-ar/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"إغلاق PIP"</string> + <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">"اضغط "<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-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml index 9e88f35e63f1..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> @@ -220,6 +221,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"İş rejimi aktivdir."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"İş rejimi sönülüdür."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"İş rejimi yanılıdır."</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_brightness" msgid="8003681285547803095">"Display brightness"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G məlumatlarına fasilə verildi"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G məlumatlarına fasilə verildi"</string> diff --git a/packages/SystemUI/res/values-az-rAZ/strings_tv.xml b/packages/SystemUI/res/values-az-rAZ/strings_tv.xml new file mode 100644 index 000000000000..6751bc9c16a6 --- /dev/null +++ b/packages/SystemUI/res/values-az-rAZ/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 3edc8057a9f4..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> @@ -221,6 +223,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Režim rada je uključen."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Režim rada je isključen."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Režim rada je uključen."</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_brightness" msgid="8003681285547803095">"Osvetljenost ekrana"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G podaci su pauzirani"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G podaci su pauzirani"</string> diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml new file mode 100644 index 000000000000..39a858cfc50a --- /dev/null +++ b/packages/SystemUI/res/values-b+sr+Latn/strings_tv.xml @@ -0,0 +1,29 @@ +<?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> + <string name="pip_fullscreen" msgid="8604643018538487816">"Ceo ekran"</string> + <string name="pip_play" msgid="674145557658227044">"Pusti"</string> + <string name="pip_pause" msgid="8412075640017218862">"Pauziraj"</string> + <string name="pip_hold_home" msgid="340086535668778109"><b>"POČETNI EKRAN"</b>" kont. PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Pritisnite i zadržite dugme POČETNI EKRAN\n da biste kontrolisali PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Važi"</string> +</resources> diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml index 84757b7f36cf..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> @@ -220,6 +221,10 @@ <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_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-bg/strings_tv.xml b/packages/SystemUI/res/values-bg/strings_tv.xml new file mode 100644 index 000000000000..38c10ab6b828 --- /dev/null +++ b/packages/SystemUI/res/values-bg/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Затваряне на PIP"</string> + <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>"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 18f37e6321de..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> @@ -220,6 +221,10 @@ <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_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-bn-rBD/strings_tv.xml b/packages/SystemUI/res/values-bn-rBD/strings_tv.xml new file mode 100644 index 000000000000..7a958155d505 --- /dev/null +++ b/packages/SystemUI/res/values-bn-rBD/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP বন্ধ করুন"</string> + <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_onboarding_button" msgid="3957426748484904611">"বুঝেছি"</string> +</resources> diff --git a/packages/SystemUI/res/values-bs-rBA/strings.xml b/packages/SystemUI/res/values-bs-rBA/strings.xml index 3a7c6cda120f..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> @@ -221,6 +223,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Poslovni režim uključen."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Poslovni režim je isključen."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Poslovni režim je uključen."</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_brightness" msgid="8003681285547803095">"Osvjetljenje ekrana"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G prijenos podataka je pauzirano"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G prijenos podataka je pauzirano"</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 f8224ac264d5..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"El mode de feina està activat."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"S\'ha desactivat el mode de feina."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"S\'ha activat el mode de feina."</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_brightness" msgid="8003681285547803095">"Brillantor de la pantalla"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Les dades 2G-3G estan aturades"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Les dades 4G estan aturades"</string> diff --git a/packages/SystemUI/res/values-ca/strings_tv.xml b/packages/SystemUI/res/values-ca/strings_tv.xml new file mode 100644 index 000000000000..1aed2b4af948 --- /dev/null +++ b/packages/SystemUI/res/values-ca/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 48c9c550c307..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> @@ -222,6 +224,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Pracovní režim zapnutý"</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_brightness" msgid="8003681285547803095">"Jas displeje"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data 2G a 3G jsou pozastavena"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Data 4G jsou pozastavena"</string> diff --git a/packages/SystemUI/res/values-cs/strings_tv.xml b/packages/SystemUI/res/values-cs/strings_tv.xml new file mode 100644 index 000000000000..2480c3736443 --- /dev/null +++ b/packages/SystemUI/res/values-cs/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 50d01ea58938..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Arbejdstilstand er slået til."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Arbejdstilstand er slået fra."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Arbejdstilstand er slået til."</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_brightness" msgid="8003681285547803095">"Skærmens lysstyrke"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G-data er sat på pause"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data er sat på pause"</string> diff --git a/packages/SystemUI/res/values-da/strings_tv.xml b/packages/SystemUI/res/values-da/strings_tv.xml new file mode 100644 index 000000000000..10a1ecd8a4b3 --- /dev/null +++ b/packages/SystemUI/res/values-da/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Luk PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Fuld skærm"</string> + <string name="pip_play" msgid="674145557658227044">"Afspil"</string> + <string name="pip_pause" msgid="8412075640017218862">"Pause"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Hold "<b>"HOME"</b>" nede for at styre PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Tryk på knappen HOME,\nog hold den nede for at styre PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string> +</resources> diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml index fd8cf89e1132..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Arbeitsmodus an."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Arbeitsmodus deaktiviert."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Arbeitsmodus aktiviert."</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_brightness" msgid="8003681285547803095">"Helligkeit des Displays"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-/3G-Daten pausiert"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-Daten pausiert"</string> diff --git a/packages/SystemUI/res/values-de/strings_tv.xml b/packages/SystemUI/res/values-de/strings_tv.xml new file mode 100644 index 000000000000..aa1a9b20de42 --- /dev/null +++ b/packages/SystemUI/res/values-de/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP schließen"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Vollbild"</string> + <string name="pip_play" msgid="674145557658227044">"Wiedergeben"</string> + <string name="pip_pause" msgid="8412075640017218862">"Pausieren"</string> + <string name="pip_hold_home" msgid="340086535668778109"><b>"STARTBILDSCHIRMTASTE"</b>" drücken, um PIP zu steuern"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"STARTBILDSCHIRMTASTE\n gedrückt halten, um PIP zu steuern"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string> +</resources> diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml index b5f55d9a0912..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> @@ -220,6 +221,10 @@ <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_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-el/strings_tv.xml b/packages/SystemUI/res/values-el/strings_tv.xml new file mode 100644 index 000000000000..c96f852d1ab7 --- /dev/null +++ b/packages/SystemUI/res/values-el/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Κλείσιμο PIP"</string> + <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">"Κρατήστε το πλήκτρο "<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-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml index cbb1ecf577a1..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,6 +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> + <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-rAU/strings_tv.xml b/packages/SystemUI/res/values-en-rAU/strings_tv.xml new file mode 100644 index 000000000000..6f3365569ab3 --- /dev/null +++ b/packages/SystemUI/res/values-en-rAU/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Close PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string> + <string name="pip_play" msgid="674145557658227044">"Play"</string> + <string name="pip_pause" msgid="8412075640017218862">"Pause"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Hold "<b>"HOME"</b>" to control PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Press and hold the HOME\nbutton to control PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Understood"</string> +</resources> diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml index cbb1ecf577a1..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,6 +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> + <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_tv.xml b/packages/SystemUI/res/values-en-rGB/strings_tv.xml new file mode 100644 index 000000000000..6f3365569ab3 --- /dev/null +++ b/packages/SystemUI/res/values-en-rGB/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Close PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string> + <string name="pip_play" msgid="674145557658227044">"Play"</string> + <string name="pip_pause" msgid="8412075640017218862">"Pause"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Hold "<b>"HOME"</b>" to control PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Press and hold the HOME\nbutton to control PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Understood"</string> +</resources> diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml index cbb1ecf577a1..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,6 +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> + <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_tv.xml b/packages/SystemUI/res/values-en-rIN/strings_tv.xml new file mode 100644 index 000000000000..6f3365569ab3 --- /dev/null +++ b/packages/SystemUI/res/values-en-rIN/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Close PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Full screen"</string> + <string name="pip_play" msgid="674145557658227044">"Play"</string> + <string name="pip_pause" msgid="8412075640017218862">"Pause"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Hold "<b>"HOME"</b>" to control PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Press and hold the HOME\nbutton to control PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Understood"</string> +</resources> diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml index 856c1c15f965..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Modo de trabajo activado"</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Se desactivó el modo de trabajo."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Se activó el modo de trabajo."</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_brightness" msgid="8003681285547803095">"Brillo de pantalla"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Datos 2G-3G pausados"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Datos 4G pausados"</string> diff --git a/packages/SystemUI/res/values-es-rUS/strings_tv.xml b/packages/SystemUI/res/values-es-rUS/strings_tv.xml new file mode 100644 index 000000000000..1df219d68aa0 --- /dev/null +++ b/packages/SystemUI/res/values-es-rUS/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 409299465f25..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Modo de trabajo activado."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Modo de trabajo desactivado."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Modo de trabajo activado."</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_brightness" msgid="8003681285547803095">"Brillo de la pantalla"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Datos 2G-3G pausados"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Datos 4G pausados"</string> diff --git a/packages/SystemUI/res/values-es/strings_tv.xml b/packages/SystemUI/res/values-es/strings_tv.xml new file mode 100644 index 000000000000..fcc839e7421b --- /dev/null +++ b/packages/SystemUI/res/values-es/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <string name="pip_hold_home" msgid="340086535668778109"><b>"INICIO"</b>" pulsado: control PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"INICIO pulsado:\ncontrol PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Entendido"</string> +</resources> diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml index 1279a2c083d3..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Töörežiim on sees."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Töörežiim on välja lülitatud."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Töörežiim on sisse lülitatud."</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_brightness" msgid="8003681285547803095">"Ekraani heledus"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G andmekasutus on peatatud"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G andmekasutus on peatatud"</string> diff --git a/packages/SystemUI/res/values-et-rEE/strings_tv.xml b/packages/SystemUI/res/values-et-rEE/strings_tv.xml new file mode 100644 index 000000000000..ae6cb30bf8b3 --- /dev/null +++ b/packages/SystemUI/res/values-et-rEE/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Sule PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Täisekraan"</string> + <string name="pip_play" msgid="674145557658227044">"Esita"</string> + <string name="pip_pause" msgid="8412075640017218862">"Peata"</string> + <string name="pip_hold_home" msgid="340086535668778109">"PIP juht. hoidke all nuppu "<b>"AVAEKRAAN"</b></string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"PIP juhtim. vajutage\npikalt nuppu AVAEKRAAN"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Selge"</string> +</resources> diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml index 29e3da8661dd..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Aktibatuta dago lan modua."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Desaktibatuta dago lan modua."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Aktibatuta dago lan modua."</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_brightness" msgid="8003681285547803095">"Bistaratu distira"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G datuen erabilera eten da"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G datuen erabilera eten da"</string> diff --git a/packages/SystemUI/res/values-eu-rES/strings_tv.xml b/packages/SystemUI/res/values-eu-rES/strings_tv.xml new file mode 100644 index 000000000000..80feff6b5f01 --- /dev/null +++ b/packages/SystemUI/res/values-eu-rES/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 cc3251858151..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> @@ -220,6 +222,10 @@ <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_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> @@ -506,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 new file mode 100644 index 000000000000..5130b5085825 --- /dev/null +++ b/packages/SystemUI/res/values-fa/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"بستن PIP"</string> + <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>"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 8b3fb5ea7675..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Työtila on käytössä."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Työtila poistettiin käytöstä."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Työtila otettiin käyttöön."</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_brightness" msgid="8003681285547803095">"Näytön kirkkaus"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G-tiedonsiirto keskeytettiin"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-tiedonsiirto keskeytettiin"</string> diff --git a/packages/SystemUI/res/values-fi/strings_tv.xml b/packages/SystemUI/res/values-fi/strings_tv.xml new file mode 100644 index 000000000000..a42c23139ae1 --- /dev/null +++ b/packages/SystemUI/res/values-fi/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 e0beecaa60d3..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Mode Travail activé."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Le mode Travail est désactivé."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Le mode Travail est activé."</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_brightness" msgid="8003681285547803095">"Luminosité de l\'écran"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Données 2G/3G désactivées"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Données 4G désactivées"</string> diff --git a/packages/SystemUI/res/values-fr-rCA/strings_tv.xml b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml new file mode 100644 index 000000000000..29e94c6d2b0d --- /dev/null +++ b/packages/SystemUI/res/values-fr-rCA/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 9ef639239b23..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Mode Travail activé"</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Le mode Travail est désactivé."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Le mode Travail est activé."</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_brightness" msgid="8003681285547803095">"Luminosité de l\'affichage"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Données 2G-3G désactivées"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Données 4G désactivées"</string> diff --git a/packages/SystemUI/res/values-fr/strings_tv.xml b/packages/SystemUI/res/values-fr/strings_tv.xml new file mode 100644 index 000000000000..8504a8ea3bab --- /dev/null +++ b/packages/SystemUI/res/values-fr/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 bb85708d554c..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Modo de traballo activado."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Desactivouse o modo de traballo."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Activouse o modo de traballo."</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_brightness" msgid="8003681285547803095">"Brillo de pantalla"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Os datos 2G-3G están en pausa"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Os datos 4G están en pausa"</string> diff --git a/packages/SystemUI/res/values-gl-rES/strings_tv.xml b/packages/SystemUI/res/values-gl-rES/strings_tv.xml new file mode 100644 index 000000000000..6aab613923a5 --- /dev/null +++ b/packages/SystemUI/res/values-gl-rES/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Pechar 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> + <string name="pip_hold_home" msgid="340086535668778109">"Premido "<b>"INICIO"</b>" para PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Premido INICIO\npara PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"De acordo"</string> +</resources> diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml index 075f02399eec..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> @@ -220,6 +221,10 @@ <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_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-gu-rIN/strings_tv.xml b/packages/SystemUI/res/values-gu-rIN/strings_tv.xml new file mode 100644 index 000000000000..56f0298d4ee3 --- /dev/null +++ b/packages/SystemUI/res/values-gu-rIN/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP બંધ કરો"</string> + <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_onboarding_button" msgid="3957426748484904611">"સમજાઈ ગયું"</string> +</resources> diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml index 91a5d69931d7..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> @@ -220,6 +222,10 @@ <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_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-hi/strings_tv.xml b/packages/SystemUI/res/values-hi/strings_tv.xml new file mode 100644 index 000000000000..c4bb26baa418 --- /dev/null +++ b/packages/SystemUI/res/values-hi/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP बंद करें"</string> + <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>"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-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml index eaa777ba5894..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> @@ -221,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Način rada uključen."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Način rada isključen."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Način rada uključen."</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_brightness" msgid="8003681285547803095">"Svjetlina zaslona"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G – 3G podaci pauzirani"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G podaci pauzirani"</string> @@ -304,8 +309,7 @@ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"prikvačivanje zaslona"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"pretraži"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Aplikacija <xliff:g id="APP">%s</xliff:g> nije pokrenuta."</string> - <!-- no translation found for recents_launch_disabled_message (1624523193008871793) --> - <skip /> + <string name="recents_launch_disabled_message" msgid="1624523193008871793">"Aplikacija <xliff:g id="APP">%s</xliff:g> onemogućena je u sigurnom načinu."</string> <string name="recents_history_button_label" msgid="5153358867807604821">"Povijest"</string> <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Izbriši"</string> <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Ta aplikacija ne podržava više prozora"</string> diff --git a/packages/SystemUI/res/values-hr/strings_tv.xml b/packages/SystemUI/res/values-hr/strings_tv.xml new file mode 100644 index 000000000000..2a72055867b3 --- /dev/null +++ b/packages/SystemUI/res/values-hr/strings_tv.xml @@ -0,0 +1,29 @@ +<?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> + <string name="pip_fullscreen" msgid="8604643018538487816">"Cijeli zaslon"</string> + <string name="pip_play" msgid="674145557658227044">"Reproduciraj"</string> + <string name="pip_pause" msgid="8412075640017218862">"Pauziraj"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Držite "<b>"POČETNI"</b>" za PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Pritisnite i držite POČETNI\nza upravljanje PIP-om"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Shvaćam"</string> +</resources> diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml index 8e55c78fcb6b..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> @@ -220,6 +221,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Munka mód be."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Munka mód kikapcsolva."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Munka mód bekapcsolva."</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_brightness" msgid="8003681285547803095">"A kijelző fényereje"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"A 2G és 3G adatforgalom szünetel."</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"A 4G adatforgalom szünetel"</string> diff --git a/packages/SystemUI/res/values-hu/strings_tv.xml b/packages/SystemUI/res/values-hu/strings_tv.xml new file mode 100644 index 000000000000..ff4d37cea08a --- /dev/null +++ b/packages/SystemUI/res/values-hu/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP bezárása"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Teljes képernyő"</string> + <string name="pip_play" msgid="674145557658227044">"Lejátszás"</string> + <string name="pip_pause" msgid="8412075640017218862">"Szüneteltetés"</string> + <string name="pip_hold_home" msgid="340086535668778109">"PIP vezérlése a "<b>"HOME"</b>"-mal"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"A PIP vezérléséhez\ntartsa nyomva a HOME-ot"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Rendben"</string> +</resources> diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml index 09e7f70be10e..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> @@ -220,6 +222,10 @@ <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_brightness" msgid="8003681285547803095">"Ցուցադրել պայծառությունը"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2Գ-3Գ տվյալների օգտագործումը դադարեցված է"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4Գ տվյալների օգտագործումը դադարեցված է"</string> diff --git a/packages/SystemUI/res/values-hy-rAM/strings_tv.xml b/packages/SystemUI/res/values-hy-rAM/strings_tv.xml new file mode 100644 index 000000000000..0ddb715f7a0b --- /dev/null +++ b/packages/SystemUI/res/values-hy-rAM/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Փակել PIP-ն"</string> + <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>"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 46340a773006..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,6 +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> + <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-in/strings_tv.xml b/packages/SystemUI/res/values-in/strings_tv.xml new file mode 100644 index 000000000000..f6315139626c --- /dev/null +++ b/packages/SystemUI/res/values-in/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Tutup PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Layar penuh"</string> + <string name="pip_play" msgid="674145557658227044">"Putar"</string> + <string name="pip_pause" msgid="8412075640017218862">"Jeda"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Tahan "<b>"LAYAR UTAMA"</b>" untuk mengontrol PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Tekan dan tahan tombol LAYAR UTAMA\nuntuk mengontrol PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Mengerti"</string> +</resources> diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml index 89708de2d20c..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Kveikt á vinnustillingu."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Slökkt á vinnustillingu."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Kveikt á vinnustillingu."</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_brightness" msgid="8003681285547803095">"Birtustig skjás"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Slökkt er á 2G- og 3G-gögnum"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Slökkt er á 4G-gögnum"</string> diff --git a/packages/SystemUI/res/values-is-rIS/strings_tv.xml b/packages/SystemUI/res/values-is-rIS/strings_tv.xml new file mode 100644 index 000000000000..b44aaf0ca1df --- /dev/null +++ b/packages/SystemUI/res/values-is-rIS/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Loka mynd í mynd"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Allur skjárinn"</string> + <string name="pip_play" msgid="674145557658227044">"Spila"</string> + <string name="pip_pause" msgid="8412075640017218862">"Hlé"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Haltu "<b>"HOME"</b>"-hnappinum inni til að stjórna innfelldri mynd"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Haltu HOME\n-hnappinum inni til að stjórna innfelldri mynd"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Ég skil"</string> +</resources> diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml index aa6dd2812477..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Modalità Lavoro attiva."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Modalità Lavoro disattivata."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Modalità Lavoro attivata."</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_brightness" msgid="8003681285547803095">"Luminosità dello schermo"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Dati 2G-3G sospesi"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Dati 4G sospesi"</string> diff --git a/packages/SystemUI/res/values-it/strings_tv.xml b/packages/SystemUI/res/values-it/strings_tv.xml new file mode 100644 index 000000000000..08f2b67a5f17 --- /dev/null +++ b/packages/SystemUI/res/values-it/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Chiudi visualizzazione PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Schermo intero"</string> + <string name="pip_play" msgid="674145557658227044">"Riproduci"</string> + <string name="pip_pause" msgid="8412075640017218862">"Pausa"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Tieni premuto "<b>"HOME"</b>" per controllare la visualizzazione PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Premi e tieni premuto HOME\nper controllare la visualizzazione PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string> +</resources> diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml index ed446245b934..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> @@ -222,6 +224,10 @@ <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_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-iw/strings_tv.xml b/packages/SystemUI/res/values-iw/strings_tv.xml new file mode 100644 index 000000000000..74297e42d695 --- /dev/null +++ b/packages/SystemUI/res/values-iw/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"סגור PIP"</string> + <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">"לחץ לחיצה ארוכה על "<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-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml index f104703d61cc..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> @@ -220,6 +221,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Work モードがオンです。"</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Work モードをオフにしました。"</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Work モードをオンにしました。"</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_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> @@ -506,12 +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> - <!-- no translation found for data_saver (5037565123367048522) --> - <skip /> - <!-- no translation found for accessibility_data_saver_on (8454111686783887148) --> - <skip /> - <!-- no translation found for accessibility_data_saver_off (8841582529453005337) --> - <skip /> + <string name="data_saver" msgid="5037565123367048522">"データセーバー"</string> + <string name="accessibility_data_saver_on" msgid="8454111686783887148">"データセーバー ON"</string> + <string name="accessibility_data_saver_off" msgid="8841582529453005337">"データセーバー OFF"</string> <string name="switch_bar_on" msgid="1142437840752794229">"ON"</string> <string name="switch_bar_off" msgid="8803270596930432874">"OFF"</string> <string name="nav_bar" msgid="1993221402773877607">"ナビゲーション バー"</string> diff --git a/packages/SystemUI/res/values-ja/strings_tv.xml b/packages/SystemUI/res/values-ja/strings_tv.xml new file mode 100644 index 000000000000..be6693bc2329 --- /dev/null +++ b/packages/SystemUI/res/values-ja/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP を閉じる"</string> + <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_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 b365eb32daca..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> @@ -220,6 +222,10 @@ <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_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-ka-rGE/strings_tv.xml b/packages/SystemUI/res/values-ka-rGE/strings_tv.xml new file mode 100644 index 000000000000..97944c3c0112 --- /dev/null +++ b/packages/SystemUI/res/values-ka-rGE/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP-ის დახურვა"</string> + <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_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 720caecfb046..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> @@ -220,6 +221,10 @@ <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_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-kk-rKZ/strings_tv.xml b/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml new file mode 100644 index 000000000000..f67157c669b6 --- /dev/null +++ b/packages/SystemUI/res/values-kk-rKZ/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP жабу"</string> + <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>"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 97772ad9ece8..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> @@ -220,6 +221,10 @@ <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_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-km-rKH/strings_tv.xml b/packages/SystemUI/res/values-km-rKH/strings_tv.xml new file mode 100644 index 000000000000..cc0a8b0e32a3 --- /dev/null +++ b/packages/SystemUI/res/values-km-rKH/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"បិទ PIP"</string> + <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">"សង្កត់ប៊ូតុង "<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 481b918c3f14..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> @@ -220,6 +222,10 @@ <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_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-kn-rIN/strings_tv.xml b/packages/SystemUI/res/values-kn-rIN/strings_tv.xml new file mode 100644 index 000000000000..09d7b07e3b05 --- /dev/null +++ b/packages/SystemUI/res/values-kn-rIN/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP ಮುಚ್ಚಿ"</string> + <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>"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-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml index a3f4ff13b54e..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> @@ -220,6 +222,10 @@ <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_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-ko/strings_tv.xml b/packages/SystemUI/res/values-ko/strings_tv.xml new file mode 100644 index 000000000000..ea12d5e6a6cc --- /dev/null +++ b/packages/SystemUI/res/values-ko/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP 닫기"</string> + <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"><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 96ffa96ebc0e..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> @@ -220,6 +222,10 @@ <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_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-ky-rKG/strings_tv.xml b/packages/SystemUI/res/values-ky-rKG/strings_tv.xml new file mode 100644 index 000000000000..e95bc8912282 --- /dev/null +++ b/packages/SystemUI/res/values-ky-rKG/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP\'ти жабуу"</string> + <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_onboarding_button" msgid="3957426748484904611">"Түшүндүм"</string> +</resources> diff --git a/packages/SystemUI/res/values-land/dimens.xml b/packages/SystemUI/res/values-land/dimens.xml index 26a81c8d835c..585984c9c99f 100644 --- a/packages/SystemUI/res/values-land/dimens.xml +++ b/packages/SystemUI/res/values-land/dimens.xml @@ -22,6 +22,9 @@ <!-- Standard notification gravity --> <integer name="notification_panel_layout_gravity">@integer/standard_notification_panel_layout_gravity</integer> + <!-- The size of the initial peek area at the bottom of the stack (above the nav bar). --> + <dimen name="recents_initial_bottom_peek_size">@dimen/recents_task_bar_height</dimen> + <dimen name="docked_divider_handle_width">2dp</dimen> <dimen name="docked_divider_handle_height">16dp</dimen> </resources> diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml index 8000621f7cd3..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> @@ -220,6 +221,10 @@ <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_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-lo-rLA/strings_tv.xml b/packages/SystemUI/res/values-lo-rLA/strings_tv.xml new file mode 100644 index 000000000000..f6bc833363aa --- /dev/null +++ b/packages/SystemUI/res/values-lo-rLA/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"ປິດ PIP"</string> + <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">"ກົດ "<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 bb49c393b603..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> @@ -222,6 +224,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Darbo režimas įjungtas."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Darbo režimas išjungtas."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Darbo režimas įjungtas."</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_brightness" msgid="8003681285547803095">"Ekrano šviesumas"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G duomenys pristabdyti"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G duomenys pristabdyti"</string> diff --git a/packages/SystemUI/res/values-lt/strings_tv.xml b/packages/SystemUI/res/values-lt/strings_tv.xml new file mode 100644 index 000000000000..140b55ddd62a --- /dev/null +++ b/packages/SystemUI/res/values-lt/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 574889eea686..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> @@ -221,6 +223,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Darba režīms ir ieslēgts."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Darba režīms ir izslēgts."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Darba režīms ir ieslēgts."</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_brightness" msgid="8003681285547803095">"Ekrāna spilgtums"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G–3G datu lietojums ir apturēts"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G datu lietojums ir apturēts"</string> diff --git a/packages/SystemUI/res/values-lv/strings_tv.xml b/packages/SystemUI/res/values-lv/strings_tv.xml new file mode 100644 index 000000000000..d7ca3704f00c --- /dev/null +++ b/packages/SystemUI/res/values-lv/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 58b7b751736e..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> @@ -220,6 +222,10 @@ <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_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-mk-rMK/strings_tv.xml b/packages/SystemUI/res/values-mk-rMK/strings_tv.xml new file mode 100644 index 000000000000..5f88cb5c4dce --- /dev/null +++ b/packages/SystemUI/res/values-mk-rMK/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Затвори PIP"</string> + <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">"Задржете "<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 6627645f8503..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> @@ -220,6 +222,10 @@ <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_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-ml-rIN/strings_tv.xml b/packages/SystemUI/res/values-ml-rIN/strings_tv.xml new file mode 100644 index 000000000000..0094bb6704e0 --- /dev/null +++ b/packages/SystemUI/res/values-ml-rIN/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP അടയ്ക്കുക"</string> + <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_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 a69be1fe5b14..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> @@ -218,6 +219,10 @@ <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_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-mn-rMN/strings_tv.xml b/packages/SystemUI/res/values-mn-rMN/strings_tv.xml new file mode 100644 index 000000000000..78b7cc859e6d --- /dev/null +++ b/packages/SystemUI/res/values-mn-rMN/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP-г хаах"</string> + <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>"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 d99678c52a77..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> @@ -220,6 +222,10 @@ <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_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-mr-rIN/strings_tv.xml b/packages/SystemUI/res/values-mr-rIN/strings_tv.xml new file mode 100644 index 000000000000..fd76c531356b --- /dev/null +++ b/packages/SystemUI/res/values-mr-rIN/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP बंद करा"</string> + <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_onboarding_button" msgid="3957426748484904611">"समजले"</string> +</resources> diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml index a716eef62236..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Mod kerja hidup."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Mod kerja dimatikan."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Mod kerja dihidupkan."</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_brightness" msgid="8003681285547803095">"Kecerahan paparan"</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-ms-rMY/strings_tv.xml b/packages/SystemUI/res/values-ms-rMY/strings_tv.xml new file mode 100644 index 000000000000..5fc98b9a1f25 --- /dev/null +++ b/packages/SystemUI/res/values-ms-rMY/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 503b91f1134b..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> @@ -220,6 +221,10 @@ <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_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 data ခေတ္တရပ်တန့်သည်"</string> diff --git a/packages/SystemUI/res/values-my-rMM/strings_tv.xml b/packages/SystemUI/res/values-my-rMM/strings_tv.xml new file mode 100644 index 000000000000..8491e371604a --- /dev/null +++ b/packages/SystemUI/res/values-my-rMM/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP ကိုပိတ်ပါ"</string> + <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_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 b3de2399fbfe..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Arbeidsmodusen er på."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Arbeidsmodusen er slått av."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Arbeidsmodusen er slått på."</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_brightness" msgid="8003681285547803095">"Lysstyrken på skjermen"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G- og 3G-data er satt på pause"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data er satt på pause"</string> diff --git a/packages/SystemUI/res/values-nb/strings_tv.xml b/packages/SystemUI/res/values-nb/strings_tv.xml new file mode 100644 index 000000000000..8574d66a3129 --- /dev/null +++ b/packages/SystemUI/res/values-nb/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Lukk PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Fullskjerm"</string> + <string name="pip_play" msgid="674145557658227044">"Spill av"</string> + <string name="pip_pause" msgid="8412075640017218862">"Sett på pause"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Hold inne "<b>"STARTSIDE"</b>" for å kontrollere PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Trykk og hold STARTSIDE-\nknappen for å kontrollere PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Greit"</string> +</resources> diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml index 2008553ad531..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,6 +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> + <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-ne-rNP/strings_tv.xml b/packages/SystemUI/res/values-ne-rNP/strings_tv.xml new file mode 100644 index 000000000000..68c86ca79fe0 --- /dev/null +++ b/packages/SystemUI/res/values-ne-rNP/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP लाई बन्द गर्नुहोस्"</string> + <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_onboarding_button" msgid="3957426748484904611">"बुझेँ"</string> +</resources> diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml index 9698cdff6eca..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> @@ -220,6 +221,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Werkmodus aan."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Werkmodus uitgeschakeld."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Werkmodus ingeschakeld."</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_brightness" msgid="8003681285547803095">"Helderheid van het scherm"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G/3G-data zijn onderbroken"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data zijn onderbroken"</string> diff --git a/packages/SystemUI/res/values-nl/strings_tv.xml b/packages/SystemUI/res/values-nl/strings_tv.xml new file mode 100644 index 000000000000..c116f817da3d --- /dev/null +++ b/packages/SystemUI/res/values-nl/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP sluiten"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Volledig scherm"</string> + <string name="pip_play" msgid="674145557658227044">"Afspelen"</string> + <string name="pip_pause" msgid="8412075640017218862">"Onderbreken"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Bedien PIP met "<b>"HOME"</b></string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Houd HOME ingedrukt\nom PIP te bedienen"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string> +</resources> diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml index 6fb2c703ecb6..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> @@ -220,6 +221,10 @@ <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_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-pa-rIN/strings_tv.xml b/packages/SystemUI/res/values-pa-rIN/strings_tv.xml new file mode 100644 index 000000000000..1bf28af27ebe --- /dev/null +++ b/packages/SystemUI/res/values-pa-rIN/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP ਬੰਦ ਕਰੋ"</string> + <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_onboarding_button" msgid="3957426748484904611">"ਸਮਝ ਲਿਆ"</string> +</resources> diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml index 974685c80358..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> @@ -222,6 +224,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Tryb pracy włączony."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Tryb pracy wyłączony."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Tryb pracy włączony."</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_brightness" msgid="8003681285547803095">"Jasność wyświetlacza"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Transmisja danych 2G-3G została wstrzymana"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Transmisja danych 4G została wstrzymana"</string> diff --git a/packages/SystemUI/res/values-pl/strings_tv.xml b/packages/SystemUI/res/values-pl/strings_tv.xml new file mode 100644 index 000000000000..b804146643ab --- /dev/null +++ b/packages/SystemUI/res/values-pl/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Zamknij PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Pełny ekran"</string> + <string name="pip_play" msgid="674145557658227044">"Odtwórz"</string> + <string name="pip_pause" msgid="8412075640017218862">"Wstrzymaj"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Przytrzymaj "<b>"EKRAN GŁÓWNY"</b>", by sterować PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Przytrzymaj EKRAN GŁÓWNY,\nby sterować PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string> +</resources> diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml index 3797adcce447..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Modo de trabalho ativado."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Modo de trabalho desativado."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Modo de trabalho ativado."</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_brightness" msgid="8003681285547803095">"Brilho da tela"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Os dados 2G e 3G foram pausados"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Os dados 4G foram pausados"</string> @@ -303,8 +309,7 @@ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixação de tela"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string> - <!-- no translation found for recents_launch_disabled_message (1624523193008871793) --> - <skip /> + <string name="recents_launch_disabled_message" msgid="1624523193008871793">"O app <xliff:g id="APP">%s</xliff:g> está desativado no modo de segurança."</string> <string name="recents_history_button_label" msgid="5153358867807604821">"Histórico"</string> <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Limpar"</string> <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Este app não é compatível com o modo de várias janelas"</string> diff --git a/packages/SystemUI/res/values-pt-rBR/strings_tv.xml b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml new file mode 100644 index 000000000000..21d36e09e425 --- /dev/null +++ b/packages/SystemUI/res/values-pt-rBR/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 7ee2554e8093..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> @@ -220,6 +221,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Modo de trabalho ativado."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"O modo de trabalho foi desativado."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"O modo de trabalho foi ativado."</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_brightness" msgid="8003681285547803095">"Brilho do visor"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Dados 2G-3G em pausa"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Dados 4G em pausa"</string> diff --git a/packages/SystemUI/res/values-pt-rPT/strings_tv.xml b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml new file mode 100644 index 000000000000..8b1b032eb3ff --- /dev/null +++ b/packages/SystemUI/res/values-pt-rPT/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Fechar PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Ecrã inteiro"</string> + <string name="pip_play" msgid="674145557658227044">"Reproduzir"</string> + <string name="pip_pause" msgid="8412075640017218862">"Interromper"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Prima sem soltar o botão "<b>"HOME"</b>" para controlar o PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Prima sem soltar o botão HOME\npara controlar o PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Compreendi"</string> +</resources> diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml index 3797adcce447..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Modo de trabalho ativado."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Modo de trabalho desativado."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Modo de trabalho ativado."</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_brightness" msgid="8003681285547803095">"Brilho da tela"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Os dados 2G e 3G foram pausados"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Os dados 4G foram pausados"</string> @@ -303,8 +309,7 @@ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"fixação de tela"</string> <string name="recents_search_bar_label" msgid="8074997400187836677">"pesquisar"</string> <string name="recents_launch_error_message" msgid="2969287838120550506">"Não foi possível iniciar <xliff:g id="APP">%s</xliff:g>."</string> - <!-- no translation found for recents_launch_disabled_message (1624523193008871793) --> - <skip /> + <string name="recents_launch_disabled_message" msgid="1624523193008871793">"O app <xliff:g id="APP">%s</xliff:g> está desativado no modo de segurança."</string> <string name="recents_history_button_label" msgid="5153358867807604821">"Histórico"</string> <string name="recents_history_clear_all_button_label" msgid="5905258334958006953">"Limpar"</string> <string name="recents_drag_non_dockable_task_message" msgid="2935843902795166158">"Este app não é compatível com o modo de várias janelas"</string> diff --git a/packages/SystemUI/res/values-pt/strings_tv.xml b/packages/SystemUI/res/values-pt/strings_tv.xml new file mode 100644 index 000000000000..21d36e09e425 --- /dev/null +++ b/packages/SystemUI/res/values-pt/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 c2bec081e7f4..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> @@ -221,6 +223,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Modul de lucru este activat."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Modul de lucru a fost dezactivat."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Modul de lucru a fost activat."</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_brightness" msgid="8003681285547803095">"Luminozitatea ecranului"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Conexiunea de date 2G – 3G este întreruptă"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Conexiunea de date 4G este întreruptă"</string> diff --git a/packages/SystemUI/res/values-ro/strings_tv.xml b/packages/SystemUI/res/values-ro/strings_tv.xml new file mode 100644 index 000000000000..e30b2f9fdf4e --- /dev/null +++ b/packages/SystemUI/res/values-ro/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Î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> + <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 8ece7faed224..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> @@ -222,6 +224,10 @@ <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_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-ru/strings_tv.xml b/packages/SystemUI/res/values-ru/strings_tv.xml new file mode 100644 index 000000000000..f25b460916d4 --- /dev/null +++ b/packages/SystemUI/res/values-ru/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"\"Кадр в кадре\" – выйти"</string> + <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">"Управляйте кадром в кадре, удерживая кнопку "<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 b4853201b1ae..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> @@ -220,6 +221,10 @@ <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_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-si-rLK/strings_tv.xml b/packages/SystemUI/res/values-si-rLK/strings_tv.xml new file mode 100644 index 000000000000..b2c6485ac3a6 --- /dev/null +++ b/packages/SystemUI/res/values-si-rLK/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP වසන්න"</string> + <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>"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-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml index 40daf19e09d2..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,6 +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> + <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-sk/strings_tv.xml b/packages/SystemUI/res/values-sk/strings_tv.xml new file mode 100644 index 000000000000..46f88f90b9c0 --- /dev/null +++ b/packages/SystemUI/res/values-sk/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Zavrieť režim PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Celá obrazovka"</string> + <string name="pip_play" msgid="674145557658227044">"Prehrať"</string> + <string name="pip_pause" msgid="8412075640017218862">"Pozastaviť"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Režim PIP ovládajte pomocou tlačidla "<b>"PLOCHA"</b></string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Režim PIP ovládajte stlačením a podržaním tlačidla PLOCHA\n"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Dobre"</string> +</resources> diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml index 756c43df4e45..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> @@ -222,6 +223,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Način za delo vklopljen."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Način za delo je izklopljen."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Način za delo je vklopljen."</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_brightness" msgid="8003681285547803095">"Svetlost zaslona"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Prenos podatkov v omrežju 2G/3G je zaustavljen"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Prenos podatkov v omrežju 4G je zaustavljen"</string> diff --git a/packages/SystemUI/res/values-sl/strings_tv.xml b/packages/SystemUI/res/values-sl/strings_tv.xml new file mode 100644 index 000000000000..e1d160413914 --- /dev/null +++ b/packages/SystemUI/res/values-sl/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 8b3861e6972c..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Modaliteti i punës është i aktivizuar."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Modaliteti i punës është i çaktivizuar."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Modaliteti i punës është i aktivizuar."</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_brightness" msgid="8003681285547803095">"Ndriçimi i ekranit"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Të dhënat 2G-3G janë ndërprerë"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Të dhënat 4G janë ndërprerë"</string> diff --git a/packages/SystemUI/res/values-sq-rAL/strings_tv.xml b/packages/SystemUI/res/values-sq-rAL/strings_tv.xml new file mode 100644 index 000000000000..28bfbb5b3fe5 --- /dev/null +++ b/packages/SystemUI/res/values-sq-rAL/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 991e9e2718b2..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> @@ -221,6 +223,10 @@ <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_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-sr/strings_tv.xml b/packages/SystemUI/res/values-sr/strings_tv.xml new file mode 100644 index 000000000000..4b03b6894a90 --- /dev/null +++ b/packages/SystemUI/res/values-sr/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Затвори PIP"</string> + <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"><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-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml index d35fad5770cf..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Arbetsläget aktiverat."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Arbetsläget har inaktiverats."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Arbetsläget har aktiverats."</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_brightness" msgid="8003681285547803095">"Skärmens ljusstyrka"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G- och 3G-data har pausats"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G-data har pausats"</string> diff --git a/packages/SystemUI/res/values-sv/strings_tv.xml b/packages/SystemUI/res/values-sv/strings_tv.xml new file mode 100644 index 000000000000..dc65877621d7 --- /dev/null +++ b/packages/SystemUI/res/values-sv/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Stäng PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Helskärm"</string> + <string name="pip_play" msgid="674145557658227044">"Spela upp"</string> + <string name="pip_pause" msgid="8412075640017218862">"Pausa"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Styr PIP med "<b>"startknappen"</b></string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Håll ned startknappen\n för att styra PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"OK"</string> +</resources> diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml index ddc1c0a6868f..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Hali ya kazi imewashwa."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Hali ya kazi imezimwa."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Hali ya kazi imewashwa."</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_brightness" msgid="8003681285547803095">"Ung\'aavu wa skrini"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Data ya 2G-3G imesitishwa"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Data ya 4G imesitishwa"</string> diff --git a/packages/SystemUI/res/values-sw/strings_tv.xml b/packages/SystemUI/res/values-sw/strings_tv.xml new file mode 100644 index 000000000000..9b3799adde1b --- /dev/null +++ b/packages/SystemUI/res/values-sw/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Funga PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Skrini nzima"</string> + <string name="pip_play" msgid="674145557658227044">"Cheza"</string> + <string name="pip_pause" msgid="8412075640017218862">"Sitisha"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Shikilia kitufe cha "<b>"HOME"</b>" ili udhibiti PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Bonyeza na ushikilie kitufe cha\nHOME ili udhibiti PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Nimeelewa"</string> +</resources> diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml index 122413d2677a..a2fa3b976922 100644 --- a/packages/SystemUI/res/values-sw600dp/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -99,6 +99,9 @@ <!-- The top padding for the task stack. --> <dimen name="recents_stack_top_padding">40dp</dimen> + <!-- The size of the initial peek area at the bottom of the stack (above the nav bar). --> + <dimen name="recents_initial_bottom_peek_size">100dp</dimen> + <!-- The side padding for the task stack. --> <dimen name="recents_stack_left_right_padding">64dp</dimen> </resources> diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml index 66a14963a823..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> @@ -220,6 +222,10 @@ <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_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-ta-rIN/strings_tv.xml b/packages/SystemUI/res/values-ta-rIN/strings_tv.xml new file mode 100644 index 000000000000..d4d661a31f25 --- /dev/null +++ b/packages/SystemUI/res/values-ta-rIN/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIPஐ மூடு"</string> + <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_onboarding_button" msgid="3957426748484904611">"சரி"</string> +</resources> diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml index d02b35321ec2..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> @@ -220,6 +222,10 @@ <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_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-te-rIN/strings_tv.xml b/packages/SystemUI/res/values-te-rIN/strings_tv.xml new file mode 100644 index 000000000000..4c18743006a0 --- /dev/null +++ b/packages/SystemUI/res/values-te-rIN/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIPని మూసివేయి"</string> + <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>"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-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml index 9b1ea748fca4..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> @@ -220,6 +221,10 @@ <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_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-th/strings_tv.xml b/packages/SystemUI/res/values-th/strings_tv.xml new file mode 100644 index 000000000000..f1c24ec646a6 --- /dev/null +++ b/packages/SystemUI/res/values-th/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"ปิด PIP"</string> + <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">"กด "<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 d131c84a8e61..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> @@ -220,6 +221,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Naka-on ang work mode."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Na-off ang work mode."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Na-on ang work mode."</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_brightness" msgid="8003681285547803095">"Liwanag ng display"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Naka-pause ang 2G-3G data"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Naka-pause ang 4G data"</string> diff --git a/packages/SystemUI/res/values-tl/strings_tv.xml b/packages/SystemUI/res/values-tl/strings_tv.xml new file mode 100644 index 000000000000..85a4f5b662d0 --- /dev/null +++ b/packages/SystemUI/res/values-tl/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 fd9e14ce2fcb..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Çalışma modu açık."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Çalışma modu kapatıldı."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Çalışma modu açıldı."</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_brightness" msgid="8003681285547803095">"Ekran parlaklığı"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G veri kullanımı duraklatıldı"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G veri kullanımı duraklatıldı"</string> diff --git a/packages/SystemUI/res/values-tr/strings_tv.xml b/packages/SystemUI/res/values-tr/strings_tv.xml new file mode 100644 index 000000000000..ea136b14fe1a --- /dev/null +++ b/packages/SystemUI/res/values-tr/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 e5bf06dd880e..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> @@ -222,6 +224,10 @@ <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_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-uk/strings_tv.xml b/packages/SystemUI/res/values-uk/strings_tv.xml new file mode 100644 index 000000000000..22bcf52ba4aa --- /dev/null +++ b/packages/SystemUI/res/values-uk/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Закрити PIP"</string> + <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_onboarding_button" msgid="3957426748484904611">"OK"</string> +</resources> diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml index 7a10732d832d..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> @@ -220,6 +222,10 @@ <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_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-ur-rPK/strings_tv.xml b/packages/SystemUI/res/values-ur-rPK/strings_tv.xml new file mode 100644 index 000000000000..4929f81fbce6 --- /dev/null +++ b/packages/SystemUI/res/values-ur-rPK/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"PIP بند کریں"</string> + <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_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 79729dcf107e..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Ish rejimi yoniq."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Ish rejimi o‘chirib qo‘yildi."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Ishchi rejim yoqildi."</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_brightness" msgid="8003681285547803095">"Ekran yorqinligi"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G internet to‘xtatib qo‘yildi"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G internet to‘xtatib qo‘yildi"</string> diff --git a/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml b/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml new file mode 100644 index 000000000000..d6ffb67f6b09 --- /dev/null +++ b/packages/SystemUI/res/values-uz-rUZ/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"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> + <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 074a8a0ba96d..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> @@ -220,6 +221,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Chế độ làm việc bật."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Chế độ làm việc đã tắt."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Chế độ làm việc đã bật."</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_brightness" msgid="8003681285547803095">"Độ sáng màn hình"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"Đã tạm dừng dữ liệu 2G-3G"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"Đã tạm dừng dữ liệu 4G"</string> diff --git a/packages/SystemUI/res/values-vi/strings_tv.xml b/packages/SystemUI/res/values-vi/strings_tv.xml new file mode 100644 index 000000000000..48ba4440082f --- /dev/null +++ b/packages/SystemUI/res/values-vi/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Đó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> + <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 dd5ea1fd8994..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> @@ -220,6 +222,10 @@ <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_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-zh-rCN/strings_tv.xml b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml new file mode 100644 index 000000000000..860df351ded2 --- /dev/null +++ b/packages/SystemUI/res/values-zh-rCN/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"关闭 PIP"</string> + <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">"按住"<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 bd379b716a74..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> @@ -220,6 +221,10 @@ <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_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> @@ -506,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 new file mode 100644 index 000000000000..8e5a2df9743c --- /dev/null +++ b/packages/SystemUI/res/values-zh-rHK/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"關閉 PIP"</string> + <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">"按住"<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 d580b28d63f5..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> @@ -220,6 +222,10 @@ <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_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-zh-rTW/strings_tv.xml b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml new file mode 100644 index 000000000000..60edac232e1f --- /dev/null +++ b/packages/SystemUI/res/values-zh-rTW/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"關閉子母畫面"</string> + <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">"按住「主畫面」"<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 9382b260f1df..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> @@ -220,6 +222,10 @@ <string name="accessibility_quick_settings_work_mode_on" msgid="7650588553988014341">"Imodi yomsebenzi ivuliwe."</string> <string name="accessibility_quick_settings_work_mode_changed_off" msgid="5605534876107300711">"Imodi yomsebenzi ivaliwe."</string> <string name="accessibility_quick_settings_work_mode_changed_on" msgid="249840330756998612">"Imodi yomsebenzi ivuliwe."</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_brightness" msgid="8003681285547803095">"Bonisa ukukhanya"</string> <string name="data_usage_disabled_dialog_3g_title" msgid="5281770593459841889">"2G-3G idatha imisiwe"</string> <string name="data_usage_disabled_dialog_4g_title" msgid="1601769736881078016">"4G idatha imisiwe"</string> diff --git a/packages/SystemUI/res/values-zu/strings_tv.xml b/packages/SystemUI/res/values-zu/strings_tv.xml new file mode 100644 index 000000000000..b901f906b583 --- /dev/null +++ b/packages/SystemUI/res/values-zu/strings_tv.xml @@ -0,0 +1,29 @@ +<?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">"Vala i-PIP"</string> + <string name="pip_fullscreen" msgid="8604643018538487816">"Iskrini esigcwele"</string> + <string name="pip_play" msgid="674145557658227044">"Dlala"</string> + <string name="pip_pause" msgid="8412075640017218862">"Misa isikhashana"</string> + <string name="pip_hold_home" msgid="340086535668778109">"Bamba "<b>"IKHAYA"</b>" ukuze ulawule i-PIP"</string> + <string name="pip_onboarding_description" msgid="2627737116380318292">"Cindezela uphinde ubambe inkinobho YASEKHAYA\nukuze ulawule i-PIP"</string> + <string name="pip_onboarding_button" msgid="3957426748484904611">"Ngiyezwa"</string> +</resources> 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/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 12c3a5d8cb50..e50f975c873f 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -58,19 +58,19 @@ <item name="status_bar_icon_scale_factor" format="float" type="dimen">1.0</item> <!-- Height of a small notification in the status bar--> - <dimen name="notification_min_height">86dp</dimen> + <dimen name="notification_min_height">92dp</dimen> <!-- Height of a small notification in the status bar which was used before android N --> <dimen name="notification_min_height_legacy">64dp</dimen> <!-- Height of a large notification in the status bar --> - <dimen name="notification_max_height">276dp</dimen> + <dimen name="notification_max_height">284dp</dimen> <!-- Height of a heads up notification in the status bar for legacy custom views --> <dimen name="notification_max_heads_up_height_legacy">128dp</dimen> <!-- Height of a heads up notification in the status bar --> - <dimen name="notification_max_heads_up_height">141dp</dimen> + <dimen name="notification_max_heads_up_height">148dp</dimen> <!-- Height of a the summary ("more card") notification on keyguard. --> <dimen name="notification_summary_height">44dp</dimen> @@ -295,6 +295,9 @@ <!-- The size of the initial peek area at the top of the stack (below the status bar). --> <dimen name="recents_initial_top_peek_size">8dp</dimen> + <!-- The size of the initial peek area at the bottom of the stack (above the nav bar). --> + <dimen name="recents_initial_bottom_peek_size">100dp</dimen> + <!-- The size of the peek area at the top of the stack (below the status bar). --> <dimen name="recents_layout_focused_top_peek_size">@dimen/recents_history_button_height</dimen> @@ -307,6 +310,9 @@ <!-- The padding between freeform workspace tasks --> <dimen name="recents_freeform_workspace_task_padding">8dp</dimen> + <!-- The offsets the tasks animate from when recents is launched while docking --> + <dimen name="recents_task_view_launched_while_docking_offset">144dp</dimen> + <!-- Space reserved for the cards behind the top card in the bottom stack --> <dimen name="bottom_stack_peek_amount">12dp</dimen> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index 1f239c3d1aa8..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> @@ -523,6 +525,10 @@ <string name="accessibility_quick_settings_work_mode_changed_off">Work mode turned off.</string> <!-- Announcement made when the work mode changes to on (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_quick_settings_work_mode_changed_on">Work mode turned on.</string> + <!-- Announcement made when the Data Saver changes to off (not shown on the screen). [CHAR LIMIT=NONE] --> + <string name="accessibility_quick_settings_data_saver_changed_off">Data Saver turned off.</string> + <!-- Announcement made when the Data Saver changes to on (not shown on the screen). [CHAR LIMIT=NONE] --> + <string name="accessibility_quick_settings_data_saver_changed_on">Data Saver turned on.</string> <!-- Content description of the display brightness slider (not shown on the screen). [CHAR LIMIT=NONE] --> <string name="accessibility_brightness">Display brightness</string> diff --git a/packages/SystemUI/res/values/strings_tv.xml b/packages/SystemUI/res/values/strings_tv.xml index c7fb0eca4665..b35038d0776c 100644 --- a/packages/SystemUI/res/values/strings_tv.xml +++ b/packages/SystemUI/res/values/strings_tv.xml @@ -17,26 +17,25 @@ */ --> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> - <!-- Picture-in-Picture menu --> + <!-- Picture-in-Picture (PIP) menu --> <eat-comment /> - <!-- Button to close PIP on PIP UI --> - <string name="pip_close" translatable="false">Close PIP</string> - <!-- Button to move PIP screen to the fullscreen on PIP UI --> - <string name="pip_fullscreen" translatable="false">Full screen</string> - <!-- Button to play the current media on PIP UI --> - <string name="pip_play" translatable="false">Play</string> - <!-- Button to pause the current media on PIP UI --> - <string name="pip_pause" translatable="false">Pause</string> - <!-- Button to close PIP overlay menu on PIP UI --> - <string name="pip_cancel" translatable="false">Cancel</string> - <!-- Overlay text on PIP --> - <string name="pip_hold_home" translatable="false">Hold <b>HOME</b> to control PIP</string> - <!-- Picture-in-Picture onboarding screen --> + <!-- Button to close picture-in-picture (PIP) in PIP menu [CHAR LIMIT=16] --> + <string name="pip_close">Close PIP</string> + <!-- Button to move picture-in-picture (PIP) screen to the fullscreen in PIP menu [CHAR LIMIT=16] --> + <string name="pip_fullscreen">Full screen</string> + <!-- Button to play the current media on picture-in-picture (PIP) [CHAR LIMIT=16] --> + <string name="pip_play">Play</string> + <!-- Button to pause the current media on picture-in-picture (PIP) [CHAR LIMIT=16] --> + <string name="pip_pause">Pause</string> + <!-- Overlay text on picture-in-picture (PIP) to indicate that longpress HOME key to control PIP [CHAR LIMIT=25] --> + <string name="pip_hold_home">Hold <b>HOME</b> to control PIP</string> + <!-- Picture-in-Picture (PIP) onboarding screen --> <eat-comment /> - <!-- Description for onboarding screen. --> - <string name="pip_onboarding_description" translatable="false">Press and hold the HOME\nbutton to close or control it</string> - <!-- Button to close onboarding screen. --> - <string name="pip_onboarding_button" translatable="false">Got it</string> + <!-- Description for picture-in-picture (PIP) onboarding screen to indicate that longpress HOME key to control PIP. + Line break is needed as if we have CHAR LIMIT=25. [CHAR LIMIT=NONE] --> + <string name="pip_onboarding_description">Press and hold the HOME\nbutton to control PIP</string> + <!-- Button to close picture-in-picture (PIP) onboarding screen. --> + <string name="pip_onboarding_button">Got it</string> <!-- Font for Recents --> <!-- DO NOT TRANSLATE --> <string name="font_roboto_regular" translatable="false">sans-serif</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 f6dcc115401d..81ba23f27f23 100644 --- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java +++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java @@ -32,6 +32,7 @@ import android.view.ViewConfiguration; import android.view.accessibility.AccessibilityEvent; import com.android.systemui.classifier.FalsingManager; +import com.android.systemui.statusbar.FlingAnimationUtils; public class SwipeHelper implements Gefingerpoken { static final String TAG = "com.android.systemui.SwipeHelper"; @@ -58,6 +59,7 @@ public class SwipeHelper implements Gefingerpoken { private float mMinSwipeProgress = 0f; private float mMaxSwipeProgress = 1f; + private FlingAnimationUtils mFlingAnimationUtils; private float mPagingTouchSlop; private Callback mCallback; private Handler mHandler; @@ -95,6 +97,8 @@ public class SwipeHelper implements Gefingerpoken { mFalsingThreshold = context.getResources().getDimensionPixelSize( R.dimen.swipe_helper_falsing_threshold); mFalsingManager = FalsingManager.getInstance(context); + mFlingAnimationUtils = new FlingAnimationUtils(context, + MAX_ESCAPE_ANIMATION_DURATION / 1000f /* maxLengthSeconds */); } public void setLongPressListener(LongPressListener listener) { @@ -320,7 +324,8 @@ public class SwipeHelper implements Gefingerpoken { * @param velocity The desired pixels/second speed at which the view should move */ public void dismissChild(final View view, float velocity) { - dismissChild(view, velocity, null, 0, false, 0); + dismissChild(view, velocity, null /* endAction */, 0 /* delay */, + velocity == 0 /* useAccelerateInterpolator */, 0 /* fixedDuration */); } /** @@ -377,10 +382,11 @@ public class SwipeHelper implements Gefingerpoken { } if (useAccelerateInterpolator) { anim.setInterpolator(Interpolators.FAST_OUT_LINEAR_IN); + anim.setDuration(duration); } else { - anim.setInterpolator(Interpolators.LINEAR); + mFlingAnimationUtils.applyDismissing(anim, getTranslation(animView), + newPos, velocity, getSize(animView)); } - anim.setDuration(duration); if (delay > 0) { anim.setStartDelay(delay); } @@ -511,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); @@ -556,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/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java index 6029c23ab30b..312d3c5dc650 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java @@ -684,7 +684,7 @@ public class KeyguardViewMediator extends SystemUI { doKeyguardLocked(null); mUpdateMonitor.registerCallback(mUpdateCallback); } - mIsPerUserLock = StorageManager.isFileBasedEncryptionEnabled(); + mIsPerUserLock = StorageManager.isFileEncryptedNativeOrEmulated(); // Most services aren't available until the system reaches the ready state, so we // send it here when the device first boots. maybeSendUserPresentBroadcast(); diff --git a/packages/SystemUI/src/com/android/systemui/qs/PathInterpolatorBuilder.java b/packages/SystemUI/src/com/android/systemui/qs/PathInterpolatorBuilder.java new file mode 100644 index 000000000000..b8cb92a1619a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/qs/PathInterpolatorBuilder.java @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the + * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the specific language governing + * permissions and limitations under the License. + */ + +package com.android.systemui.qs; + +import android.graphics.Path; +import android.view.animation.BaseInterpolator; +import android.view.animation.Interpolator; + +public class PathInterpolatorBuilder { + + // This governs how accurate the approximation of the Path is. + private static final float PRECISION = 0.002f; + + private float[] mX; // x coordinates in the line + private float[] mY; // y coordinates in the line + private float[] mDist; // Cumulative percentage length of the line + + public PathInterpolatorBuilder(Path path) { + initPath(path); + } + + public PathInterpolatorBuilder(float controlX, float controlY) { + initQuad(controlX, controlY); + } + + public PathInterpolatorBuilder(float controlX1, float controlY1, float controlX2, + float controlY2) { + initCubic(controlX1, controlY1, controlX2, controlY2); + } + + private void initQuad(float controlX, float controlY) { + Path path = new Path(); + path.moveTo(0, 0); + path.quadTo(controlX, controlY, 1f, 1f); + initPath(path); + } + + private void initCubic(float x1, float y1, float x2, float y2) { + Path path = new Path(); + path.moveTo(0, 0); + path.cubicTo(x1, y1, x2, y2, 1f, 1f); + initPath(path); + } + + private void initPath(Path path) { + float[] pointComponents = path.approximate(PRECISION); + + int numPoints = pointComponents.length / 3; + if (pointComponents[1] != 0 || pointComponents[2] != 0 + || pointComponents[pointComponents.length - 2] != 1 + || pointComponents[pointComponents.length - 1] != 1) { + throw new IllegalArgumentException("The Path must start at (0,0) and end at (1,1)"); + } + + mX = new float[numPoints]; + mY = new float[numPoints]; + mDist = new float[numPoints]; + float prevX = 0; + float prevFraction = 0; + int componentIndex = 0; + for (int i = 0; i < numPoints; i++) { + float fraction = pointComponents[componentIndex++]; + float x = pointComponents[componentIndex++]; + float y = pointComponents[componentIndex++]; + if (fraction == prevFraction && x != prevX) { + throw new IllegalArgumentException( + "The Path cannot have discontinuity in the X axis."); + } + if (x < prevX) { + throw new IllegalArgumentException("The Path cannot loop back on itself."); + } + mX[i] = x; + mY[i] = y; + if (i > 0) { + float dx = mX[i] - mX[i - 1]; + float dy = mY[i] - mY[i - 1]; + float dist = (float) Math.sqrt(dx * dx + dy * dy); + mDist[i] = mDist[i - 1] + dist; + } + prevX = x; + prevFraction = fraction; + } + // Scale down dist to 0-1. + float max = mDist[mDist.length - 1]; + for (int i = 0; i < numPoints; i++) { + mDist[i] /= max; + } + } + + public Interpolator getXInterpolator() { + return new PathInterpolator(mDist, mX); + } + + public Interpolator getYInterpolator() { + return new PathInterpolator(mDist, mY); + } + + private static class PathInterpolator extends BaseInterpolator { + private final float[] mX; // x coordinates in the line + private final float[] mY; // y coordinates in the line + + private PathInterpolator(float[] xs, float[] ys) { + mX = xs; + mY = ys; + } + + @Override + public float getInterpolation(float t) { + if (t <= 0) { + return 0; + } else if (t >= 1) { + return 1; + } + // Do a binary search for the correct x to interpolate between. + int startIndex = 0; + int endIndex = mX.length - 1; + + while (endIndex - startIndex > 1) { + int midIndex = (startIndex + endIndex) / 2; + if (t < mX[midIndex]) { + endIndex = midIndex; + } else { + startIndex = midIndex; + } + } + + float xRange = mX[endIndex] - mX[startIndex]; + if (xRange == 0) { + return mY[startIndex]; + } + + float tInRange = t - mX[startIndex]; + float fraction = tInRange / xRange; + + float startY = mY[startIndex]; + float endY = mY[endIndex]; + return startY + (fraction * (endY - startY)); + } + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java index c8c71cb441b8..f601f908be2f 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java @@ -53,7 +53,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha private boolean mOnFirstPage = true; private TouchAnimator mFirstPageAnimator; private TouchAnimator mFirstPageDelayedAnimator; - private TouchAnimator mTranslationAnimator; + private TouchAnimator mTranslationXAnimator; + private TouchAnimator mTranslationYAnimator; private TouchAnimator mNonfirstPageAnimator; private boolean mOnKeyguard; @@ -138,6 +139,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha firstPageBuilder.setListener(this); // Fade in the tiles/labels as we reach the final position. firstPageDelayedBuilder.addFloat(mQsPanel.getTileLayout(), "alpha", 0, 1); + clearAnimationState(); mAllViews.clear(); mTopFiveQs.clear(); mAllViews.add((View) mQsPanel.getTileLayout()); @@ -188,13 +190,15 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha Path path = new Path(); path.moveTo(0, 0); path.cubicTo(0, 0, 0, 1, 1, 1); - mTranslationAnimator = new TouchAnimator.Builder() - .addPath(translationXBuilder.build(), translationYBuilder.build(), - "position", "position", path) - .build(); + PathInterpolatorBuilder interpolatorBuilder = new PathInterpolatorBuilder(0, 0, 0, 1); + translationXBuilder.setInterpolator(interpolatorBuilder.getXInterpolator()); + translationYBuilder.setInterpolator(interpolatorBuilder.getYInterpolator()); + mTranslationXAnimator = translationXBuilder.build(); + mTranslationYAnimator = translationYBuilder.build(); } mNonfirstPageAnimator = new TouchAnimator.Builder() .addFloat(mQuickQsPanel, "alpha", 1, 0) + .setListener(mNonFirstPageListener) .setEndDelay(.5f) .build(); } @@ -229,7 +233,8 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha mQuickQsPanel.setAlpha(1); mFirstPageAnimator.setPosition(position); mFirstPageDelayedAnimator.setPosition(position); - mTranslationAnimator.setPosition(position); + mTranslationXAnimator.setPosition(position); + mTranslationYAnimator.setPosition(position); } else { mNonfirstPageAnimator.setPosition(position); } @@ -263,7 +268,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha private void clearAnimationState() { final int N = mAllViews.size(); mQuickQsPanel.setAlpha(0); - mQuickQsPanel.setVisibility(View.VISIBLE); + mQuickQsPanel.setVisibility(View.INVISIBLE); for (int i = 0; i < N; i++) { View v = mAllViews.get(i); v.setAlpha(1); @@ -289,6 +294,14 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha mQsPanel.post(mUpdateAnimators); } + private final TouchAnimator.Listener mNonFirstPageListener = + new TouchAnimator.ListenerAdapter() { + @Override + public void onAnimationStarted() { + mQuickQsPanel.setVisibility(View.VISIBLE); + } + }; + private Runnable mUpdateAnimators = new Runnable() { @Override public void run() { diff --git a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java index db1724570476..37f2528205f7 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java +++ b/packages/SystemUI/src/com/android/systemui/qs/TouchAnimator.java @@ -14,11 +14,8 @@ package com.android.systemui.qs; -import android.graphics.Path; -import android.graphics.PathMeasure; import android.util.FloatProperty; import android.util.MathUtils; -import android.util.Pair; import android.util.Property; import android.view.View; import android.view.animation.Interpolator; @@ -141,19 +138,6 @@ public class TouchAnimator { return this; } - public Builder addPath(Object target, String xProp, String yProp, - Path path) { - return addPath(target, target, xProp, yProp, path); - } - - public Builder addPath(Object xTarget, Object yTarget, String xProp, String yProp, - Path path) { - add(new Pair<>(xTarget, yTarget), - KeyframeSet.ofPath(getProperty(xTarget, xProp, float.class), - getProperty(yTarget, yProp, float.class), path)); - return this; - } - private void add(Object target, KeyframeSet keyframeSet) { mTargets.add(target); mValues.add(keyframeSet); @@ -241,10 +225,6 @@ public class TouchAnimator { public static KeyframeSet ofFloat(Property property, float... values) { return new FloatKeyframeSet((Property<?, Float>) property, values); } - - public static KeyframeSet ofPath(Property xProp, Property yProp, Path path) { - return new PathKeyframeSet<>(xProp, yProp, path); - } } private static class FloatKeyframeSet<T> extends KeyframeSet { @@ -282,31 +262,4 @@ public class TouchAnimator { mProperty.set((T) target, (int) (firstFloat + (secondFloat - firstFloat) * amount)); } } - - private static class PathKeyframeSet<T> extends KeyframeSet { - private final Property<T, Float> mXProp; - private final Property<T, Float> mYProp; - private final Path mPath; - private final PathMeasure mPathMeasure; - private final float mLength; - private final float[] mPos; - - public PathKeyframeSet(Property<T, Float> xProp, Property<T, Float> yProp, Path path) { - super(2); - mXProp = xProp; - mYProp = yProp; - mPath = path; - mPathMeasure = new PathMeasure(mPath, false); - mLength = mPathMeasure.getLength(); - mPos = new float[2]; - } - - @Override - protected void interpolate(int index, float amount, Object target) { - Pair<Object, Object> targets = (Pair<Object, Object>) target; - mPathMeasure.getPosTan(amount * mLength, mPos, null); - mXProp.set((T) targets.first, mPos[0]); - mYProp.set((T) targets.second, mPos[1]); - } - } } 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/qs/tiles/DataSaverTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java index fa235d33e4e5..74b3fdc0bf61 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java +++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/DataSaverTile.java @@ -73,6 +73,15 @@ public class DataSaverTile extends QSTile<QSTile.BooleanState> implements } @Override + protected String composeChangeAnnouncement() { + if (mState.value) { + return mContext.getString(R.string.accessibility_quick_settings_data_saver_changed_on); + } else { + return mContext.getString(R.string.accessibility_quick_settings_data_saver_changed_off); + } + } + + @Override public void onDataSaverChanged(boolean isDataSaving) { refreshState(isDataSaving); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl index cb8f0e7e91de..9a00d95d6060 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl +++ b/packages/SystemUI/src/com/android/systemui/recents/IRecentsSystemUserCallbacks.aidl @@ -16,6 +16,8 @@ package com.android.systemui.recents; +import android.graphics.Rect; + /** * Due to the fact that RecentsActivity is per-user, we need to establish an * interface (this) for the non-system user to register itself for callbacks and to @@ -27,6 +29,6 @@ oneway interface IRecentsSystemUserCallbacks { void updateRecentsVisibility(boolean visible); void startScreenPinning(); void sendRecentsDrawnEvent(); - void sendDockingTopTaskEvent(int dragMode); + void sendDockingTopTaskEvent(int dragMode, in Rect initialRect); void sendLaunchRecentsEvent(); } diff --git a/packages/SystemUI/src/com/android/systemui/recents/Recents.java b/packages/SystemUI/src/com/android/systemui/recents/Recents.java index efac0fb3d90a..2b6ed445a810 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/Recents.java +++ b/packages/SystemUI/src/com/android/systemui/recents/Recents.java @@ -23,7 +23,9 @@ import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.res.Configuration; +import android.graphics.Point; import android.graphics.Rect; +import android.hardware.display.DisplayManager; import android.os.Build; import android.os.Handler; import android.os.IBinder; @@ -43,7 +45,8 @@ 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.DockingTopTaskEvent; +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; import com.android.systemui.recents.events.component.ScreenPinningRequestEvent; @@ -389,6 +392,13 @@ public class Recents extends SystemUI return false; } + Point realSize = new Point(); + if (initialBounds == null) { + mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY) + .getRealSize(realSize); + initialBounds = new Rect(0, 0, realSize.x, realSize.y); + } + int currentUser = sSystemServicesProxy.getCurrentUser(); SystemServicesProxy ssp = Recents.getSystemServices(); ActivityManager.RunningTaskInfo topTask = ssp.getTopMostTask(); @@ -577,14 +587,15 @@ public class Recents extends SystemUI } } - public final void onBusEvent(final DockingTopTaskEvent event) { + public final void onBusEvent(final DockedTopTaskEvent event) { int processUser = sSystemServicesProxy.getProcessUser(); if (!sSystemServicesProxy.isSystemUser(processUser)) { postToSystemUser(new Runnable() { @Override public void run() { try { - mUserToSystemCallbacks.sendDockingTopTaskEvent(event.dragMode); + mUserToSystemCallbacks.sendDockingTopTaskEvent(event.dragMode, + event.initialRect); } catch (RemoteException e) { Log.e(TAG, "Callback failed", e); } @@ -609,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/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java index cd1a27fd0515..473956fbe4d7 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java @@ -431,13 +431,6 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD mIgnoreAltTabRelease = false; mIterateTrigger.stopDozing(); - - // Workaround for b/22542869, if the RecentsActivity is started again, but without going - // through SystemUI, we need to reset the config launch flags to ensure that we do not - // wait on the system to send a signal that was never queued. - RecentsConfiguration config = Recents.getConfiguration(); - RecentsActivityLaunchState launchState = config.getLaunchState(); - launchState.reset(); } @Override @@ -453,6 +446,13 @@ public class RecentsActivity extends Activity implements ViewTreeObserver.OnPreD mIsVisible = false; EventBus.getDefault().send(new RecentsVisibilityChangedEvent(this, false)); MetricsLogger.hidden(this, MetricsEvent.OVERVIEW_ACTIVITY); + + // Workaround for b/22542869, if the RecentsActivity is started again, but without going + // through SystemUI, we need to reset the config launch flags to ensure that we do not + // wait on the system to send a signal that was never queued. + RecentsConfiguration config = Recents.getConfiguration(); + RecentsActivityLaunchState launchState = config.getLaunchState(); + launchState.reset(); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java index 3ad2cc37cd17..d864df8331e1 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsImpl.java @@ -47,7 +47,7 @@ import com.android.systemui.Prefs; import com.android.systemui.R; import com.android.systemui.SystemUIApplication; import com.android.systemui.recents.events.EventBus; -import com.android.systemui.recents.events.activity.DockingTopTaskEvent; +import com.android.systemui.recents.events.activity.DockedTopTaskEvent; import com.android.systemui.recents.events.activity.EnterRecentsWindowLastAnimationFrameEvent; import com.android.systemui.recents.events.activity.HideRecentsEvent; import com.android.systemui.recents.events.activity.IterateRecentsEvent; @@ -66,7 +66,6 @@ import com.android.systemui.recents.model.RecentsTaskLoader; import com.android.systemui.recents.model.Task; import com.android.systemui.recents.model.TaskGrouping; import com.android.systemui.recents.model.TaskStack; -import com.android.systemui.recents.tv.views.TaskStackHorizontalGridView; import com.android.systemui.recents.views.TaskStackLayoutAlgorithm; import com.android.systemui.recents.views.TaskStackView; import com.android.systemui.recents.views.TaskStackViewScroller; @@ -569,7 +568,7 @@ public class RecentsImpl implements ActivityOptions.OnAnimationFinishedListener // Make sure we inform DividerView before we actually start the activity so we can change // the resize mode already. if (ssp.moveTaskToDockedStack(topTaskId, stackCreateMode, initialBounds)) { - EventBus.getDefault().send(new DockingTopTaskEvent(dragMode)); + EventBus.getDefault().send(new DockedTopTaskEvent(dragMode, initialBounds)); showRecents( false /* triggeredFromAltTab */, dragMode == NavigationBarGestureHelper.DRAG_MODE_RECENTS, @@ -760,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--) { @@ -826,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/RecentsSystemUser.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java index f8000b8990bf..ffeb4a10b050 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java +++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsSystemUser.java @@ -17,6 +17,7 @@ package com.android.systemui.recents; import android.content.Context; +import android.graphics.Rect; import android.os.IBinder; import android.os.RemoteException; import android.util.EventLog; @@ -26,7 +27,7 @@ import android.util.SparseArray; import com.android.systemui.EventLogConstants; import com.android.systemui.EventLogTags; import com.android.systemui.recents.events.EventBus; -import com.android.systemui.recents.events.activity.DockingTopTaskEvent; +import com.android.systemui.recents.events.activity.DockedTopTaskEvent; import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent; import com.android.systemui.recents.events.ui.RecentsDrawnEvent; @@ -91,8 +92,8 @@ public class RecentsSystemUser extends IRecentsSystemUserCallbacks.Stub { } @Override - public void sendDockingTopTaskEvent(int dragMode) throws RemoteException { - EventBus.getDefault().post(new DockingTopTaskEvent(dragMode)); + public void sendDockingTopTaskEvent(int dragMode, Rect initialRect) throws RemoteException { + EventBus.getDefault().post(new DockedTopTaskEvent(dragMode, initialRect)); } @Override diff --git a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockingTopTaskEvent.java b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedTopTaskEvent.java index 264c2c43bd2e..f1bc214670f5 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockingTopTaskEvent.java +++ b/packages/SystemUI/src/com/android/systemui/recents/events/activity/DockedTopTaskEvent.java @@ -16,16 +16,21 @@ package com.android.systemui.recents.events.activity; +import android.graphics.Rect; + import com.android.systemui.recents.events.EventBus; /** - * Fires when the user invoked the gesture to dock the top/left task. + * Fires when the user invoked the gesture to dock the top/left task after we called into window + * manager and before we start recents. */ -public class DockingTopTaskEvent extends EventBus.Event { +public class DockedTopTaskEvent extends EventBus.Event { public int dragMode; + public Rect initialRect; - public DockingTopTaskEvent(int dragMode) { + public DockedTopTaskEvent(int dragMode, Rect initialRect) { this.dragMode = dragMode; + this.initialRect = initialRect; } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java index dd825cb4331f..a91bbd4b6d45 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsTransitionHelper.java @@ -105,6 +105,9 @@ public class RecentsTransitionHelper { animStartedListener = new ActivityOptions.OnAnimationStartedListener() { @Override public void onAnimationStarted() { + // If we are launching into another task, cancel the previous task's + // window transition + EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task)); EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent()); if (screenPinningRequested) { @@ -119,6 +122,9 @@ public class RecentsTransitionHelper { animStartedListener = new ActivityOptions.OnAnimationStartedListener() { @Override public void onAnimationStarted() { + // If we are launching into another task, cancel the previous task's + // window transition + EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task)); EventBus.getDefault().send(new ExitRecentsWindowFirstAnimationFrameEvent()); } }; @@ -146,10 +152,6 @@ public class RecentsTransitionHelper { animStartedListener); } } - - // If we are launching into another task, cancel the previous task's - // window transition - EventBus.getDefault().send(new CancelEnterRecentsWindowAnimationEvent(task)); } /** @@ -278,7 +280,8 @@ public class RecentsTransitionHelper { } else { layoutAlgorithm.getStackTransformScreenCoordinates(task, stackScroll, mTmpTransform, null); - specs.add(composeAnimationSpec(taskView, mTmpTransform, true /* addHeaderBitmap */)); + specs.add(composeAnimationSpec(stackView, taskView, mTmpTransform, + true /* addHeaderBitmap */)); } return specs; } @@ -299,7 +302,8 @@ public class RecentsTransitionHelper { } else { layoutAlgorithm.getStackTransformScreenCoordinates(t, stackScroll, mTmpTransform, null); - specs.add(composeAnimationSpec(tv, mTmpTransform, true /* addHeaderBitmap */)); + specs.add(composeAnimationSpec(stackView, tv, mTmpTransform, + true /* addHeaderBitmap */)); } } } @@ -318,8 +322,8 @@ public class RecentsTransitionHelper { /** * Composes a single animation spec for the given {@link TaskView} */ - private static AppTransitionAnimationSpec composeAnimationSpec(TaskView taskView, - TaskViewTransform transform, boolean addHeaderBitmap) { + private static AppTransitionAnimationSpec composeAnimationSpec(TaskStackView stackView, + TaskView taskView, TaskViewTransform transform, boolean addHeaderBitmap) { Bitmap b = null; if (addHeaderBitmap) { float scale = transform.scale; @@ -341,6 +345,10 @@ public class RecentsTransitionHelper { Rect taskRect = new Rect(); transform.rect.round(taskRect); + if (stackView.getStack().getStackFrontMostTask(false /* includeFreeformTasks */) != + taskView.getTask()) { + taskRect.bottom = 2 * Recents.getSystemServices().getDisplayRect().height(); + } return new AppTransitionAnimationSpec(taskView.getTask().key.id, b, taskRect); } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java index 079d7b9148f0..84590f25149f 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsViewTouchHandler.java @@ -16,6 +16,7 @@ package com.android.systemui.recents.views; +import android.app.ActivityManager; import android.content.res.Configuration; import android.graphics.Point; import android.view.MotionEvent; @@ -149,7 +150,8 @@ public class RecentsViewTouchHandler { mTaskView.setTranslationY(y); mVisibleDockStates.clear(); - if (!ssp.hasDockedTask() && mRv.getTaskStack().getTaskCount() > 1) { + if (ActivityManager.supportsMultiWindow() && + !ssp.hasDockedTask() && mRv.getTaskStack().getTaskCount() > 1) { if (!event.task.isDockable) { Toast.makeText(mRv.getContext(), R.string.recents_drag_non_dockable_task_message, Toast.LENGTH_SHORT).show(); diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java index 758f4d82336b..b36d5d195138 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackAnimationHelper.java @@ -71,6 +71,8 @@ public class TaskStackAnimationHelper { public static final int ENTER_FROM_HOME_ALPHA_DURATION = 100; public static final int ENTER_FROM_HOME_TRANSLATION_DURATION = 333; + public static final int ENTER_WHILE_DOCKING_DURATION = 150; + private static final PathInterpolator ENTER_FROM_HOME_TRANSLATION_INTERPOLATOR = new PathInterpolator(0, 0, 0, 1f); private static final PathInterpolator ENTER_FROM_HOME_ALPHA_INTERPOLATOR = @@ -90,6 +92,9 @@ public class TaskStackAnimationHelper { private static final PathInterpolator FOCUS_BEHIND_NEXT_TASK_INTERPOLATOR = new PathInterpolator(0.4f, 0, 0.2f, 1f); + private static final PathInterpolator ENTER_WHILE_DOCKING_INTERPOLATOR = + new PathInterpolator(0, 0, 0.2f, 1f); + private TaskStackView mStackView; private TaskViewTransform mTmpTransform = new TaskViewTransform(); @@ -122,6 +127,8 @@ public class TaskStackAnimationHelper { int offscreenYOffset = stackLayout.mStackRect.height(); int taskViewAffiliateGroupEnterOffset = res.getDimensionPixelSize( R.dimen.recents_task_view_affiliate_group_enter_offset); + int launchedWhileDockingOffset = res.getDimensionPixelSize( + R.dimen.recents_task_view_launched_while_docking_offset); // Prepare each of the task views for their enter animation from front to back List<TaskView> taskViews = mStackView.getTaskViews(); @@ -141,7 +148,7 @@ public class TaskStackAnimationHelper { tv.setVisibility(View.INVISIBLE); } else if (launchState.launchedHasConfigurationChanged) { // Just load the views as-is - } else if (launchState.launchedFromApp) { + } else if (launchState.launchedFromApp && !launchState.launchedWhileDocking) { if (task.isLaunchTarget) { tv.onPrepareLaunchTargetForEnterAnimation(); } else if (currentTaskOccludesLaunchTarget) { @@ -159,6 +166,11 @@ public class TaskStackAnimationHelper { bounds.offset(0, offscreenYOffset); tv.setLeftTopRightBottom((int) bounds.left, (int) bounds.top, (int) bounds.right, (int) bounds.bottom); + } else if (launchState.launchedWhileDocking) { + RectF bounds = new RectF(mTmpTransform.rect); + bounds.offset(0, launchedWhileDockingOffset); + tv.setLeftTopRightBottom((int) bounds.left, (int) bounds.top, (int) bounds.right, + (int) bounds.bottom); } } } @@ -192,6 +204,7 @@ public class TaskStackAnimationHelper { int taskViewCount = taskViews.size(); for (int i = taskViewCount - 1; i >= 0; i--) { int taskIndexFromFront = taskViewCount - i - 1; + int taskIndexFromBack = i; final TaskView tv = taskViews.get(i); Task task = tv.getTask(); boolean currentTaskOccludesLaunchTarget = false; @@ -205,7 +218,7 @@ public class TaskStackAnimationHelper { stackLayout.getStackTransform(task, stackScroller.getStackScroll(), mTmpTransform, null); - if (launchState.launchedFromApp) { + if (launchState.launchedFromApp && !launchState.launchedWhileDocking) { if (task.isLaunchTarget) { tv.onStartLaunchTargetEnterAnimation(mTmpTransform, taskViewEnterFromAppDuration, mStackView.mScreenPinningEnabled, @@ -241,6 +254,16 @@ public class TaskStackAnimationHelper { .setListener(postAnimationTrigger.decrementOnAnimationEnd()); postAnimationTrigger.increment(); mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation); + } else if (launchState.launchedWhileDocking) { + // Animate the tasks up + AnimationProps taskAnimation = new AnimationProps() + .setDuration(AnimationProps.BOUNDS, (int) (ENTER_WHILE_DOCKING_DURATION + + (taskIndexFromBack * 2f * FRAME_OFFSET_MS))) + .setInterpolator(AnimationProps.BOUNDS, + ENTER_WHILE_DOCKING_INTERPOLATOR) + .setListener(postAnimationTrigger.decrementOnAnimationEnd()); + postAnimationTrigger.increment(); + mStackView.updateTaskViewToTransform(tv, mTmpTransform, taskAnimation); } } } diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java index a5ed32a081d4..6df5884328b3 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackLayoutAlgorithm.java @@ -222,9 +222,11 @@ public class TaskStackLayoutAlgorithm { private Range mUnfocusedRange; private Range mFocusedRange; - // The initial offset from the top of the stack + // The initial offset from the top and bottom of the stack @ViewDebug.ExportedProperty(category="recents") private int mInitialTopPeekHeight; + @ViewDebug.ExportedProperty(category="recents") + private int mInitialBottomPeekHeight; // The offset from the top when scrolled to the top of the stack @ViewDebug.ExportedProperty(category="recents") @@ -322,6 +324,8 @@ public class TaskStackLayoutAlgorithm { res.getFloat(R.integer.recents_layout_unfocused_range_max)); mFocusState = getInitialFocusState(); mInitialTopPeekHeight = res.getDimensionPixelSize(R.dimen.recents_initial_top_peek_size); + mInitialBottomPeekHeight = + res.getDimensionPixelSize(R.dimen.recents_initial_bottom_peek_size); mFocusedTopPeekHeight = res.getDimensionPixelSize(R.dimen.recents_layout_focused_top_peek_size); mFocusedBottomTaskPeekHeight = @@ -508,10 +512,13 @@ public class TaskStackLayoutAlgorithm { float initialPeekOffsetNormX = mUnfocusedCurveInterpolator.getX(initialPeekOffsetPct); float initialFocusedOffset = mStackRect.height() - mInitialTopPeekHeight - (mHeaderBarHeight * 1f) + 1; - float initialFocusedOffsetPct = (float) initialFocusedOffset / mStackRect.height(); + float initialFocusedOffsetPct = initialFocusedOffset / mStackRect.height(); float initialFocusedNormX = mUnfocusedCurveInterpolator.getX(initialFocusedOffsetPct); - int initialBottomOffset = mStackBottomOffset + mHeaderBarHeight; - float initialBottomOffsetPct = (float) initialBottomOffset / mStackRect.height(); + float initialBottomOffset = mStackBottomOffset + + (ssp.hasDockedTask() + ? mHeaderBarHeight + : mInitialBottomPeekHeight); + float initialBottomOffsetPct = initialBottomOffset / mStackRect.height(); float initialBottomNormX = mUnfocusedCurveInterpolator.getX(initialBottomOffsetPct); /* // If we want to offset the top card slightly 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 2601cd327982..6c410c3981c6 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java @@ -641,9 +641,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal // If we had a deferred animation, cancel that mDeferredTaskViewLayoutAnimation = null; - // Cancel all task view animations - cancelAllTaskViewAnimations(); - // Synchronize the current set of TaskViews bindVisibleTaskViews(mStackScroller.getStackScroll(), ignoreTasksSet, false /* ignoreTaskOverrides */); @@ -678,6 +675,10 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal */ public void updateTaskViewToTransform(TaskView taskView, TaskViewTransform transform, AnimationProps animation) { + if (taskView.isAnimatingTo(transform)) { + return; + } + taskView.cancelTransformAnimation(); taskView.updateViewPropertiesToTaskTransform(transform, animation, mRequestUpdateClippingListener); } @@ -812,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); } @@ -821,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/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java index 0bc7f8927a9c..7584a2e08f85 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java @@ -147,6 +147,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks AnimateableViewBounds mViewBounds; private AnimatorSet mTransformAnimation; + private final TaskViewTransform mTargetAnimationTransform = new TaskViewTransform(); private ArrayList<Animator> mTmpAnimators = new ArrayList<>(); View mContent; @@ -319,6 +320,7 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks // Create the animator mTransformAnimation = toAnimation.createAnimator(mTmpAnimators); mTransformAnimation.start(); + mTargetAnimationTransform.copyFrom(toTransform); } } @@ -338,6 +340,14 @@ public class TaskView extends FixedSizeFrameLayout implements Task.TaskCallbacks } /** + * @return whether we are animating towards {@param transform} + */ + boolean isAnimatingTo(TaskViewTransform transform) { + return mTransformAnimation != null && mTransformAnimation.isStarted() + && mTargetAnimationTransform.isSame(transform); + } + + /** * Cancels any current transform animations. */ public void cancelTransformAnimation() { diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java index 0d16a79735fd..dc76e61c0d1e 100644 --- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java +++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskViewTransform.java @@ -121,6 +121,18 @@ public class TaskViewTransform { } /** + * @return whether {@param other} is the same transform as this + */ + public boolean isSame(TaskViewTransform other) { + return translationZ == other.translationZ + && scale == other.scale + && other.alpha == alpha + && dimAlpha == other.dimAlpha + && visible == other.visible + && rect.equals(other.rect); + } + + /** * Resets the current transform. */ public void reset() { 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/shortcut/ShortcutKeyDispatcher.java b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java index 8f8683b4ea23..69dcabea28b8 100644 --- a/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java +++ b/packages/SystemUI/src/com/android/systemui/shortcut/ShortcutKeyDispatcher.java @@ -17,18 +17,31 @@ package com.android.systemui.shortcut; import android.accessibilityservice.AccessibilityServiceInfo; +import android.app.ActivityManager; +import android.app.ActivityManagerNative; +import android.app.IActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.pm.ServiceInfo; +import android.content.res.Configuration; import android.os.RemoteException; +import android.util.DisplayMetrics; import android.util.Log; import android.view.IWindowManager; import android.view.KeyEvent; +import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityManager; +import com.android.internal.logging.MetricsLogger; +import com.android.internal.logging.MetricsProto.MetricsEvent; +import com.android.internal.policy.DividerSnapAlgorithm; import com.android.settingslib.accessibility.AccessibilityUtils; import com.android.systemui.R; import com.android.systemui.SystemUI; +import com.android.systemui.recents.Recents; +import com.android.systemui.stackdivider.Divider; +import com.android.systemui.stackdivider.DividerView; +import com.android.systemui.statusbar.phone.NavigationBarGestureHelper; import java.util.List; import java.util.Set; @@ -42,28 +55,70 @@ public class ShortcutKeyDispatcher extends SystemUI private static final String TAG = "ShortcutKeyDispatcher"; private ShortcutKeyServiceProxy mShortcutKeyServiceProxy = new ShortcutKeyServiceProxy(this); - private IWindowManager windowManagerService = WindowManagerGlobal.getWindowManagerService(); + private IWindowManager mWindowManagerService = WindowManagerGlobal.getWindowManagerService(); + private IActivityManager mActivityManager = ActivityManagerNative.getDefault(); protected final long META_MASK = ((long) KeyEvent.META_META_ON) << Integer.SIZE; protected final long ALT_MASK = ((long) KeyEvent.META_ALT_ON) << Integer.SIZE; protected final long CTRL_MASK = ((long) KeyEvent.META_CTRL_ON) << Integer.SIZE; protected final long SHIFT_MASK = ((long) KeyEvent.META_SHIFT_ON) << Integer.SIZE; + protected final long SC_DOCK_LEFT = META_MASK | KeyEvent.KEYCODE_LEFT_BRACKET; + protected final long SC_DOCK_RIGHT = META_MASK | KeyEvent.KEYCODE_RIGHT_BRACKET; + /** * Registers a shortcut key to window manager. * @param shortcutCode packed representation of shortcut key code and meta information */ public void registerShortcutKey(long shortcutCode) { try { - windowManagerService.registerShortcutKey(shortcutCode, mShortcutKeyServiceProxy); + mWindowManagerService.registerShortcutKey(shortcutCode, mShortcutKeyServiceProxy); } catch (RemoteException e) { // Do nothing } } @Override - public void onShortcutKeyPressed(long shortcutCode) {} + public void onShortcutKeyPressed(long shortcutCode) { + int orientation = mContext.getResources().getConfiguration().orientation; + if ((shortcutCode == SC_DOCK_LEFT || shortcutCode == SC_DOCK_RIGHT) + && orientation == Configuration.ORIENTATION_LANDSCAPE) { + handleDockKey(shortcutCode); + } + } @Override - public void start() {} + public void start() { + registerShortcutKey(SC_DOCK_LEFT); + registerShortcutKey(SC_DOCK_RIGHT); + } + + private void handleDockKey(long shortcutCode) { + try { + int dockSide = mWindowManagerService.getDockedStackSide(); + if (dockSide == WindowManager.DOCKED_INVALID) { + // If there is no window docked, we dock the top-most window. + Recents recents = getComponent(Recents.class); + int dockMode = (shortcutCode == SC_DOCK_LEFT) + ? ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT + : ActivityManager.DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT; + recents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE, dockMode, null); + MetricsLogger.action(mContext, MetricsEvent.WINDOW_DOCK_SHORTCUTS); + } else { + // If there is already a docked window, we respond by resizing the docking pane. + DividerView dividerView = getComponent(Divider.class).getView(); + DividerSnapAlgorithm snapAlgorithm = dividerView.getSnapAlgorithm(); + int dividerPosition = dividerView.getCurrentPosition(); + DividerSnapAlgorithm.SnapTarget currentTarget = + snapAlgorithm.calculateNonDismissingSnapTarget(dividerPosition); + int increment = (shortcutCode == SC_DOCK_LEFT) ? -1 : 1; + DividerSnapAlgorithm.SnapTarget target = snapAlgorithm.cycleNonDismissTarget( + currentTarget, increment); + dividerView.startDragging(true /* animate */, false /* touching */); + dividerView.stopDragging(target.position, 0f, true /* avoidDismissStart */); + } + } catch (RemoteException e) { + Log.e(TAG, "handleDockKey() failed."); + } + } } diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java index da5cbe7a9003..e0156660efbb 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/DividerView.java @@ -16,6 +16,9 @@ package com.android.systemui.stackdivider; +import static android.view.PointerIcon.STYLE_HORIZONTAL_DOUBLE_ARROW; +import static android.view.PointerIcon.STYLE_VERTICAL_DOUBLE_ARROW; + import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ValueAnimator; @@ -31,6 +34,9 @@ import android.os.Bundle; import android.util.AttributeSet; import android.view.Display; import android.view.DisplayInfo; +import android.view.GestureDetector; +import android.view.GestureDetector.OnDoubleTapListener; +import android.view.GestureDetector.SimpleOnGestureListener; import android.view.MotionEvent; import android.view.PointerIcon; import android.view.VelocityTracker; @@ -39,6 +45,7 @@ import android.view.View.OnTouchListener; import android.view.ViewConfiguration; import android.view.ViewTreeObserver.InternalInsetsInfo; import android.view.ViewTreeObserver.OnComputeInternalInsetsListener; +import android.view.ViewTreeObserver.OnGlobalLayoutListener; import android.view.WindowInsets; import android.view.WindowManager; import android.view.accessibility.AccessibilityNodeInfo; @@ -52,17 +59,16 @@ import com.android.internal.policy.DividerSnapAlgorithm.SnapTarget; import com.android.internal.policy.DockedDividerUtils; import com.android.systemui.Interpolators; import com.android.systemui.R; +import com.android.systemui.recents.Recents; import com.android.systemui.recents.events.EventBus; -import com.android.systemui.recents.events.activity.DockingTopTaskEvent; +import com.android.systemui.recents.events.activity.DockedTopTaskEvent; import com.android.systemui.recents.events.activity.RecentsActivityStartingEvent; import com.android.systemui.recents.events.activity.UndockingTaskEvent; import com.android.systemui.recents.events.ui.RecentsDrawnEvent; +import com.android.systemui.recents.misc.SystemServicesProxy; import com.android.systemui.statusbar.FlingAnimationUtils; import com.android.systemui.statusbar.phone.NavigationBarGestureHelper; -import static android.view.PointerIcon.STYLE_HORIZONTAL_DOUBLE_ARROW; -import static android.view.PointerIcon.STYLE_VERTICAL_DOUBLE_ARROW; - /** * Docked stack divider. */ @@ -123,6 +129,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, private final Rect mDockedInsetRect = new Rect(); private final Rect mOtherInsetRect = new Rect(); private final Rect mLastResizeRect = new Rect(); + private final Rect mDisplayRect = new Rect(); private final WindowManagerProxy mWindowManagerProxy = WindowManagerProxy.getInstance(); private DividerWindowManager mWindowManager; private VelocityTracker mVelocityTracker; @@ -133,7 +140,9 @@ public class DividerView extends FrameLayout implements OnTouchListener, private boolean mAnimateAfterRecentsDrawn; private boolean mGrowAfterRecentsDrawn; private boolean mGrowRecents; - private Animator mCurrentAnimator; + private ValueAnimator mCurrentAnimator; + private boolean mEntranceAnimationRunning; + private GestureDetector mGestureDetector; private final AccessibilityDelegate mHandleDelegate = new AccessibilityDelegate() { @Override @@ -211,12 +220,35 @@ public class DividerView extends FrameLayout implements OnTouchListener, landscape ? STYLE_HORIZONTAL_DOUBLE_ARROW : STYLE_VERTICAL_DOUBLE_ARROW)); getViewTreeObserver().addOnComputeInternalInsetsListener(this); mHandle.setAccessibilityDelegate(mHandleDelegate); + mGestureDetector = new GestureDetector(mContext, new SimpleOnGestureListener() { + @Override + public boolean onSingleTapUp(MotionEvent e) { + updateDockSide(); + SystemServicesProxy ssp = Recents.getSystemServices(); + if (mDockSide != WindowManager.DOCKED_INVALID + && !ssp.isRecentsTopMost(ssp.getTopMostTask(), null /* isTopHome */)) { + mWindowManagerProxy.swapTasks(); + return true; + } + return false; + } + }); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); EventBus.getDefault().register(this); + getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { + + @Override + public void onGlobalLayout() { + getViewTreeObserver().removeOnGlobalLayoutListener(this); + mWindowManagerProxy.setTouchRegion(new Rect(mHandle.getLeft(), mHandle.getTop(), + mHandle.getLeft() + mHandle.getWidth(), + mHandle.getTop() + mHandle.getHeight())); + } + }); } @Override @@ -318,6 +350,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, @Override public boolean onTouch(View v, MotionEvent event) { convertToScreenCoordinates(event); + mGestureDetector.onTouchEvent(event); final int action = event.getAction() & MotionEvent.ACTION_MASK; switch (action) { case MotionEvent.ACTION_DOWN: @@ -411,6 +444,7 @@ public class DividerView extends FrameLayout implements OnTouchListener, mWindowManagerProxy.setResizing(false); mDockSide = WindowManager.DOCKED_INVALID; mCurrentAnimator = null; + mEntranceAnimationRunning = false; } }); mCurrentAnimator = anim; @@ -594,7 +628,18 @@ public class DividerView extends FrameLayout implements OnTouchListener, } mLastResizeRect.set(mDockedRect); - if (taskPosition != TASK_POSITION_SAME) { + if (mEntranceAnimationRunning && taskPosition != TASK_POSITION_SAME) { + if (mCurrentAnimator != null) { + calculateBoundsForPosition(taskPosition, mDockSide, mDockedTaskRect); + } else { + calculateBoundsForPosition(isHorizontalDivision() ? mDisplayHeight : mDisplayWidth, + mDockSide, mDockedTaskRect); + } + calculateBoundsForPosition(taskPosition, DockedDividerUtils.invertDockSide(mDockSide), + mOtherTaskRect); + mWindowManagerProxy.resizeDockedStack(mDockedRect, mDockedTaskRect, null, + mOtherTaskRect, null); + } else if (taskPosition != TASK_POSITION_SAME) { calculateBoundsForPosition(position, DockedDividerUtils.invertDockSide(mDockSide), mOtherRect); int dockSideInverted = DockedDividerUtils.invertDockSide(mDockSide); @@ -610,16 +655,17 @@ public class DividerView extends FrameLayout implements OnTouchListener, calculateBoundsForPosition(taskPositionDocked, mDockSide, mDockedTaskRect); calculateBoundsForPosition(taskPositionOther, dockSideInverted, mOtherTaskRect); + mDisplayRect.set(0, 0, mDisplayWidth, mDisplayHeight); alignTopLeft(mDockedRect, mDockedTaskRect); alignTopLeft(mOtherRect, mOtherTaskRect); mDockedInsetRect.set(mDockedTaskRect); mOtherInsetRect.set(mOtherTaskRect); if (dockSideTopLeft(mDockSide)) { - alignTopLeft(mDockedRect, mDockedInsetRect); - alignBottomRight(mOtherRect, mOtherInsetRect); + alignTopLeft(mDisplayRect, mDockedInsetRect); + alignBottomRight(mDisplayRect, mOtherInsetRect); } else { - alignBottomRight(mDockedRect, mDockedInsetRect); - alignTopLeft(mOtherRect, mOtherInsetRect); + alignBottomRight(mDisplayRect, mDockedInsetRect); + alignTopLeft(mDisplayRect, mOtherInsetRect); } applyDismissingParallax(mDockedTaskRect, mDockSide, taskSnapTarget, position, taskPositionDocked); @@ -638,6 +684,9 @@ public class DividerView extends FrameLayout implements OnTouchListener, } private float getDimFraction(int position, SnapTarget dismissTarget) { + if (mEntranceAnimationRunning) { + return 0f; + } float fraction = mSnapAlgorithm.calculateDismissingFraction(position); fraction = Math.max(0, Math.min(fraction, 1f)); fraction = DIM_INTERPOLATOR.getInterpolation(fraction); @@ -839,12 +888,18 @@ public class DividerView extends FrameLayout implements OnTouchListener, } } - public final void onBusEvent(DockingTopTaskEvent dockingEvent) { - if (dockingEvent.dragMode == NavigationBarGestureHelper.DRAG_MODE_NONE) { + public final void onBusEvent(DockedTopTaskEvent event) { + if (event.dragMode == NavigationBarGestureHelper.DRAG_MODE_NONE) { mGrowAfterRecentsDrawn = false; mAnimateAfterRecentsDrawn = true; startDragging(false /* animate */, false /* touching */); } + updateDockSide(); + int position = DockedDividerUtils.calculatePositionForBounds(event.initialRect, + mDockSide, mDividerSize); + mEntranceAnimationRunning = true; + resizeStack(position, mSnapAlgorithm.getMiddleTarget().position, + mSnapAlgorithm.getMiddleTarget()); } public final void onBusEvent(RecentsDrawnEvent drawnEvent) { diff --git a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java index 15bcaf834f72..e312fa2028a5 100644 --- a/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java +++ b/packages/SystemUI/src/com/android/systemui/stackdivider/WindowManagerProxy.java @@ -16,6 +16,9 @@ package com.android.systemui.stackdivider; +import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; +import static android.view.WindowManager.DOCKED_INVALID; + import android.app.ActivityManagerNative; import android.graphics.Rect; import android.os.RemoteException; @@ -27,9 +30,6 @@ import com.android.internal.annotations.GuardedBy; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; -import static android.view.WindowManager.DOCKED_INVALID; - /** * Proxy to simplify calls into window manager/activity manager */ @@ -39,7 +39,7 @@ public class WindowManagerProxy { private static final WindowManagerProxy sInstance = new WindowManagerProxy(); - @GuardedBy("mResizeRect") + @GuardedBy("mDockedRect") private final Rect mDockedRect = new Rect(); private final Rect mTempDockedTaskRect = new Rect(); private final Rect mTempDockedInsetRect = new Rect(); @@ -52,6 +52,9 @@ public class WindowManagerProxy { private final Rect mTmpRect4 = new Rect(); private final Rect mTmpRect5 = new Rect(); + @GuardedBy("mDockedRect") + private final Rect mTouchableRegion = new Rect(); + private boolean mDimLayerVisible; private int mDimLayerTargetStack; private float mDimLayerAlpha; @@ -117,6 +120,32 @@ public class WindowManagerProxy { } }; + private final Runnable mSwapRunnable = new Runnable() { + @Override + public void run() { + try { + ActivityManagerNative.getDefault().swapDockedAndFullscreenStack(); + } catch (RemoteException e) { + Log.w(TAG, "Failed to resize stack: " + e); + } + } + }; + + private final Runnable mSetTouchableRegionRunnable = new Runnable() { + @Override + public void run() { + try { + synchronized (mDockedRect) { + mTmpRect1.set(mTouchableRegion); + } + WindowManagerGlobal.getWindowManagerService().setDockedStackDividerTouchRegion( + mTmpRect1); + } catch (RemoteException e) { + Log.w(TAG, "Failed to set touchable region: " + e); + } + } + }; + private WindowManagerProxy() { } @@ -188,4 +217,15 @@ public class WindowManagerProxy { mDimLayerAlpha = alpha; mExecutor.execute(mDimLayerRunnable); } + + public void swapTasks() { + mExecutor.execute(mSwapRunnable); + } + + public void setTouchRegion(Rect region) { + synchronized (mDockedRect) { + mTouchableRegion.set(region); + } + mExecutor.execute(mSetTouchableRegionRunnable); + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java index 5652c7da7ebb..71f74cdcbdeb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java @@ -148,7 +148,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView public void onAnimationEnd(Animator animation) { super.onAnimationEnd(animation); mFadeInFromDarkAnimator = null; - updateOutlineAlpha(); + updateBackground(); } }; private ValueAnimator.AnimatorUpdateListener mUpdateOutlineListener @@ -340,9 +340,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView animator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - if (mDimmed) { - mBackgroundNormal.setVisibility(View.INVISIBLE); - } + updateBackground(); } }); animator.start(); @@ -371,14 +369,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView */ public void makeInactive(boolean animate) { if (mActivated) { + mActivated = false; if (mDimmed) { if (animate) { startActivateAnimation(true /* reverse */); } else { - mBackgroundNormal.setVisibility(View.INVISIBLE); + updateBackground(); } } - mActivated = false; } if (mOnActivatedListener != null) { mOnActivatedListener.onActivationReset(this); @@ -408,20 +406,9 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView return; } mDark = dark; + updateBackground(); if (!dark && fade && !shouldHideBackground()) { - if (mActivated) { - mBackgroundDimmed.setVisibility(View.VISIBLE); - mBackgroundNormal.setVisibility(View.VISIBLE); - } else if (mDimmed) { - mBackgroundDimmed.setVisibility(View.VISIBLE); - mBackgroundNormal.setVisibility(View.INVISIBLE); - } else { - mBackgroundDimmed.setVisibility(View.INVISIBLE); - mBackgroundNormal.setVisibility(View.VISIBLE); - } fadeInFromDark(delay); - } else { - updateBackground(); } updateOutlineAlpha(); } @@ -528,6 +515,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private void fadeInFromDark(long delay) { final View background = mDimmed ? mBackgroundDimmed : mBackgroundNormal; background.setAlpha(0f); + mBackgroundVisibilityUpdater.onAnimationUpdate(null); background.setPivotX(mBackgroundDimmed.getWidth() / 2f); background.setPivotY(getActualHeight() / 2f); background.setScaleX(DARK_EXIT_SCALE_START); @@ -565,6 +553,10 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView private void fadeDimmedBackground() { mBackgroundDimmed.animate().cancel(); mBackgroundNormal.animate().cancel(); + if (mActivated) { + updateBackground(); + return; + } if (!shouldHideBackground()) { if (mDimmed) { mBackgroundDimmed.setVisibility(View.VISIBLE); @@ -594,11 +586,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mBackgroundAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { - if (mDimmed) { - mBackgroundNormal.setVisibility(View.INVISIBLE); - } else { - mBackgroundDimmed.setVisibility(View.INVISIBLE); - } + updateBackground(); mBackgroundAnimator = null; } }); @@ -613,12 +601,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView mBackgroundNormal.setVisibility(View.INVISIBLE); } else if (mDimmed) { mBackgroundDimmed.setVisibility(View.VISIBLE); - mBackgroundNormal.setVisibility(View.INVISIBLE); + mBackgroundNormal.setVisibility(mActivated ? View.VISIBLE : View.INVISIBLE); } else { mBackgroundDimmed.setVisibility(View.INVISIBLE); mBackgroundNormal.setVisibility(View.VISIBLE); mBackgroundNormal.setAlpha(1f); removeCallbacks(mTapTimeoutRunnable); + // make in inactive to avoid it sticking around active + makeInactive(false /* animate */); } setNormalBackgroundVisibilityAmount( mBackgroundNormal.getVisibility() == View.VISIBLE ? 1.0f : 0.0f); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java index c2e1f7d79df0..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() { @@ -1349,7 +1353,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView { float y = event.getY(); NotificationHeaderView header = getVisibleNotificationHeader(); if (header != null) { - return header.isInTouchRect(x, y); + return header.isInTouchRect(x - getTranslation(), y); } return super.disallowSingleClick(event); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java index c0e434046139..91418ad312bf 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableView.java @@ -43,6 +43,7 @@ public abstract class ExpandableView extends FrameLayout { private boolean mWillBeGone; private int mMinClipTopAmount = 0; private boolean mClipToActualHeight = true; + private boolean mChangingPosition = false; public ExpandableView(Context context, AttributeSet attrs) { super(context, attrs); @@ -407,6 +408,14 @@ public abstract class ExpandableView extends FrameLayout { return 0; } + public void setChangingPosition(boolean changingPosition) { + mChangingPosition = changingPosition; + } + + public boolean isChangingPosition() { + return mChangingPosition; + } + /** * A listener notifying when {@link #getActualHeight} changes. */ 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/car/CarNavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java index 8a93c5b0d1c2..bb43899c44e1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/car/CarNavigationBarController.java @@ -71,7 +71,6 @@ class CarNavigationBarController { private List<CarNavigationButton> mNavButtons = new ArrayList<CarNavigationButton>(); private int mCurrentFacetIndex; - private String mCurrentPackageName; private SparseBooleanArray mFacetHasMultipleAppsCache = new SparseBooleanArray(); public CarNavigationBarController(Context context, @@ -84,7 +83,6 @@ class CarNavigationBarController { } public void taskChanged(String packageName) { - mCurrentPackageName = packageName; // If the package name belongs to a filter, then highlight appropriate button in // the navigation bar. if (mFacetPackageMap.containsKey(packageName)) { @@ -298,12 +296,6 @@ class CarNavigationBarController { return; } - // Don't launch the lens picker if it's already running and the - // user clicks the same facet - if (packageName.equals(mCurrentPackageName) && index == mCurrentFacetIndex) { - return; - } - intent.putExtra(EXTRA_FACET_CATEGORIES, mFacetCategories.get(index)); intent.putExtra(EXTRA_FACET_PACKAGES, mFacetPackages.get(index)); // The facet is identified by the index in which it was added to the nav bar. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java index d3393b330355..20dbc4a31b8a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/TextViewTransformState.java @@ -46,7 +46,8 @@ public class TextViewTransformState extends TransformState { if(TextUtils.equals(otherTvs.mText.getText(), mText.getText())) { int ownEllipsized = getEllipsisCount(); int otherEllipsized = otherTvs.getEllipsisCount(); - return ownEllipsized == otherEllipsized; + return ownEllipsized == otherEllipsized + && mText.getHeight() == otherTvs.mText.getHeight(); } } return super.sameAs(otherState); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java index 5b4a3f0039c9..65e797379fef 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java @@ -105,7 +105,6 @@ public class LockscreenWallpaper extends IWallpaperManagerCallback.Stub implemen if (mSelectedUser != null && mSelectedUser.getIdentifier() != mCurrentUserId) { // When selected user is different from the current user, show the selected // user's static wallpaper. - mWallpaperManager.forgetLoadedWallpaper(); mCache = mWallpaperManager.getBitmapAsUser(mSelectedUser.getIdentifier()); } else { // When there is no selected user, or it's same as the current user, show the diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java index d50e67aaefbe..e5e3cafe9395 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -277,11 +277,12 @@ public class NotificationPanelView extends PanelView implements public void updateResources() { int panelWidth = getResources().getDimensionPixelSize(R.dimen.notification_panel_width); int panelGravity = getResources().getInteger(R.integer.notification_panel_layout_gravity); - FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mQsContainer.getLayoutParams(); + FrameLayout.LayoutParams lp = + (FrameLayout.LayoutParams) mQsDensityContainer.getLayoutParams(); if (lp.width != panelWidth) { lp.width = panelWidth; lp.gravity = panelGravity; - mQsContainer.setLayoutParams(lp); + mQsDensityContainer.setLayoutParams(lp); mQsContainer.post(mUpdateHeader); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 6ad7aadc0972..906bd0ff4b57 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -1012,7 +1012,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } - private void clearAllNotifications() { + public void clearAllNotifications() { // animate-swipe all dismissable notifications, then animate the shade closed int numChildren = mStackScroller.getChildCount(); @@ -1149,9 +1149,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, @Override public boolean onLongClick(View v) { - if (mRecents == null) { + if (mRecents == null || !ActivityManager.supportsMultiWindow()) { return false; } + boolean initiallyDocked = WindowManagerProxy.getInstance().getDockSide() == WindowManager.DOCKED_INVALID; boolean dockedAtEnd = toggleSplitScreenMode(); @@ -1172,13 +1173,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } int dockSide = WindowManagerProxy.getInstance().getDockSide(); if (dockSide == WindowManager.DOCKED_INVALID) { - Point realSize = new Point(); - mContext.getSystemService(DisplayManager.class).getDisplay(Display.DEFAULT_DISPLAY) - .getRealSize(realSize); - Rect initialBounds= new Rect(0, 0, realSize.x, realSize.y); return mRecents.dockTopTask(NavigationBarGestureHelper.DRAG_MODE_NONE, - ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, - initialBounds); + ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT, null); } else { EventBus.getDefault().send(new UndockingTaskEvent()); return false; @@ -1951,6 +1947,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, // We are unlocking directly - no animation! mBackdrop.setVisibility(View.GONE); + mBackdropBack.setImageDrawable(null); } else { mBackdrop.animate() // Never let the alpha become zero - otherwise the RenderNode @@ -1966,7 +1963,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void run() { mBackdrop.setVisibility(View.GONE); mBackdropFront.animate().cancel(); - mBackdropBack.animate().cancel(); + mBackdropBack.setImageDrawable(null); mHandler.post(mHideBackdropFront); } }); @@ -3141,7 +3138,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } }; - private void resetUserExpandedStates() { + public void resetUserExpandedStates() { ArrayList<Entry> activeNotifications = mNotificationData.getActiveNotifications(); final int notificationCount = activeNotifications.size(); for (int i = 0; i < notificationCount; i++) { @@ -4494,7 +4491,20 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } private void handlePulseWhileDozing(@NonNull PulseCallback callback, int reason) { - mDozeScrimController.pulse(callback, reason); + mDozeScrimController.pulse(new PulseCallback() { + + @Override + public void onPulseStarted() { + callback.onPulseStarted(); + mStackScroller.setPulsing(true); + } + + @Override + public void onPulseFinished() { + callback.onPulseFinished(); + mStackScroller.setPulsing(false); + } + }, reason); } private void handleStopDozing() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java index fcaf050549f2..77ece9322583 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowManager.java @@ -173,7 +173,7 @@ public class StatusBarWindowManager implements RemoteInputController.Callback { private void applyInputFeatures(State state) { if (state.isKeyguardShowingAndNotOccluded() && state.statusBarState == StatusBarState.KEYGUARD - && !state.qsExpanded) { + && !state.qsExpanded && !state.forceUserActivity) { mLpChanged.inputFeatures |= WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY; } else { @@ -265,6 +265,11 @@ public class StatusBarWindowManager implements RemoteInputController.Callback { apply(mCurrentState); } + public void setForceUserActivity(boolean forceUserActivity) { + mCurrentState.forceUserActivity = forceUserActivity; + apply(mCurrentState); + } + public void setHeadsUpShowing(boolean showing) { mCurrentState.headsUpShowing = showing; apply(mCurrentState); @@ -332,6 +337,7 @@ public class StatusBarWindowManager implements RemoteInputController.Callback { boolean forceStatusBarVisible; boolean forceCollapsed; boolean forceDozeBrightness; + boolean forceUserActivity; /** * The {@link BaseStatusBar} state from the status bar. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java index c6659d1e7da2..29b0f4b75876 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java @@ -155,8 +155,21 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + if (mEntry.row.isChangingPosition()) { + if (getVisibility() == VISIBLE && mEditText.isFocusable()) { + mEditText.requestFocus(); + } + } + } + + @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); + if (mEntry.row.isChangingPosition()) { + return; + } mController.removeRemoteInput(mEntry); } @@ -229,6 +242,9 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } private void defocusIfNeeded() { + if (mDefocusListener.mEntry.row.isChangingPosition()) { + return; + } if (isFocusable() && isEnabled()) { setInnerFocusable(false); if (mDefocusListener != null) { @@ -248,9 +264,11 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene } @Override - protected void onFocusLost() { - super.onFocusLost(); - defocusIfNeeded(); + protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { + super.onFocusChanged(focused, direction, previouslyFocusedRect); + if (!focused) { + defocusIfNeeded(); + } } @Override 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/NotificationChildrenContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java index 9d50ab44ffa6..676ff2ebc258 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationChildrenContainer.java @@ -96,7 +96,8 @@ public class NotificationChildrenContainer extends ViewGroup { com.android.internal.R.dimen.notification_content_margin_top); mNotificatonTopPadding = getResources().getDimensionPixelSize( R.dimen.notification_children_container_top_padding); - mCollapsedBottompadding = 11.5f * getResources().getDisplayMetrics().density; + mCollapsedBottompadding = getResources().getDimensionPixelSize( + com.android.internal.R.dimen.notification_content_margin_bottom); } @Override 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 824b8b70eede..d9b78a2f09fc 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java @@ -324,6 +324,7 @@ public class NotificationStackScrollLayout extends ViewGroup } }; private PorterDuffXfermode mSrcMode = new PorterDuffXfermode(PorterDuff.Mode.SRC); + private boolean mPulsing; public NotificationStackScrollLayout(Context context) { this(context, null); @@ -371,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) { @@ -716,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); } } } @@ -2194,7 +2204,7 @@ public class NotificationStackScrollLayout extends ViewGroup } private void updateNotificationAnimationStates() { - boolean running = mAnimationsEnabled; + boolean running = mAnimationsEnabled || mPulsing; int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View child = getChildAt(i); @@ -2204,7 +2214,8 @@ public class NotificationStackScrollLayout extends ViewGroup } private void updateAnimationState(View child) { - updateAnimationState(mAnimationsEnabled && (mIsExpanded || isPinnedHeadsUp(child)), child); + updateAnimationState((mAnimationsEnabled || mPulsing) + && (mIsExpanded || isPinnedHeadsUp(child)), child); } @@ -2250,8 +2261,10 @@ public class NotificationStackScrollLayout extends ViewGroup int currentIndex = indexOfChild(child); if (child != null && child.getParent() == this && currentIndex != newIndex) { mChangePositionInProgress = true; + ((ExpandableView)child).setChangingPosition(true); removeView(child); addView(child, newIndex); + ((ExpandableView)child).setChangingPosition(false); mChangePositionInProgress = false; if (mIsExpanded && mAnimationsEnabled && child.getVisibility() != View.GONE) { mChildrenChangingPositions.add(child); @@ -2652,6 +2665,7 @@ public class NotificationStackScrollLayout extends ViewGroup mIsExpansionChanging = false; if (!mIsExpanded) { mOwnScrollY = 0; + mPhoneStatusBar.resetUserExpandedStates(); // lets make sure nothing is in the overlay anymore getOverlay().clear(); @@ -2725,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; @@ -3322,6 +3336,11 @@ public class NotificationStackScrollLayout extends ViewGroup return mIsExpanded; } + public void setPulsing(boolean pulsing) { + mPulsing = pulsing; + updateNotificationAnimationStates(); + } + /** * A listener that is notified when some child locations might have changed. */ @@ -3369,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); @@ -3390,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; @@ -3401,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(); @@ -3424,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 @@ -3489,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. */ @@ -3500,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); } @@ -3511,7 +3630,6 @@ public class NotificationStackScrollLayout extends ViewGroup mCurrIconRow.cancelFadeAnimator(); } mHandler.removeCallbacks(mCheckForDrag); - mCheckForDrag = null; } private final class CheckForDrag implements Runnable { @@ -3521,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; } } } @@ -3541,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/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java index ea15b8164214..ff7ea276aa91 100644 --- a/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java +++ b/packages/SystemUI/src/com/android/systemui/tv/pip/PipManager.java @@ -68,6 +68,9 @@ public class PipManager { public static final int SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_MENU_ACTIVITY_FINISH = 0x1; public static final int SUSPEND_PIP_RESIZE_REASON_WAITING_FOR_OVERLAY_ACTIVITY_FINISH = 0x2; + + private static final int CLOSE_PIP_WHEN_MEDIA_SESSION_GONE_TIMEOUT_MS = 3000; + private int mSuspendPipResizingReason; private static final float SCALE_FACTOR = 1.1f; @@ -172,6 +175,12 @@ public class PipManager { resizePinnedStack(mState); } }; + private final Runnable mClosePipRunnable = new Runnable() { + @Override + public void run() { + closePip(); + } + }; private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override @@ -283,6 +292,7 @@ public class PipManager { for (int i = mListeners.size() - 1; i >= 0; --i) { mListeners.get(i).onPipActivityClosed(); } + mHandler.removeCallbacks(mClosePipRunnable); } /** @@ -545,6 +555,12 @@ public class PipManager { for (int i = mListeners.size() - 1; i >= 0; i--) { mListeners.get(i).onMediaControllerChanged(); } + if (mPipMediaController == null) { + mHandler.postDelayed(mClosePipRunnable, + CLOSE_PIP_WHEN_MEDIA_SESSION_GONE_TIMEOUT_MS); + } else { + mHandler.removeCallbacks(mClosePipRunnable); + } } } diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index 65654a8d4270..d36a1d702701 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -1956,6 +1956,46 @@ message MetricsEvent { // Logs that the user has edited the enabled VR listeners. VR_MANAGE_LISTENERS = 334; + // Settings -> Accessibility -> Click after pointer stops moving + ACCESSIBILITY_TOGGLE_AUTOCLICK = 335; + // Settings -> Sound + SOUND = 336; + // Settings -> Notifications -> Gear + CONFIGURE_NOTIFICATION = 337; + // Settings -> Wi-Fi -> Gear + CONFIGURE_WIFI = 338; + // Settings -> Display -> Display size + DISPLAY_SCREEN_ZOOM = 339; + // Settings -> Display -> Font size + ACCESSIBILITY_FONT_SIZE = 340; + // Settings -> Data usage -> Cellular/Wi-Fi data usage + DATA_USAGE_LIST = 341; + // Settings -> Data usage -> Billing cycle or DATA_USAGE_LIST -> Gear + BILLING_CYCLE = 342; + // DATA_USAGE_LIST -> Any item or App info -> Data usage + APP_DATA_USAGE = 343; + // Settings -> Language & input -> Language + USER_LOCALE_LIST = 344; + // Settings -> Language & input -> Virtual keyboard + VIRTUAL_KEYBOARDS = 345; + // Settings -> Language & input -> Physical keyboard + PHYSICAL_KEYBOARDS = 346; + // Settings -> Language & input -> Virtual keyboard -> Add a virtual keyboard + ENABLE_VIRTUAL_KEYBOARDS = 347; + // Settings -> Data usage -> Data Saver + DATA_SAVER_SUMMARY = 348; + // Settings -> Data usage -> Data Saver -> Unrestricted data access + DATA_USAGE_UNRESTRICTED_ACCESS = 349; + + // Used for generic logging of Settings Preference Persistence, should not be used + // outside SharedPreferencesLogger. + ACTION_GENERIC_PACKAGE = 350; + // Settings -> Apps -> Gear -> Special access + SPECIAL_ACCESS = 351; + + // Logs that the user docks window via shortcut key. + WINDOW_DOCK_SHORTCUTS = 352; + // Add new aosp constants above this line. // END OF AOSP CONSTANTS } diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java index ad70853f13ba..3ac81f65797f 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityGestureDetector.java @@ -37,7 +37,8 @@ import java.util.ArrayList; /** * This class handles gesture detection for the Touch Explorer. It collects - * touch events, and sends events to mListener as gestures are recognized. + * touch events and determines when they match a gesture, as well as when they + * won't match a gesture. These state changes are then surfaced to mListener. */ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListener { @@ -46,12 +47,66 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen // Tag for logging received events. private static final String LOG_TAG = "AccessibilityGestureDetector"; + /** + * Listener functions are called as a result of onMoveEvent(). The current + * MotionEvent in the context of these functions is the event passed into + * onMotionEvent. + */ public interface Listener { - public void onDoubleTapAndHold(MotionEvent event, int policyFlags); - public boolean onDoubleTap(MotionEvent event, int policyFlags); - public boolean onGestureCompleted(int gestureId); - public void onGestureStarted(); - public void onGestureCancelled(MotionEvent event, int policyFlags); + /** + * Called when the user has performed a double tap and then held down + * the second tap. + * + * @param event The most recent MotionEvent received. + * @param policyFlags The policy flags of the most recent event. + */ + 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. + * + * @param event The most recent MotionEvent received. + * @param policyFlags The policy flags of the most recent event. + * + * @return true if the event is consumed, else false + */ + boolean onDoubleTap(MotionEvent event, int policyFlags); + + /** + * Called when the system has decided the event stream is a gesture. + * + * @return true if the event is consumed, else false + */ + boolean onGestureStarted(); + + /** + * Called when an event stream is recognized as a gesture. + * + * @param gestureId ID of the gesture that was recognized. + * + * @return true if the event is consumed, else false + */ + boolean onGestureCompleted(int gestureId); + + /** + * Called when the system has decided an event stream doesn't match any + * known gesture. + * + * @param event The most recent MotionEvent received. + * @param policyFlags The policy flags of the most recent event. + * + * @return true if the event is consumed, else false + */ + public boolean onGestureCancelled(MotionEvent event, int policyFlags); } private final Listener mListener; @@ -121,9 +176,9 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen // movement when gesturing, and touch exploring. Based on user testing, // all gestures started with the initial movement taking less than 100ms. // When touch exploring, the first movement almost always takes longer than - // 200ms. From this data, 150ms seems the best value to decide what + // 200ms. From this data, 200ms seems the best value to decide what // kind of interaction it is. - private static final long CANCEL_ON_PAUSE_THRESHOLD_NOT_STARTED_MS = 150; + private static final long CANCEL_ON_PAUSE_THRESHOLD_NOT_STARTED_MS = 200; // Time threshold used to determine if a gesture should be cancelled. If // the finger pauses for longer than this delay, the ongoing gesture is @@ -145,6 +200,18 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen context.getResources().getDisplayMetrics()) * GESTURE_CONFIRM_MM; } + /** + * Handle a motion event. If an action is completed, the appropriate + * callback on mListener is called, and the return value of the callback is + * passed to the caller. + * + * @param event The raw motion event. It's important that this be the raw + * event, before any transformations have been applied, so that measurements + * can be made in physical units. + * @param policyFlags Policy flags for the event. + * + * @return true if the event is consumed, else false + */ public boolean onMotionEvent(MotionEvent event, int policyFlags) { final float x = event.getX(); final float y = event.getY(); @@ -183,7 +250,7 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen // the event. if (!mGestureStarted) { mGestureStarted = true; - mListener.onGestureStarted(); + return mListener.onGestureStarted(); } } else { final long timeDelta = time - mBaseTime; @@ -195,8 +262,7 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen // timeout, cancel gesture detection. if (timeDelta > threshold) { cancelGesture(); - mListener.onGestureCancelled(event, policyFlags); - return false; + return mListener.onGestureCancelled(event, policyFlags); } } @@ -211,16 +277,13 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen break; case MotionEvent.ACTION_UP: - if (maybeFinishDoubleTap(event, policyFlags)) { - return true; + if (mDoubleTapDetected) { + return finishDoubleTap(event, policyFlags); } if (mGestureStarted) { mStrokeBuffer.add(new GesturePoint(x, y, time)); - if (!recognizeGesture()) { - mListener.onGestureCancelled(event, policyFlags); - } - return true; + return recognizeGesture(event, policyFlags); } break; @@ -244,8 +307,8 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen case MotionEvent.ACTION_POINTER_UP: // If we're detecting taps on the second finger, see if we // should finish the double tap. - if (mSecondFingerDoubleTap && maybeFinishDoubleTap(event, policyFlags)) { - return true; + if (mSecondFingerDoubleTap && mDoubleTapDetected) { + return finishDoubleTap(event, policyFlags); } break; @@ -308,7 +371,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 true; + return mListener.onDoubleTapStarted(); } private void maybeSendLongPress(MotionEvent event, int policyFlags) { @@ -321,11 +384,7 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen mListener.onDoubleTapAndHold(event, policyFlags); } - private boolean maybeFinishDoubleTap(MotionEvent event, int policyFlags) { - if (!mDoubleTapDetected) { - return false; - } - + private boolean finishDoubleTap(MotionEvent event, int policyFlags) { clear(); return mListener.onDoubleTap(event, policyFlags); @@ -337,7 +396,7 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen mStrokeBuffer.clear(); } - private boolean recognizeGesture() { + private boolean recognizeGesture(MotionEvent event, int policyFlags) { Gesture gesture = new Gesture(); gesture.addStroke(new GestureStroke(mStrokeBuffer)); @@ -351,16 +410,14 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen } try { final int gestureId = Integer.parseInt(bestPrediction.name); - if (mListener.onGestureCompleted(gestureId)) { - return true; - } + return mListener.onGestureCompleted(gestureId); } catch (NumberFormatException nfe) { Slog.w(LOG_TAG, "Non numeric gesture id:" + bestPrediction.name); } } } - return false; + return mListener.onGestureCancelled(event, policyFlags); } private MotionEvent mapSecondPointerToFirstPointer(MotionEvent event) { diff --git a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java index 3ecff405d756..cd8b792449cc 100644 --- a/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java +++ b/services/accessibility/java/com/android/server/accessibility/TouchExplorer.java @@ -390,6 +390,11 @@ 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) { @@ -437,6 +442,20 @@ class TouchExplorer implements EventStreamTransformation, AccessibilityGestureDe } @Override + public boolean onGestureStarted() { + // We have to perform gesture detection, so + // clear the current state and try to detect. + mCurrentState = STATE_GESTURE_DETECTING; + mSendHoverEnterAndMoveDelayed.cancel(); + mSendHoverExitDelayed.cancel(); + mExitGestureDetectionModeDelayed.post(); + // Send accessibility event to announce the start + // of gesture recognition. + sendAccessibilityEvent(AccessibilityEvent.TYPE_GESTURE_DETECTION_START); + return false; + } + + @Override public boolean onGestureCompleted(int gestureId) { if (mCurrentState != STATE_GESTURE_DETECTING) { return false; @@ -450,36 +469,26 @@ class TouchExplorer implements EventStreamTransformation, AccessibilityGestureDe } @Override - public void onGestureStarted() { - // We have to perform gesture detection, so - // clear the current state and try to detect. - mCurrentState = STATE_GESTURE_DETECTING; - mSendHoverEnterAndMoveDelayed.cancel(); - mSendHoverExitDelayed.cancel(); - mExitGestureDetectionModeDelayed.post(); - // Send accessibility event to announce the start - // of gesture recognition. - sendAccessibilityEvent(AccessibilityEvent.TYPE_GESTURE_DETECTION_START); - } + public boolean onGestureCancelled(MotionEvent event, int policyFlags) { + if (mCurrentState == STATE_GESTURE_DETECTING) { + endGestureDetection(); + return true; + } else if (mCurrentState == STATE_TOUCH_EXPLORING) { + // If the finger is still moving, pass the event on. + if (event.getActionMasked() == MotionEvent.ACTION_MOVE) { + final int pointerId = mReceivedPointerTracker.getPrimaryPointerId(); + final int pointerIdBits = (1 << pointerId); - @Override - public void onGestureCancelled(MotionEvent event, int policyFlags) { - if (mCurrentState == STATE_GESTURE_DETECTING) { - endGestureDetection(); - } else if (mCurrentState == STATE_TOUCH_EXPLORING) { - // If the finger is still moving, pass the event on. - if (event.getActionMasked() == MotionEvent.ACTION_MOVE) { - final int pointerId = mReceivedPointerTracker.getPrimaryPointerId(); - final int pointerIdBits = (1 << pointerId); - - // We have just decided that the user is touch, - // exploring so start sending events. - mSendHoverEnterAndMoveDelayed.addEvent(event); - mSendHoverEnterAndMoveDelayed.forceSendAndRemove(); - mSendHoverExitDelayed.cancel(); - sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags); - } - } + // We have just decided that the user is touch, + // exploring so start sending events. + mSendHoverEnterAndMoveDelayed.addEvent(event); + mSendHoverEnterAndMoveDelayed.forceSendAndRemove(); + mSendHoverExitDelayed.cancel(); + sendMotionEvent(event, MotionEvent.ACTION_HOVER_MOVE, pointerIdBits, policyFlags); + return true; + } + } + return false; } /** diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java index 46671729a2ef..c5a210c6802d 100644 --- a/services/core/java/com/android/server/AlarmManagerService.java +++ b/services/core/java/com/android/server/AlarmManagerService.java @@ -150,6 +150,12 @@ class AlarmManagerService extends SystemService { int mNumTimeChanged; /** + * The current set of user whitelisted apps for device idle mode, meaning these are allowed + * to freely schedule alarms. + */ + int[] mDeviceIdleUserWhitelist = new int[0]; + + /** * For each uid, this is the last time we dispatched an "allow while idle" alarm, * used to determine the earliest we can dispatch the next such alarm. */ @@ -936,6 +942,7 @@ class AlarmManagerService extends SystemService { } publishBinderService(Context.ALARM_SERVICE, mService); + publishLocalService(LocalService.class, new LocalService()); } @Override @@ -1251,14 +1258,6 @@ class AlarmManagerService extends SystemService { flags &= ~AlarmManager.FLAG_IDLE_UNTIL; } - // If the caller is a core system component, and not calling to do work on behalf - // of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED. This means we - // will allow these alarms to go off as normal even while idle, with no timing - // restrictions. - if (callingUid < Process.FIRST_APPLICATION_UID && workSource == null) { - flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; - } - // If this is an exact time alarm, then it can't be batched with other alarms. if (windowLength == AlarmManager.WINDOW_EXACT) { flags |= AlarmManager.FLAG_STANDALONE; @@ -1268,6 +1267,16 @@ class AlarmManagerService extends SystemService { // use it to wake early from idle if needed. if (alarmClock != null) { flags |= AlarmManager.FLAG_WAKE_FROM_IDLE | AlarmManager.FLAG_STANDALONE; + + // If the caller is a core system component or on the user's whitelist, and not calling + // to do work on behalf of someone else, then always set ALLOW_WHILE_IDLE_UNRESTRICTED. + // This means we will allow these alarms to go off as normal even while idle, with no + // timing restrictions. + } else if (workSource == null && (callingUid < Process.FIRST_APPLICATION_UID + || Arrays.binarySearch(mDeviceIdleUserWhitelist, + UserHandle.getAppId(callingUid)) >= 0)) { + flags |= AlarmManager.FLAG_ALLOW_WHILE_IDLE_UNRESTRICTED; + flags &= ~AlarmManager.FLAG_ALLOW_WHILE_IDLE; } setImpl(type, triggerAtTime, windowLength, interval, operation, directReceiver, @@ -1344,6 +1353,12 @@ class AlarmManagerService extends SystemService { } }; + public final class LocalService { + public void setDeviceIdleUserWhitelist(int[] appids) { + setDeviceIdleUserWhitelistImpl(appids); + } + } + void dumpImpl(PrintWriter pw) { synchronized (mLock) { pw.println("Current Alarm Manager state:"); @@ -1386,6 +1401,7 @@ class AlarmManagerService extends SystemService { pw.print(" Next wakeup: "); TimeUtils.formatDuration(mNextWakeup, nowELAPSED, pw); pw.print(" = "); pw.println(sdf.format(new Date(nextWakeupRTC))); pw.print(" Num time change events: "); pw.println(mNumTimeChanged); + pw.println(" mDeviceIdleUserWhitelist=" + Arrays.toString(mDeviceIdleUserWhitelist)); pw.println(); pw.println(" Next alarm clock information: "); @@ -1678,6 +1694,12 @@ class AlarmManagerService extends SystemService { } } + void setDeviceIdleUserWhitelistImpl(int[] appids) { + synchronized (mLock) { + mDeviceIdleUserWhitelist = appids; + } + } + AlarmManager.AlarmClockInfo getNextAlarmClockImpl(int userId) { synchronized (mLock) { return mNextAlarmClockForUser.get(userId); 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/DeviceIdleController.java b/services/core/java/com/android/server/DeviceIdleController.java index 62fa7d5af754..7bf4b56c03d1 100644 --- a/services/core/java/com/android/server/DeviceIdleController.java +++ b/services/core/java/com/android/server/DeviceIdleController.java @@ -120,6 +120,7 @@ public class DeviceIdleController extends SystemService private AlarmManager mAlarmManager; private IBatteryStats mBatteryStats; private PowerManagerInternal mLocalPowerManager; + private AlarmManagerService.LocalService mLocalAlarmManager; private INetworkPolicyManager mNetworkPolicyManager; private DisplayManager mDisplayManager; private SensorManager mSensorManager; @@ -269,6 +270,17 @@ public class DeviceIdleController extends SystemService private int[] mPowerSaveWhitelistAllAppIdArray = new int[0]; /** + * App IDs that have been white-listed by the user to opt out of power save restrictions. + */ + private final SparseBooleanArray mPowerSaveWhitelistUserAppIds = new SparseBooleanArray(); + + /** + * Current app IDs that are in the user power save white list. This array can + * be shared with others because it will not be modified once set. + */ + private int[] mPowerSaveWhitelistUserAppIdArray = new int[0]; + + /** * List of end times for UIDs that are temporarily marked as being allowed to access * the network and acquire wakelocks. Times are in milliseconds. */ @@ -964,6 +976,10 @@ public class DeviceIdleController extends SystemService return getSystemPowerWhitelistInternal(); } + @Override public String[] getUserPowerWhitelist() { + return getUserPowerWhitelistInternal(); + } + @Override public String[] getFullPowerWhitelistExceptIdle() { return getFullPowerWhitelistExceptIdleInternal(); } @@ -980,6 +996,10 @@ public class DeviceIdleController extends SystemService return getAppIdWhitelistInternal(); } + @Override public int[] getAppIdUserWhitelist() { + return getAppIdUserWhitelistInternal(); + } + @Override public int[] getAppIdTempWhitelist() { return getAppIdTempWhitelistInternal(); } @@ -1161,6 +1181,7 @@ public class DeviceIdleController extends SystemService mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE); mBatteryStats = BatteryStatsService.getService(); mLocalPowerManager = getLocalService(PowerManagerInternal.class); + mLocalAlarmManager = getLocalService(AlarmManagerService.LocalService.class); mNetworkPolicyManager = INetworkPolicyManager.Stub.asInterface( ServiceManager.getService(Context.NETWORK_POLICY_SERVICE)); mDisplayManager = (DisplayManager) getContext().getSystemService( @@ -1227,6 +1248,7 @@ public class DeviceIdleController extends SystemService getContext().registerReceiver(mReceiver, filter); mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); + mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray); mDisplayManager.registerDisplayListener(mDisplayListener, null); updateDisplayLocked(); @@ -1291,6 +1313,17 @@ public class DeviceIdleController extends SystemService } } + public String[] getUserPowerWhitelistInternal() { + synchronized (this) { + int size = mPowerSaveWhitelistUserApps.size(); + String[] apps = new String[size]; + for (int i = 0; i < mPowerSaveWhitelistUserApps.size(); i++) { + apps[i] = mPowerSaveWhitelistUserApps.keyAt(i); + } + return apps; + } + } + public String[] getFullPowerWhitelistExceptIdleInternal() { synchronized (this) { int size = mPowerSaveWhitelistAppsExceptIdle.size() + mPowerSaveWhitelistUserApps.size(); @@ -1351,6 +1384,12 @@ public class DeviceIdleController extends SystemService } } + public int[] getAppIdUserWhitelistInternal() { + synchronized (this) { + return mPowerSaveWhitelistUserAppIdArray; + } + } + public int[] getAppIdTempWhitelistInternal() { synchronized (this) { return mTempWhitelistAppIdArray; @@ -1993,11 +2032,15 @@ public class DeviceIdleController extends SystemService private static int[] buildAppIdArray(ArrayMap<String, Integer> systemApps, ArrayMap<String, Integer> userApps, SparseBooleanArray outAppIds) { outAppIds.clear(); - for (int i=0; i<systemApps.size(); i++) { - outAppIds.put(systemApps.valueAt(i), true); + if (systemApps != null) { + for (int i = 0; i < systemApps.size(); i++) { + outAppIds.put(systemApps.valueAt(i), true); + } } - for (int i=0; i<userApps.size(); i++) { - outAppIds.put(userApps.valueAt(i), true); + if (userApps != null) { + for (int i = 0; i < userApps.size(); i++) { + outAppIds.put(userApps.valueAt(i), true); + } } int size = outAppIds.size(); int[] appids = new int[size]; @@ -2012,6 +2055,8 @@ public class DeviceIdleController extends SystemService mPowerSaveWhitelistUserApps, mPowerSaveWhitelistExceptIdleAppIds); mPowerSaveWhitelistAllAppIdArray = buildAppIdArray(mPowerSaveWhitelistApps, mPowerSaveWhitelistUserApps, mPowerSaveWhitelistAllAppIds); + mPowerSaveWhitelistUserAppIdArray = buildAppIdArray(null, + mPowerSaveWhitelistUserApps, mPowerSaveWhitelistUserAppIds); if (mLocalPowerManager != null) { if (DEBUG) { Slog.d(TAG, "Setting wakelock whitelist to " @@ -2019,6 +2064,13 @@ public class DeviceIdleController extends SystemService } mLocalPowerManager.setDeviceIdleWhitelist(mPowerSaveWhitelistAllAppIdArray); } + if (mLocalAlarmManager != null) { + if (DEBUG) { + Slog.d(TAG, "Setting alarm whitelist to " + + Arrays.toString(mPowerSaveWhitelistUserAppIdArray)); + } + mLocalAlarmManager.setDeviceIdleUserWhitelist(mPowerSaveWhitelistUserAppIdArray); + } } private void updateTempWhitelistAppIdsLocked() { @@ -2536,6 +2588,15 @@ public class DeviceIdleController extends SystemService pw.println(); } } + size = mPowerSaveWhitelistUserAppIds.size(); + if (size > 0) { + pw.println(" Whitelist user app ids:"); + for (int i = 0; i < size; i++) { + pw.print(" "); + pw.print(mPowerSaveWhitelistUserAppIds.keyAt(i)); + pw.println(); + } + } size = mPowerSaveWhitelistAllAppIds.size(); if (size > 0) { pw.println(" Whitelist all app ids:"); diff --git a/services/core/java/com/android/server/DiskStatsService.java b/services/core/java/com/android/server/DiskStatsService.java index 93131488f509..8ca675a904c4 100644 --- a/services/core/java/com/android/server/DiskStatsService.java +++ b/services/core/java/com/android/server/DiskStatsService.java @@ -80,7 +80,7 @@ public class DiskStatsService extends Binder { reportFreeSpace(Environment.getDownloadCacheDirectory(), "Cache", pw); reportFreeSpace(new File("/system"), "System", pw); - if (StorageManager.isNativeFileBasedEncryptionEnabled()) { + if (StorageManager.isFileEncryptedNativeOnly()) { pw.println("File-based Encryption: true"); } diff --git a/services/core/java/com/android/server/InputMethodManagerService.java b/services/core/java/com/android/server/InputMethodManagerService.java index a93b4d8bc250..9b8f2d2d7d57 100644 --- a/services/core/java/com/android/server/InputMethodManagerService.java +++ b/services/core/java/com/android/server/InputMethodManagerService.java @@ -3588,6 +3588,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub private static final String ATTR_IME_SUBTYPE_MODE = "imeSubtypeMode"; private static final String ATTR_IME_SUBTYPE_EXTRA_VALUE = "imeSubtypeExtraValue"; private static final String ATTR_IS_AUXILIARY = "isAuxiliary"; + private static final String ATTR_IS_ASCII_CAPABLE = "isAsciiCapable"; private final AtomicFile mAdditionalInputMethodSubtypeFile; private final HashMap<String, InputMethodInfo> mMethodMap; private final HashMap<String, List<InputMethodSubtype>> mAdditionalSubtypesMap = @@ -3684,6 +3685,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub out.attribute(null, ATTR_IME_SUBTYPE_EXTRA_VALUE, subtype.getExtraValue()); out.attribute(null, ATTR_IS_AUXILIARY, String.valueOf(subtype.isAuxiliary() ? 1 : 0)); + out.attribute(null, ATTR_IS_ASCII_CAPABLE, + String.valueOf(subtype.isAsciiCapable() ? 1 : 0)); out.endTag(null, NODE_SUBTYPE); } out.endTag(null, NODE_IMI); @@ -3749,6 +3752,8 @@ public class InputMethodManagerService extends IInputMethodManager.Stub parser.getAttributeValue(null, ATTR_IME_SUBTYPE_EXTRA_VALUE); final boolean isAuxiliary = "1".equals(String.valueOf( parser.getAttributeValue(null, ATTR_IS_AUXILIARY))); + final boolean isAsciiCapable = "1".equals(String.valueOf( + parser.getAttributeValue(null, ATTR_IS_ASCII_CAPABLE))); final InputMethodSubtype subtype = new InputMethodSubtypeBuilder() .setSubtypeNameResId(label) .setSubtypeIconResId(icon) @@ -3757,6 +3762,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub .setSubtypeMode(imeSubtypeMode) .setSubtypeExtraValue(imeSubtypeExtraValue) .setIsAuxiliary(isAuxiliary) + .setIsAsciiCapable(isAsciiCapable) .build(); tempSubtypesArray.add(subtype); } diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java index a3322fc99677..4536e048df9d 100644 --- a/services/core/java/com/android/server/MountService.java +++ b/services/core/java/com/android/server/MountService.java @@ -839,11 +839,11 @@ class MountService extends IMountService.Stub Slog.d(TAG, "Thinking about init, mSystemReady=" + mSystemReady + ", mDaemonConnected=" + mDaemonConnected); if (mSystemReady && mDaemonConnected - && !StorageManager.isNativeFileBasedEncryptionEnabled()) { + && !StorageManager.isFileEncryptedNativeOnly()) { // When booting a device without native support, make sure that our // user directories are locked or unlocked based on the current // emulation status. - final boolean initLocked = StorageManager.isEmulatedFileBasedEncryptionEnabled(); + final boolean initLocked = StorageManager.isFileEncryptedEmulatedOnly(); Slog.d(TAG, "Setting up emulation state, initlocked=" + initLocked); final List<UserInfo> users = mContext.getSystemService(UserManager.class).getUsers(); for (UserInfo user : users) { @@ -1940,7 +1940,7 @@ class MountService extends IMountService.Stub waitForReady(); if ((mask & StorageManager.DEBUG_EMULATE_FBE) != 0) { - if (StorageManager.isNativeFileBasedEncryptionEnabled()) { + if (StorageManager.isFileEncryptedNativeOnly()) { throw new IllegalStateException( "Emulation not available on device with native FBE"); } @@ -2811,7 +2811,7 @@ class MountService extends IMountService.Stub @Override public boolean isUserKeyUnlocked(int userId) { - if (StorageManager.isFileBasedEncryptionEnabled()) { + if (StorageManager.isFileEncryptedNativeOrEmulated()) { synchronized (mLock) { return ArrayUtils.contains(mLocalUnlockedUsers, userId); } diff --git a/services/core/java/com/android/server/SystemConfig.java b/services/core/java/com/android/server/SystemConfig.java index 73d8bddc5e60..30e0ceb52af3 100644 --- a/services/core/java/com/android/server/SystemConfig.java +++ b/services/core/java/com/android/server/SystemConfig.java @@ -446,7 +446,7 @@ public class SystemConfig { // Some devices can be field-converted to FBE, so offer to splice in // those features if not already defined by the static config - if (StorageManager.isNativeFileBasedEncryptionEnabled()) { + if (StorageManager.isFileEncryptedNativeOnly()) { addFeature(PackageManager.FEATURE_FILE_BASED_ENCRYPTION, 0); addFeature(PackageManager.FEATURE_SECURELY_REMOVES_USERS, 0); } diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java index 772a15c1bf64..11888ff4705c 100644 --- a/services/core/java/com/android/server/Watchdog.java +++ b/services/core/java/com/android/server/Watchdog.java @@ -64,6 +64,7 @@ public class Watchdog extends Thread { // Which native processes to dump into dropbox's stack traces public static final String[] NATIVE_STACKS_OF_INTEREST = new String[] { + "/system/bin/audioserver", "/system/bin/mediaserver", "/system/bin/sdcard", "/system/bin/surfaceflinger" 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 f07c1d05e29a..07f668bf691f 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -352,6 +352,11 @@ import static com.android.server.am.TaskRecord.INVALID_TASK_ID; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV; import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE; +import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN; +import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH; +import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE; +import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN; +import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT; import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; @@ -537,9 +542,11 @@ public final class ActivityManagerService extends ActivityManagerNative final ActivityStarter mActivityStarter; /** Task stack change listeners. */ - private RemoteCallbackList<ITaskStackListener> mTaskStackListeners = + private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners = new RemoteCallbackList<ITaskStackListener>(); + final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter(); + public IntentFirewall mIntentFirewall; // Whether we should show our dialogs (ANR, crash, etc) or just perform their @@ -3260,9 +3267,9 @@ public final class ActivityManagerService extends ActivityManagerNative boolean isNextTransitionForward() { int transit = mWindowManager.getPendingAppTransition(); - return transit == AppTransition.TRANSIT_ACTIVITY_OPEN - || transit == AppTransition.TRANSIT_TASK_OPEN - || transit == AppTransition.TRANSIT_TASK_TO_FRONT; + return transit == TRANSIT_ACTIVITY_OPEN + || transit == TRANSIT_TASK_OPEN + || transit == TRANSIT_TASK_TO_FRONT; } int startIsolatedProcess(String entryPoint, String[] entryPointArgs, @@ -5270,6 +5277,10 @@ public final class ActivityManagerService extends ActivityManagerNative public boolean clearApplicationUserData(final String packageName, final IPackageDataObserver observer, int userId) { enforceNotIsolatedCaller("clearApplicationUserData"); + int uid = Binder.getCallingUid(); + int pid = Binder.getCallingPid(); + userId = mUserController.handleIncomingUser(pid, uid, userId, false, + ALLOW_FULL_ONLY, "clearApplicationUserData", null); final DevicePolicyManagerInternal dpmi = LocalServices .getService(DevicePolicyManagerInternal.class); @@ -5277,10 +5288,6 @@ public final class ActivityManagerService extends ActivityManagerNative throw new SecurityException("Cannot clear data for a device owner or a profile owner"); } - int uid = Binder.getCallingUid(); - int pid = Binder.getCallingPid(); - userId = mUserController.handleIncomingUser(pid, uid, userId, false, - ALLOW_FULL_ONLY, "clearApplicationUserData", null); long callingId = Binder.clearCallingIdentity(); try { IPackageManager pm = AppGlobals.getPackageManager(); @@ -9100,7 +9107,8 @@ public final class ActivityManagerService extends ActivityManagerNative preserveWindow = false; } - mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow); + mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow, + false /* deferResume */); } } finally { Binder.restoreCallingIdentity(ident); @@ -9165,7 +9173,7 @@ public final class ActivityManagerService extends ActivityManagerNative throw new IllegalArgumentException("Expected in-place ActivityOption " + "with valid animation"); } - mWindowManager.prepareAppTransition(AppTransition.TRANSIT_TASK_IN_PLACE, false); + mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false); mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(), opts.getCustomInPlaceResId()); mWindowManager.executeAppTransition(); @@ -9544,6 +9552,55 @@ public final class ActivityManagerService extends ActivityManagerNative } } + @Override + public void swapDockedAndFullscreenStack() throws RemoteException { + enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()"); + synchronized (this) { + long ident = Binder.clearCallingIdentity(); + try { + final ActivityStack fullscreenStack = mStackSupervisor.getStack( + FULLSCREEN_WORKSPACE_STACK_ID); + final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask() + : null; + final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID); + final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks() + : null; + if (topTask == null || tasks == null || tasks.size() == 0) { + Slog.w(TAG, + "Unable to swap tasks, either docked or fullscreen stack is empty."); + return; + } + + // TODO: App transition + mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false); + + // Defer the resume so resume/pausing while moving stacks is dangerous. + mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID, + false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack", + ANIMATE, true /* deferResume */); + final int size = tasks.size(); + for (int i = 0; i < size; i++) { + final int id = tasks.get(i).taskId; + if (id == topTask.taskId) { + continue; + } + mStackSupervisor.moveTaskToStackLocked(id, + FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS, + "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */); + } + + // Because we deferred the resume, to avoid conflicts with stack switches while + // resuming, we need to do it after all the tasks are moved. + mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS); + mStackSupervisor.resumeFocusedStackTopActivityLocked(); + + mWindowManager.executeAppTransition(); + } finally { + Binder.restoreCallingIdentity(ident); + } + } + } + /** * Moves the input task to the docked stack. * @@ -10886,7 +10943,7 @@ public final class ActivityManagerService extends ActivityManagerNative * belonging to any running apps. */ private void installEncryptionUnawareProviders(int userId) { - if (!StorageManager.isFileBasedEncryptionEnabled()) { + if (!StorageManager.isFileEncryptedNativeOrEmulated()) { // TODO: eventually pivot this back to look at current user state, // similar to the comment in UserManager.isUserUnlocked(), but for // now, if we started apps when "unlocked" then unaware providers @@ -17796,17 +17853,17 @@ public final class ActivityManagerService extends ActivityManagerNative } catch (RemoteException e) { } if (ii == null) { - reportStartInstrumentationFailure(watcher, className, + reportStartInstrumentationFailureLocked(watcher, className, "Unable to find instrumentation info for: " + className); return false; } if (ai == null) { - reportStartInstrumentationFailure(watcher, className, + reportStartInstrumentationFailureLocked(watcher, className, "Unable to find instrumentation target package: " + ii.targetPackage); return false; } if (!ai.hasCode()) { - reportStartInstrumentationFailure(watcher, className, + reportStartInstrumentationFailureLocked(watcher, className, "Instrumentation target has no code: " + ii.targetPackage); return false; } @@ -17821,7 +17878,7 @@ public final class ActivityManagerService extends ActivityManagerNative + " not allowed because package " + ii.packageName + " does not have a signature matching the target " + ii.targetPackage; - reportStartInstrumentationFailure(watcher, className, msg); + reportStartInstrumentationFailureLocked(watcher, className, msg); throw new SecurityException(msg); } @@ -17852,31 +17909,21 @@ public final class ActivityManagerService extends ActivityManagerNative * @param cn The component name of the instrumentation. * @param report The error report. */ - private void reportStartInstrumentationFailure(IInstrumentationWatcher watcher, + private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher, ComponentName cn, String report) { Slog.w(TAG, report); - try { - if (watcher != null) { - Bundle results = new Bundle(); - results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); - results.putString("Error", report); - watcher.instrumentationStatus(cn, -1, results); - } - } catch (RemoteException e) { - Slog.w(TAG, e); + if (watcher != null) { + Bundle results = new Bundle(); + results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService"); + results.putString("Error", report); + mInstrumentationReporter.reportStatus(watcher, cn, -1, results); } } void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) { if (app.instrumentationWatcher != null) { - try { - // NOTE: IInstrumentationWatcher *must* be oneway here - app.instrumentationWatcher.instrumentationFinished( - app.instrumentationClass, - resultCode, - results); - } catch (RemoteException e) { - } + mInstrumentationReporter.reportFinished(app.instrumentationWatcher, + app.instrumentationClass, resultCode, results); } // Can't call out of the system process with a lock held, so post a message. diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 39895ac54e7f..09542cbdf3e1 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -20,6 +20,7 @@ import static android.app.ActivityManager.StackId.DOCKED_STACK_ID; import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID; import static android.app.ActivityManager.StackId.HOME_STACK_ID; +import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.ActivityManager.StackId.PINNED_STACK_ID; import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION; import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT; @@ -414,6 +415,12 @@ final class ActivityStack { mTaskPositioner.reset(); } mWindowManager.detachStack(mStackId); + if (mStackId == DOCKED_STACK_ID) { + // If we removed a docked stack we want to resize it so it resizes all other stacks + // in the system to fullscreen. + mStackSupervisor.resizeDockedStackLocked( + null, null, null, null, null, PRESERVE_WINDOWS); + } } public void getDisplaySize(Point out) { @@ -1398,22 +1405,37 @@ final class ActivityStack { * needed. A stack is considered translucent if it don't contain a visible or * starting (about to be visible) activity that is fullscreen (opaque). * @param starting The currently starting activity or null if there is none. + * @param stackBehindId The id of the stack directly behind this one. */ - private boolean isStackTranslucent(ActivityRecord starting) { + private boolean isStackTranslucent(ActivityRecord starting, int stackBehindId) { for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { final TaskRecord task = mTaskHistory.get(taskNdx); final ArrayList<ActivityRecord> activities = task.mActivities; for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { final ActivityRecord r = activities.get(activityNdx); - // Conditions for an activity to obscure the stack we're - // examining: - // 1. Not Finishing AND (Visible or the Starting activity) AND: - // 2. Either: - // - Full Screen Activity OR - // - On top of Home and our stack is NOT home - if (!r.finishing && (r.visible || r == starting) && (r.fullscreen || - (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()))) { + if (r.finishing) { + // We don't factor in finishing activities when determining translucency since + // they will be gone soon. + continue; + } + + if (!r.visible && r != starting) { + // Also ignore invisible activities that are not the currently starting + // activity (about to be visible). + continue; + } + + if (r.fullscreen) { + // Stack isn't translucent if it has at least one fullscreen activity + // that is visible. + return false; + } + + if (!isHomeStack() && r.frontOfTask + && task.isOverHomeStack() && stackBehindId != HOME_STACK_ID) { + // Stack isn't translucent if it's top activity should have the home stack + // behind it and the stack currently behind it isn't the home stack. return false; } } @@ -1469,30 +1491,33 @@ final class ActivityStack { : STACK_INVISIBLE; } - // Find the first stack below focused stack that actually got something visible. - int belowFocusedIndex = mStacks.indexOf(focusedStack) - 1; - while (belowFocusedIndex >= 0 && - mStacks.get(belowFocusedIndex).topRunningActivityLocked() == null) { - belowFocusedIndex--; + // Find the first stack behind focused stack that actually got something visible. + int stackBehindFocusedIndex = mStacks.indexOf(focusedStack) - 1; + while (stackBehindFocusedIndex >= 0 && + mStacks.get(stackBehindFocusedIndex).topRunningActivityLocked() == null) { + stackBehindFocusedIndex--; } if ((focusedStackId == DOCKED_STACK_ID || focusedStackId == PINNED_STACK_ID) - && stackIndex == belowFocusedIndex) { + && stackIndex == stackBehindFocusedIndex) { // Stacks directly behind the docked or pinned stack are always visible. return STACK_VISIBLE; } + final int stackBehindFocusedId = (stackBehindFocusedIndex >= 0) + ? mStacks.get(stackBehindFocusedIndex).mStackId : INVALID_STACK_ID; + if (focusedStackId == FULLSCREEN_WORKSPACE_STACK_ID - && focusedStack.isStackTranslucent(starting)) { + && focusedStack.isStackTranslucent(starting, stackBehindFocusedId)) { // Stacks behind the fullscreen stack with a translucent activity are always // visible so they can act as a backdrop to the translucent activity. // For example, dialog activities - if (stackIndex == belowFocusedIndex) { + if (stackIndex == stackBehindFocusedIndex) { return STACK_VISIBLE; } - if (belowFocusedIndex >= 0) { - final ActivityStack stack = mStacks.get(belowFocusedIndex); - if ((stack.mStackId == DOCKED_STACK_ID || stack.mStackId == PINNED_STACK_ID) - && stackIndex == (belowFocusedIndex - 1)) { + if (stackBehindFocusedIndex >= 0) { + if ((stackBehindFocusedId == DOCKED_STACK_ID + || stackBehindFocusedId == PINNED_STACK_ID) + && stackIndex == (stackBehindFocusedIndex - 1)) { // The stack behind the docked or pinned stack is also visible so we can have a // complete backdrop to the translucent activity when the docked stack is up. return STACK_VISIBLE; @@ -1517,7 +1542,7 @@ final class ActivityStack { return STACK_INVISIBLE; } - if (!stack.isStackTranslucent(starting)) { + if (!stack.isStackTranslucent(starting, INVALID_STACK_ID)) { return STACK_INVISIBLE; } } @@ -1784,6 +1809,12 @@ final class ActivityStack { r.app.pendingUiClean = true; r.app.thread.scheduleWindowVisibility(r.appToken, true); r.stopFreezingScreenLocked(false); + + // The activity may be waiting for stop, but that is no longer + // appropriate for it. + mStackSupervisor.mStoppingActivities.remove(r); + mStackSupervisor.mGoingToSleepActivities.remove(r); + mStackSupervisor.mWaitingVisibleActivities.remove(r); } catch (Exception e) { // Just skip on any failure; we'll make it // visible when it next restarts. diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java index 48f31f9bc222..d364d8569db0 100644 --- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java @@ -2062,7 +2062,8 @@ public final class ActivityStackSupervisor implements DisplayListener { } } - boolean resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow) { + boolean resizeTaskLocked(TaskRecord task, Rect bounds, int resizeMode, boolean preserveWindow, + boolean deferResume) { if (!task.isResizeable()) { Slog.w(TAG, "resizeTask: task " + task + " not resizeable."); return true; @@ -2105,10 +2106,14 @@ public final class ActivityStackSupervisor implements DisplayListener { if (r != null) { final ActivityStack stack = task.stack; kept = stack.ensureActivityConfigurationLocked(r, 0, preserveWindow); - // All other activities must be made visible with their correct configuration. - ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS); - if (!kept) { - resumeFocusedStackTopActivityLocked(); + + if (!deferResume) { + + // All other activities must be made visible with their correct configuration. + ensureActivitiesVisibleLocked(r, 0, !PRESERVE_WINDOWS); + if (!kept) { + resumeFocusedStackTopActivityLocked(); + } } } } @@ -2247,6 +2252,12 @@ public final class ActivityStackSupervisor implements DisplayListener { boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus, String reason, boolean animate) { + return moveTaskToStackLocked(taskId, stackId, toTop, forceFocus, reason, animate, + false /* deferResume */); + } + + boolean moveTaskToStackLocked(int taskId, int stackId, boolean toTop, boolean forceFocus, + String reason, boolean animate, boolean deferResume) { final TaskRecord task = anyTaskForIdLocked(taskId); if (task == null) { Slog.w(TAG, "moveTaskToStack: no task for id=" + taskId); @@ -2297,16 +2308,19 @@ public final class ActivityStackSupervisor implements DisplayListener { // Make sure the task has the appropriate bounds/size for the stack it is in. if (stackId == FULLSCREEN_WORKSPACE_STACK_ID && task.mBounds != null) { - kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow); + kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, + !mightReplaceWindow, deferResume); } else if (stackId == FREEFORM_WORKSPACE_STACK_ID) { Rect bounds = task.getLaunchBounds(); if (bounds == null) { stack.layoutTaskInStack(task, null); bounds = task.mBounds; } - kept = resizeTaskLocked(task, bounds, RESIZE_MODE_FORCED, !mightReplaceWindow); + kept = resizeTaskLocked(task, bounds, RESIZE_MODE_FORCED, !mightReplaceWindow, + deferResume); } else if (stackId == DOCKED_STACK_ID || stackId == PINNED_STACK_ID) { - kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, !mightReplaceWindow); + kept = resizeTaskLocked(task, stack.mBounds, RESIZE_MODE_SYSTEM, + !mightReplaceWindow, deferResume); } } finally { mWindowManager.continueSurfaceLayout(); @@ -2319,10 +2333,13 @@ public final class ActivityStackSupervisor implements DisplayListener { mWindowManager.scheduleClearReplacingWindowIfNeeded(topActivity.appToken, !kept); } - // The task might have already been running and its visibility needs to be synchronized with - // the visibility of the stack / windows. - ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow); - resumeFocusedStackTopActivityLocked(); + if (!deferResume) { + + // The task might have already been running and its visibility needs to be synchronized with + // the visibility of the stack / windows. + ensureActivitiesVisibleLocked(null, 0, !mightReplaceWindow); + resumeFocusedStackTopActivityLocked(); + } showNonResizeableDockToastIfNeeded(task, preferredLaunchStackId, stackId); @@ -2372,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/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java index 28882def6b99..71a1f97bf8c8 100644 --- a/services/core/java/com/android/server/am/BatteryStatsService.java +++ b/services/core/java/com/android/server/am/BatteryStatsService.java @@ -32,6 +32,7 @@ import android.os.Message; import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.ParcelFormatException; +import android.os.PowerManager; import android.os.PowerManagerInternal; import android.os.Process; import android.os.RemoteException; @@ -39,6 +40,9 @@ import android.os.ServiceManager; import android.os.SystemClock; import android.os.UserHandle; import android.os.WorkSource; +import android.os.health.HealthStatsParceler; +import android.os.health.HealthStatsWriter; +import android.os.health.UidHealthStats; import android.telephony.DataConnectionRealTimeInfo; import android.telephony.ModemActivityInfo; import android.telephony.SignalStrength; @@ -65,7 +69,9 @@ import java.nio.CharBuffer; import java.nio.charset.CharsetDecoder; import java.nio.charset.CodingErrorAction; import java.nio.charset.StandardCharsets; +import java.util.Arrays; import java.util.List; +import java.util.Map; /** * All information we are collecting about things that can happen that impact @@ -1419,4 +1425,88 @@ public final class BatteryStatsService extends IBatteryStats.Stub } } } + + /** + * Gets a snapshot of the system health for a particular uid. + */ + @Override + public HealthStatsParceler takeUidSnapshot(int requestUid) { + if (requestUid != Binder.getCallingUid()) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BATTERY_STATS, null); + } + long ident = Binder.clearCallingIdentity(); + try { + updateExternalStats("get-health-stats-for-uid", + BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL); + synchronized (mStats) { + return getHealthStatsForUidLocked(requestUid); + } + } catch (Exception ex) { + Slog.d(TAG, "Crashed while writing for takeUidSnapshot(" + requestUid + ")", ex); + throw ex; + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + /** + * Gets a snapshot of the system health for a number of uids. + */ + @Override + public HealthStatsParceler[] takeUidSnapshots(int[] requestUids) { + if (!onlyCaller(requestUids)) { + mContext.enforceCallingOrSelfPermission( + android.Manifest.permission.BATTERY_STATS, null); + } + long ident = Binder.clearCallingIdentity(); + int i=-1; + try { + updateExternalStats("get-health-stats-for-uids", + BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL); + synchronized (mStats) { + final int N = requestUids.length; + final HealthStatsParceler[] results = new HealthStatsParceler[N]; + for (i=0; i<N; i++) { + results[i] = getHealthStatsForUidLocked(requestUids[i]); + } + return results; + } + } catch (Exception ex) { + Slog.d(TAG, "Crashed while writing for takeUidSnapshots(" + + Arrays.toString(requestUids) + ") i=" + i, ex); + throw ex; + } finally { + Binder.restoreCallingIdentity(ident); + } + } + + /** + * Returns whether the Binder.getCallingUid is the only thing in requestUids. + */ + private static boolean onlyCaller(int[] requestUids) { + final int caller = Binder.getCallingUid(); + final int N = requestUids.length; + for (int i=0; i<N; i++) { + if (requestUids[i] != caller) { + return false; + } + } + return true; + } + + /** + * Gets a HealthStatsParceler for the given uid. You should probably call + * updateExternalStats first. + */ + HealthStatsParceler getHealthStatsForUidLocked(int requestUid) { + final HealthStatsBatteryStatsWriter writer = new HealthStatsBatteryStatsWriter(); + final HealthStatsWriter uidWriter = new HealthStatsWriter(UidHealthStats.CONSTANTS); + final BatteryStats.Uid uid = mStats.getUidStats().get(requestUid); + if (uid != null) { + writer.writeUid(uidWriter, mStats, uid); + } + return new HealthStatsParceler(uidWriter); + } + } diff --git a/services/core/java/com/android/server/am/HealthStatsBatteryStatsWriter.java b/services/core/java/com/android/server/am/HealthStatsBatteryStatsWriter.java new file mode 100644 index 000000000000..39c6ce6345d2 --- /dev/null +++ b/services/core/java/com/android/server/am/HealthStatsBatteryStatsWriter.java @@ -0,0 +1,473 @@ +/* + * 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.server.am; + +import android.os.BatteryStats; +import static android.os.BatteryStats.STATS_SINCE_UNPLUGGED; +import android.os.PowerManager; +import android.os.SystemClock; +import android.os.health.HealthKeys; +import android.os.health.HealthStatsParceler; +import android.os.health.HealthStatsWriter; +import android.os.health.PackageHealthStats; +import android.os.health.ProcessHealthStats; +import android.os.health.PidHealthStats; +import android.os.health.ServiceHealthStats; +import android.os.health.TimerStat; +import android.os.health.UidHealthStats; +import android.util.SparseArray; + +import java.util.Map; + +public class HealthStatsBatteryStatsWriter { + + private final long mNowRealtime; + private final long mNowUptime; + + public HealthStatsBatteryStatsWriter() { + mNowRealtime = SystemClock.elapsedRealtime(); + mNowUptime = SystemClock.uptimeMillis(); + } + + /** + * Writes the contents of a BatteryStats.Uid into a HealthStatsWriter. + */ + public void writeUid(HealthStatsWriter uidWriter, BatteryStats bs, BatteryStats.Uid uid) { + int N; + BatteryStats.Timer timer; + SparseArray<? extends BatteryStats.Uid.Sensor> sensors; + SparseArray<? extends BatteryStats.Uid.Pid> pids; + BatteryStats.ControllerActivityCounter controller; + long sum; + + // + // It's a little odd for these first four to be here but it's not the end of the + // world. It would be easy enough to duplicate them somewhere else if this API + // grows. + // + + // MEASUREMENT_REALTIME_BATTERY_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_REALTIME_BATTERY_MS, + bs.computeBatteryRealtime(mNowRealtime*1000, STATS_SINCE_UNPLUGGED)/1000); + + // MEASUREMENT_UPTIME_BATTERY_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_UPTIME_BATTERY_MS, + bs.computeBatteryUptime(mNowUptime*1000, STATS_SINCE_UNPLUGGED)/1000); + + // MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_REALTIME_SCREEN_OFF_BATTERY_MS, + bs.computeBatteryScreenOffRealtime(mNowRealtime*1000, STATS_SINCE_UNPLUGGED)/1000); + + // MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_UPTIME_SCREEN_OFF_BATTERY_MS, + bs.computeBatteryScreenOffUptime(mNowUptime*1000, STATS_SINCE_UNPLUGGED)/1000); + + // + // Now on to the real per-uid stats... + // + + for (final Map.Entry<String,? extends BatteryStats.Uid.Wakelock> entry: + uid.getWakelockStats().entrySet()) { + final String key = entry.getKey(); + final BatteryStats.Uid.Wakelock wakelock = entry.getValue(); + + // TIMERS_WAKELOCKS_FULL + timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_FULL); + addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_FULL, key, timer); + + // TIMERS_WAKELOCKS_PARTIAL + timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_PARTIAL); + addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_PARTIAL, key, timer); + + // TIMERS_WAKELOCKS_WINDOW + timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_WINDOW); + addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_WINDOW, key, timer); + + // TIMERS_WAKELOCKS_DRAW + timer = wakelock.getWakeTime(BatteryStats.WAKE_TYPE_DRAW); + addTimers(uidWriter, UidHealthStats.TIMERS_WAKELOCKS_DRAW, key, timer); + } + + // TIMERS_SYNCS + for (final Map.Entry<String,? extends BatteryStats.Timer> entry: + uid.getSyncStats().entrySet()) { + addTimers(uidWriter, UidHealthStats.TIMERS_SYNCS, entry.getKey(), entry.getValue()); + } + + // TIMERS_JOBS + for (final Map.Entry<String,? extends BatteryStats.Timer> entry: + uid.getJobStats().entrySet()) { + addTimers(uidWriter, UidHealthStats.TIMERS_JOBS, entry.getKey(), entry.getValue()); + } + + // TIMERS_SENSORS + sensors = uid.getSensorStats(); + N = sensors.size(); + for (int i=0; i<N; i++) { + int sensorId = sensors.keyAt(i); + // Battery Stats stores the GPS sensors with a bogus key in this API. Pull it out + // as a separate metric here so as to not expose that in the API. + if (sensorId == BatteryStats.Uid.Sensor.GPS) { + addTimer(uidWriter, UidHealthStats.TIMER_GPS_SENSOR, sensors.valueAt(i).getSensorTime()); + } else { + addTimers(uidWriter, UidHealthStats.TIMERS_SENSORS, Integer.toString(sensorId), + sensors.valueAt(i).getSensorTime()); + } + } + + // STATS_PIDS + pids = uid.getPidStats(); + N = sensors.size(); + for (int i=0; i<N; i++) { + final HealthStatsWriter writer = new HealthStatsWriter(PidHealthStats.CONSTANTS); + writePid(writer, pids.valueAt(i)); + uidWriter.addStats(UidHealthStats.STATS_PIDS, Integer.toString(pids.keyAt(i)), writer); + } + + // STATS_PROCESSES + for (final Map.Entry<String,? extends BatteryStats.Uid.Proc> entry: + uid.getProcessStats().entrySet()) { + final HealthStatsWriter writer = new HealthStatsWriter(ProcessHealthStats.CONSTANTS); + writeProc(writer, entry.getValue()); + uidWriter.addStats(UidHealthStats.STATS_PROCESSES, entry.getKey(), writer); + } + + // STATS_PACKAGES + for (final Map.Entry<String,? extends BatteryStats.Uid.Pkg> entry: + uid.getPackageStats().entrySet()) { + final HealthStatsWriter writer = new HealthStatsWriter(PackageHealthStats.CONSTANTS); + writePkg(writer, entry.getValue()); + uidWriter.addStats(UidHealthStats.STATS_PACKAGES, entry.getKey(), writer); + } + + controller = uid.getWifiControllerActivity(); + if (controller != null) { + // MEASUREMENT_WIFI_IDLE_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_IDLE_MS, + controller.getIdleTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED)); + // MEASUREMENT_WIFI_RX_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RX_MS, + controller.getRxTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED)); + // MEASUREMENT_WIFI_TX_MS + sum = 0; + for (final BatteryStats.LongCounter counter: controller.getTxTimeCounters()) { + sum += counter.getCountLocked(STATS_SINCE_UNPLUGGED); + } + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_TX_MS, sum); + // MEASUREMENT_WIFI_POWER_MAMS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_POWER_MAMS, + controller.getPowerCounter().getCountLocked(STATS_SINCE_UNPLUGGED)); + } + + controller = uid.getBluetoothControllerActivity(); + if (controller != null) { + // MEASUREMENT_BLUETOOTH_IDLE_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_IDLE_MS, + controller.getIdleTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED)); + // MEASUREMENT_BLUETOOTH_RX_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_RX_MS, + controller.getRxTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED)); + // MEASUREMENT_BLUETOOTH_TX_MS + sum = 0; + for (final BatteryStats.LongCounter counter: controller.getTxTimeCounters()) { + sum += counter.getCountLocked(STATS_SINCE_UNPLUGGED); + } + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_TX_MS, sum); + // MEASUREMENT_BLUETOOTH_POWER_MAMS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_POWER_MAMS, + controller.getPowerCounter().getCountLocked(STATS_SINCE_UNPLUGGED)); + } + + controller = uid.getModemControllerActivity(); + if (controller != null) { + // MEASUREMENT_MOBILE_IDLE_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_IDLE_MS, + controller.getIdleTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED)); + // MEASUREMENT_MOBILE_RX_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_RX_MS, + controller.getRxTimeCounter().getCountLocked(STATS_SINCE_UNPLUGGED)); + // MEASUREMENT_MOBILE_TX_MS + sum = 0; + for (final BatteryStats.LongCounter counter: controller.getTxTimeCounters()) { + sum += counter.getCountLocked(STATS_SINCE_UNPLUGGED); + } + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_TX_MS, sum); + // MEASUREMENT_MOBILE_POWER_MAMS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_POWER_MAMS, + controller.getPowerCounter().getCountLocked(STATS_SINCE_UNPLUGGED)); + } + + // MEASUREMENT_WIFI_RUNNING_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RUNNING_MS, + uid.getWifiRunningTime(mNowRealtime, STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_WIFI_FULL_LOCK_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_FULL_LOCK_MS, + uid.getFullWifiLockTime(mNowRealtime, STATS_SINCE_UNPLUGGED)); + + // TIMER_WIFI_SCAN + uidWriter.addTimer(UidHealthStats.TIMER_WIFI_SCAN, + uid.getWifiScanCount(STATS_SINCE_UNPLUGGED), + uid.getWifiScanTime(mNowRealtime, STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_WIFI_MULTICAST_MS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_MULTICAST_MS, + uid.getWifiMulticastTime(mNowRealtime, STATS_SINCE_UNPLUGGED)); + + // TIMER_AUDIO + addTimer(uidWriter, UidHealthStats.TIMER_AUDIO, uid.getAudioTurnedOnTimer()); + + // TIMER_VIDEO + addTimer(uidWriter, UidHealthStats.TIMER_VIDEO, uid.getVideoTurnedOnTimer()); + + // TIMER_FLASHLIGHT + addTimer(uidWriter, UidHealthStats.TIMER_FLASHLIGHT, uid.getFlashlightTurnedOnTimer()); + + // TIMER_CAMERA + addTimer(uidWriter, UidHealthStats.TIMER_CAMERA, uid.getCameraTurnedOnTimer()); + + // TIMER_FOREGROUND_ACTIVITY + addTimer(uidWriter, UidHealthStats.TIMER_FOREGROUND_ACTIVITY, uid.getForegroundActivityTimer()); + + // TIMER_BLUETOOTH_SCAN + addTimer(uidWriter, UidHealthStats.TIMER_BLUETOOTH_SCAN, uid.getBluetoothScanTimer()); + + // TIMER_PROCESS_STATE_TOP_MS + addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_TOP_MS, + uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_TOP)); + + // TIMER_PROCESS_STATE_FOREGROUND_SERVICE_MS + addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_FOREGROUND_SERVICE_MS, + uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_FOREGROUND_SERVICE)); + + // TIMER_PROCESS_STATE_TOP_SLEEPING_MS + addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_TOP_SLEEPING_MS, + uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_TOP_SLEEPING)); + + // TIMER_PROCESS_STATE_FOREGROUND_MS + addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_FOREGROUND_MS, + uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_FOREGROUND)); + + // TIMER_PROCESS_STATE_BACKGROUND_MS + addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_BACKGROUND_MS, + uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_BACKGROUND)); + + // TIMER_PROCESS_STATE_CACHED_MS + addTimer(uidWriter, UidHealthStats.TIMER_PROCESS_STATE_CACHED_MS, + uid.getProcessStateTimer(BatteryStats.Uid.PROCESS_STATE_CACHED)); + + // TIMER_VIBRATOR + addTimer(uidWriter, UidHealthStats.TIMER_VIBRATOR, uid.getVibratorOnTimer()); + + // MEASUREMENT_OTHER_USER_ACTIVITY_COUNT + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_OTHER_USER_ACTIVITY_COUNT, + uid.getUserActivityCount(PowerManager.USER_ACTIVITY_EVENT_OTHER, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BUTTON_USER_ACTIVITY_COUNT, + uid.getUserActivityCount(PowerManager.USER_ACTIVITY_EVENT_BUTTON, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_TOUCH_USER_ACTIVITY_COUNT, + uid.getUserActivityCount(PowerManager.USER_ACTIVITY_EVENT_TOUCH, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_MOBILE_RX_BYTES + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_RX_BYTES, + uid.getNetworkActivityBytes(BatteryStats.NETWORK_MOBILE_RX_DATA, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_MOBILE_TX_BYTES + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_TX_BYTES, + uid.getNetworkActivityBytes(BatteryStats.NETWORK_MOBILE_TX_DATA, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_WIFI_RX_BYTES + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RX_BYTES, + uid.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_RX_DATA, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_WIFI_TX_BYTES + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_TX_BYTES, + uid.getNetworkActivityBytes(BatteryStats.NETWORK_WIFI_TX_DATA, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_BLUETOOTH_RX_BYTES + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_RX_BYTES, + uid.getNetworkActivityBytes(BatteryStats.NETWORK_BT_RX_DATA, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_BLUETOOTH_TX_BYTES + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_TX_BYTES, + uid.getNetworkActivityBytes(BatteryStats.NETWORK_BT_TX_DATA, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_MOBILE_RX_PACKETS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_RX_PACKETS, + uid.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_RX_DATA, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_MOBILE_TX_PACKETS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_MOBILE_TX_PACKETS, + uid.getNetworkActivityPackets(BatteryStats.NETWORK_MOBILE_TX_DATA, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_WIFI_RX_PACKETS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_RX_PACKETS, + uid.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_RX_DATA, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_WIFI_TX_PACKETS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_WIFI_TX_PACKETS, + uid.getNetworkActivityPackets(BatteryStats.NETWORK_WIFI_TX_DATA, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_BLUETOOTH_RX_PACKETS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_RX_PACKETS, + uid.getNetworkActivityPackets(BatteryStats.NETWORK_BT_RX_DATA, + STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_BLUETOOTH_TX_PACKETS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_BLUETOOTH_TX_PACKETS, + uid.getNetworkActivityPackets(BatteryStats.NETWORK_BT_TX_DATA, + STATS_SINCE_UNPLUGGED)); + + // TIMER_MOBILE_RADIO_ACTIVE + uidWriter.addTimer(UidHealthStats.TIMER_MOBILE_RADIO_ACTIVE, + uid.getMobileRadioActiveCount(STATS_SINCE_UNPLUGGED), + uid.getMobileRadioActiveTime(STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_USER_CPU_TIME_US + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_USER_CPU_TIME_US, + uid.getUserCpuTimeUs(STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_SYSTEM_CPU_TIME_US + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_SYSTEM_CPU_TIME_US, + uid.getSystemCpuTimeUs(STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_CPU_POWER_MAUS + uidWriter.addMeasurement(UidHealthStats.MEASUREMENT_CPU_POWER_MAUS, + uid.getCpuPowerMaUs(STATS_SINCE_UNPLUGGED)); + } + + /** + * Writes the contents of a BatteryStats.Uid.Pid into a HealthStatsWriter. + */ + public void writePid(HealthStatsWriter pidWriter, BatteryStats.Uid.Pid pid) { + if (pid == null) { + return; + } + + // MEASUREMENT_WAKE_NESTING_COUNT + pidWriter.addMeasurement(PidHealthStats.MEASUREMENT_WAKE_NESTING_COUNT, pid.mWakeNesting); + + // MEASUREMENT_WAKE_SUM_MS + pidWriter.addMeasurement(PidHealthStats.MEASUREMENT_WAKE_SUM_MS, pid.mWakeSumMs); + + // MEASUREMENT_WAKE_START_MS + pidWriter.addMeasurement(PidHealthStats.MEASUREMENT_WAKE_SUM_MS, pid.mWakeStartMs); + } + + /** + * Writes the contents of a BatteryStats.Uid.Proc into a HealthStatsWriter. + */ + public void writeProc(HealthStatsWriter procWriter, BatteryStats.Uid.Proc proc) { + // MEASUREMENT_USER_TIME_MS + procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_USER_TIME_MS, + proc.getUserTime(STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_SYSTEM_TIME_MS + procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_SYSTEM_TIME_MS, + proc.getSystemTime(STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_STARTS_COUNT + procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_STARTS_COUNT, + proc.getStarts(STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_CRASHES_COUNT + procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_CRASHES_COUNT, + proc.getNumCrashes(STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_ANR_COUNT + procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_ANR_COUNT, + proc.getNumAnrs(STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_FOREGROUND_MS + procWriter.addMeasurement(ProcessHealthStats.MEASUREMENT_FOREGROUND_MS, + proc.getForegroundTime(STATS_SINCE_UNPLUGGED)); + } + + /** + * Writes the contents of a BatteryStats.Uid.Pkg into a HealthStatsWriter. + */ + public void writePkg(HealthStatsWriter pkgWriter, BatteryStats.Uid.Pkg pkg) { + // STATS_SERVICES + for (final Map.Entry<String,? extends BatteryStats.Uid.Pkg.Serv> entry: + pkg.getServiceStats().entrySet()) { + final HealthStatsWriter writer = new HealthStatsWriter(ServiceHealthStats.CONSTANTS); + writeServ(writer, entry.getValue()); + pkgWriter.addStats(PackageHealthStats.STATS_SERVICES, entry.getKey(), writer); + } + + // MEASUREMENTS_WAKEUP_ALARMS_COUNT + for (final Map.Entry<String,? extends BatteryStats.Counter> entry: + pkg.getWakeupAlarmStats().entrySet()) { + final BatteryStats.Counter counter = entry.getValue(); + if (counter != null) { + pkgWriter.addMeasurements(PackageHealthStats.MEASUREMENTS_WAKEUP_ALARMS_COUNT, + entry.getKey(), counter.getCountLocked(STATS_SINCE_UNPLUGGED)); + } + } + } + + /** + * Writes the contents of a BatteryStats.Uid.Pkg.Serv into a HealthStatsWriter. + */ + public void writeServ(HealthStatsWriter servWriter, BatteryStats.Uid.Pkg.Serv serv) { + // MEASUREMENT_START_SERVICE_COUNT + servWriter.addMeasurement(ServiceHealthStats.MEASUREMENT_START_SERVICE_COUNT, + serv.getStarts(STATS_SINCE_UNPLUGGED)); + + // MEASUREMENT_LAUNCH_COUNT + servWriter.addMeasurement(ServiceHealthStats.MEASUREMENT_LAUNCH_COUNT, + serv.getLaunches(STATS_SINCE_UNPLUGGED)); + } + + /** + * Adds a BatteryStats.Timer into a HealthStatsWriter. Safe to pass a null timer. + */ + private void addTimer(HealthStatsWriter writer, int key, BatteryStats.Timer timer) { + if (timer != null) { + writer.addTimer(key, timer.getCountLocked(STATS_SINCE_UNPLUGGED), + timer.getTotalTimeLocked(mNowRealtime, STATS_SINCE_UNPLUGGED)); + } + } + + /** + * Adds a named BatteryStats.Timer into a HealthStatsWriter. Safe to pass a null timer. + */ + private void addTimers(HealthStatsWriter writer, int key, String name, + BatteryStats.Timer timer) { + if (timer != null) { + writer.addTimers(key, name, new TimerStat(timer.getCountLocked(STATS_SINCE_UNPLUGGED), + timer.getTotalTimeLocked(mNowRealtime, STATS_SINCE_UNPLUGGED))); + } + } +} + diff --git a/services/core/java/com/android/server/am/InstrumentationReporter.java b/services/core/java/com/android/server/am/InstrumentationReporter.java new file mode 100644 index 000000000000..fdbb73e9fa0e --- /dev/null +++ b/services/core/java/com/android/server/am/InstrumentationReporter.java @@ -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. + */ + +package com.android.server.am; + +import android.app.IInstrumentationWatcher; +import android.content.ComponentName; +import android.os.Bundle; +import android.os.Process; +import android.os.RemoteException; +import android.util.Slog; + +import java.util.ArrayList; + +public class InstrumentationReporter { + static final boolean DEBUG = false; + static final String TAG = ActivityManagerDebugConfig.TAG_AM; + + static final int REPORT_TYPE_STATUS = 0; + static final int REPORT_TYPE_FINISHED = 1; + + final Object mLock = new Object(); + ArrayList<Report> mPendingReports; + Thread mThread; + + final class MyThread extends Thread { + public MyThread() { + super("InstrumentationReporter"); + if (DEBUG) Slog.d(TAG, "Starting InstrumentationReporter: " + this); + } + + @Override + public void run() { + Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT); + boolean waited = false; + while (true) { + ArrayList<Report> reports; + synchronized (mLock) { + reports = mPendingReports; + mPendingReports = null; + if (reports == null || reports.isEmpty()) { + if (!waited) { + // Sleep for a little bit, to avoid thrashing through threads. + try { + mLock.wait(10000); // 10 seconds + } catch (InterruptedException e) { + } + waited = true; + continue; + } else { + mThread = null; + if (DEBUG) Slog.d(TAG, "Exiting InstrumentationReporter: " + this); + return; + } + } + } + + waited = false; + + for (int i=0; i<reports.size(); i++) { + final Report rep = reports.get(i); + try { + if (rep.mType == REPORT_TYPE_STATUS) { + if (DEBUG) Slog.d(TAG, "Dispatch status to " + rep.mWatcher + + ": " + rep.mName.flattenToShortString() + + " code=" + rep.mResultCode + " result=" + rep.mResults); + rep.mWatcher.instrumentationStatus(rep.mName, rep.mResultCode, + rep.mResults); + } else { + if (DEBUG) Slog.d(TAG, "Dispatch finished to " + rep.mWatcher + + ": " + rep.mName.flattenToShortString() + + " code=" + rep.mResultCode + " result=" + rep.mResults); + rep.mWatcher.instrumentationFinished(rep.mName, rep.mResultCode, + rep.mResults); + } + } catch (RemoteException e) { + Slog.i(TAG, "Failure reporting to instrumentation watcher: comp=" + + rep.mName + " results=" + rep.mResults); + } + } + } + } + } + + final class Report { + final int mType; + final IInstrumentationWatcher mWatcher; + final ComponentName mName; + final int mResultCode; + final Bundle mResults; + + Report(int type, IInstrumentationWatcher watcher, ComponentName name, int resultCode, + Bundle results) { + mType = type; + mWatcher = watcher; + mName = name; + mResultCode = resultCode; + mResults = results; + } + } + + public void reportStatus(IInstrumentationWatcher watcher, ComponentName name, int resultCode, + Bundle results) { + if (DEBUG) Slog.d(TAG, "Report status to " + watcher + + ": " + name.flattenToShortString() + + " code=" + resultCode + " result=" + results); + report(new Report(REPORT_TYPE_STATUS, watcher, name, resultCode, results)); + } + + public void reportFinished(IInstrumentationWatcher watcher, ComponentName name, int resultCode, + Bundle results) { + if (DEBUG) Slog.d(TAG, "Report finished to " + watcher + + ": " + name.flattenToShortString() + + " code=" + resultCode + " result=" + results); + report(new Report(REPORT_TYPE_FINISHED, watcher, name, resultCode, results)); + } + + private void report(Report report) { + synchronized (mLock) { + if (mThread == null) { + mThread = new MyThread(); + mThread.start(); + } + if (mPendingReports == null) { + mPendingReports = new ArrayList<>(); + } + mPendingReports.add(report); + mLock.notifyAll(); + } + } +} diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java index ea85fa1de464..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; } @@ -1334,8 +1342,13 @@ final class TaskRecord { if (bounds == null) { return; } - final int minimalSize = mMinimalSize == -1 - ? mService.mStackSupervisor.mDefaultMinimalSizeOfResizeableTask : mMinimalSize; + int minimalSize = mMinimalSize; + // If the task has no requested minimal size, we'd like to enforce a minimal size + // so that the user can not render the task too small to manipulate. We don't need + // to do this for the pinned stack as the bounds are controlled by the system. + if (minimalSize == -1 && stack.mStackId != PINNED_STACK_ID) { + minimalSize = mService.mStackSupervisor.mDefaultMinimalSizeOfResizeableTask; + } final boolean adjustWidth = minimalSize > bounds.width(); final boolean adjustHeight = minimalSize > bounds.height(); if (!(adjustWidth || adjustHeight)) { diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 4a5df7a42f25..59c2682bdb0f 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -584,7 +584,7 @@ final class UserController { } } else { Slog.w(TAG, "Mount service not published; guessing locked state based on property"); - return !StorageManager.isFileBasedEncryptionEnabled(); + return !StorageManager.isFileEncryptedNativeOrEmulated(); } } 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/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java index f231f922a0e6..3b0b79a771ef 100644 --- a/services/core/java/com/android/server/connectivity/Vpn.java +++ b/services/core/java/com/android/server/connectivity/Vpn.java @@ -718,7 +718,8 @@ public class Vpn { public void onUserAdded(int userHandle) { // If the user is restricted tie them to the parent user's VPN UserInfo user = UserManager.get(mContext).getUserInfo(userHandle); - if (user.isRestricted() && user.restrictedProfileParentId == mUserHandle) { + if (user.isRestricted() && user.restrictedProfileParentId == mUserHandle + && mVpnUsers != null) { synchronized(Vpn.this) { try { addVpnUserLocked(userHandle); @@ -736,7 +737,8 @@ public class Vpn { public void onUserRemoved(int userHandle) { // clean up if restricted UserInfo user = UserManager.get(mContext).getUserInfo(userHandle); - if (user.isRestricted() && user.restrictedProfileParentId == mUserHandle) { + if (user.isRestricted() && user.restrictedProfileParentId == mUserHandle + && mVpnUsers != null) { synchronized(Vpn.this) { try { removeVpnUserLocked(userHandle); diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java index 95a98751c7d0..e1d208eb19fd 100644 --- a/services/core/java/com/android/server/content/SyncManager.java +++ b/services/core/java/com/android/server/content/SyncManager.java @@ -192,6 +192,13 @@ public class SyncManager { */ private static final long SYNC_DELAY_ON_CONFLICT = 10*1000; // 10 seconds + /** + * Generate job ids in the range [MIN_SYNC_JOB_ID, MAX_SYNC_JOB_ID) to avoid conflicts with + * other jobs scheduled by the system process. + */ + private static final int MIN_SYNC_JOB_ID = 100000; + private static final int MAX_SYNC_JOB_ID = 110000; + private static final String SYNC_WAKE_LOCK_PREFIX = "*sync*/"; private static final String HANDLE_SYNC_ALARM_WAKE_LOCK = "SyncManagerHandleSyncAlarm"; private static final String SYNC_LOOP_WAKE_LOCK = "SyncLoopWakeLock"; @@ -249,7 +256,7 @@ public class SyncManager { synchronized (mScheduledSyncs) { int newJobId; do { - newJobId = mRand.nextInt(Integer.MAX_VALUE); + newJobId = MIN_SYNC_JOB_ID + mRand.nextInt(MAX_SYNC_JOB_ID - MIN_SYNC_JOB_ID); } while (isJobIdInUseLockedH(newJobId)); return newJobId; } diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java b/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java index a626b5b33012..9cfb590c9234 100644 --- a/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java +++ b/services/core/java/com/android/server/net/NetworkPolicyManagerShellCommand.java @@ -24,6 +24,7 @@ import static com.android.server.net.NetworkPolicyManagerService.TAG; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -364,9 +365,12 @@ class NetworkPolicyManagerShellCommand extends ShellCommand { private List<NetworkPolicy> getWifiPolicies() throws RemoteException { // First gets a list of saved wi-fi networks. final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks(); - final Set<String> ssids = new HashSet<>(configs.size()); - for (WifiConfiguration config : configs) { - ssids.add(removeDoubleQuotes(config.SSID)); + final int size = configs != null ? configs.size() : 0; + final Set<String> ssids = new HashSet<>(size); + if (configs != null) { + for (WifiConfiguration config : configs) { + ssids.add(removeDoubleQuotes(config.SSID)); + } } // Then gets the saved policies. diff --git a/services/core/java/com/android/server/notification/EventConditionProvider.java b/services/core/java/com/android/server/notification/EventConditionProvider.java index ab3cb8326b29..b13fec19cc66 100644 --- a/services/core/java/com/android/server/notification/EventConditionProvider.java +++ b/services/core/java/com/android/server/notification/EventConditionProvider.java @@ -26,7 +26,9 @@ import android.content.IntentFilter; import android.content.pm.PackageManager.NameNotFoundException; import android.net.Uri; import android.os.Handler; +import android.os.HandlerThread; import android.os.Looper; +import android.os.Process; import android.os.UserHandle; import android.os.UserManager; import android.service.notification.Condition; @@ -63,15 +65,18 @@ public class EventConditionProvider extends SystemConditionProviderService { private final ArraySet<Uri> mSubscriptions = new ArraySet<Uri>(); private final SparseArray<CalendarTracker> mTrackers = new SparseArray<>(); private final Handler mWorker; + private final HandlerThread mThread; private boolean mConnected; private boolean mRegistered; private boolean mBootComplete; // don't hammer the calendar provider until boot completes. private long mNextAlarmTime; - public EventConditionProvider(Looper worker) { + public EventConditionProvider() { if (DEBUG) Slog.d(TAG, "new " + SIMPLE_NAME + "()"); - mWorker = new Handler(worker); + mThread = new HandlerThread(TAG, Process.THREAD_PRIORITY_BACKGROUND); + mThread.start(); + mWorker = new Handler(mThread.getLooper()); } @Override diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index 17313b685ae9..6cf3940e004c 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -328,12 +328,16 @@ abstract public class ManagedServices { component.flattenToShortString()); } - final int[] userIds = mUserProfiles.getCurrentProfileIds(); - for (int userId : userIds) { - if (enabled) { - registerServiceLocked(component, userId); - } else { - unregisterServiceLocked(component, userId); + + synchronized (mMutex) { + final int[] userIds = mUserProfiles.getCurrentProfileIds(); + + for (int userId : userIds) { + if (enabled) { + registerServiceLocked(component, userId); + } else { + unregisterServiceLocked(component, userId); + } } } } @@ -453,7 +457,7 @@ abstract public class ManagedServices { return queryPackageForServices(packageName, userId, null); } - protected Set<ComponentName> queryPackageForServices(String packageName, int userId, + public Set<ComponentName> queryPackageForServices(String packageName, int userId, String category) { Set<ComponentName> installed = new ArraySet<>(); final PackageManager pm = mContext.getPackageManager(); @@ -636,7 +640,21 @@ abstract public class ManagedServices { } } + /** + * Inject a system service into the management list. + */ + public void registerSystemService(final ComponentName name, final int userid) { + synchronized (mMutex) { + registerServiceLocked(name, userid, true /* isSystem */); + } + } + private void registerServiceLocked(final ComponentName name, final int userid) { + registerServiceLocked(name, userid, false /* isSystem */); + } + + private void registerServiceLocked(final ComponentName name, final int userid, + final boolean isSystem) { if (DEBUG) Slog.v(TAG, "registerService: " + name + " u=" + userid); final String servicesBindingTag = name.toString() + "/" + userid; @@ -694,7 +712,7 @@ abstract public class ManagedServices { try { mService = asInterface(binder); info = newServiceInfo(mService, name, - userid, false /*isSystem*/, this, targetSdkVersion); + userid, isSystem, this, targetSdkVersion); binder.linkToDeath(info, 0); added = mServices.add(info); } catch (RemoteException e) { @@ -890,6 +908,7 @@ abstract public class ManagedServices { return false; } if (this.userid == UserHandle.USER_ALL) return true; + if (this.userid == UserHandle.USER_SYSTEM) return true; if (nid == UserHandle.USER_ALL || nid == this.userid) return true; return supportsProfiles() && mUserProfiles.isCurrentProfile(nid); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 24ffe1fcae4b..516602e55e5c 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -160,6 +160,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map.Entry; import java.util.Objects; +import java.util.Set; import java.util.concurrent.TimeUnit; /** {@hide} */ @@ -212,6 +213,7 @@ public class NotificationManagerService extends SystemService { /** notification_enqueue status value for an ignored notification. */ private static final int EVENTLOG_ENQUEUE_STATUS_IGNORED = 2; + private String mRankerServicePackageName; private IActivityManager mAm; AudioManager mAudioManager; @@ -289,7 +291,7 @@ public class NotificationManagerService extends SystemService { private final UserProfiles mUserProfiles = new UserProfiles(); private NotificationListeners mListeners; - private NotificationRanker mRankerServices; + private NotificationRankers mRankerServices; private ConditionProviders mConditionProviders; private NotificationUsageStats mUsageStats; @@ -887,6 +889,10 @@ public class NotificationManagerService extends SystemService { mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE); mAppUsageStats = LocalServices.getService(UsageStatsManagerInternal.class); + // This is the package that contains the AOSP framework update. + mRankerServicePackageName = getContext().getPackageManager() + .getServicesSystemSharedLibraryPackageName(); + mHandler = new WorkerHandler(); mRankingThread.start(); String[] extractorNames; @@ -931,8 +937,26 @@ public class NotificationManagerService extends SystemService { importOldBlockDb(); + // This is a MangedServices object that keeps track of the listeners. mListeners = new NotificationListeners(); - mRankerServices = new NotificationRanker(); + + // This is a MangedServices object that keeps track of the ranker. + mRankerServices = new NotificationRankers(); + // Find the updatable ranker and register it. + Set<ComponentName> rankerComponents = mRankerServices.queryPackageForServices( + mRankerServicePackageName, UserHandle.USER_SYSTEM, null); + Iterator<ComponentName> iterator = rankerComponents.iterator(); + if (iterator.hasNext()) { + ComponentName rankerComponent = iterator.next(); + if (iterator.hasNext()) { + Slog.e(TAG, "found multiple ranker services:" + rankerComponents); + } else { + mRankerServices.registerSystemService(rankerComponent, UserHandle.USER_SYSTEM); + } + } else { + Slog.w(TAG, "could not start ranker service: none found"); + } + mStatusBar = getLocalService(StatusBarManagerInternal.class); mStatusBar.setNotificationDelegate(mNotificationDelegate); @@ -1410,13 +1434,9 @@ public class NotificationManagerService extends SystemService { */ @Override public void registerListener(final INotificationListener listener, - final ComponentName component, final int userid, boolean asRanker) { + final ComponentName component, final int userid) { enforceSystemOrSystemUI("INotificationManager.registerListener"); - if (asRanker) { - mRankerServices.registerService(listener, component, userid); - } else { - mListeners.registerService(listener, component, userid); - } + mListeners.registerService(listener, component, userid); } /** @@ -1424,16 +1444,7 @@ public class NotificationManagerService extends SystemService { */ @Override public void unregisterListener(INotificationListener token, int userid) { - final long identity = Binder.clearCallingIdentity(); - try { - if(mRankerServices.checkServiceTokenLocked(token) != null) { - mRankerServices.unregisterService(token, userid); - } else { - mListeners.unregisterService(token, userid); - } - } finally { - Binder.restoreCallingIdentity(identity); - } + mListeners.unregisterService(token, userid); } /** @@ -2138,6 +2149,7 @@ public class NotificationManagerService extends SystemService { pw.print(listener.component); } pw.println(')'); + pw.println("\n mRankerServicePackageName: " + mRankerServicePackageName); pw.println("\n Notification ranker services:"); mRankerServices.dump(pw, filter); } @@ -3485,9 +3497,9 @@ public class NotificationManagerService extends SystemService { } } - public class NotificationRanker extends ManagedServices { + public class NotificationRankers extends ManagedServices { - public NotificationRanker() { + public NotificationRankers() { super(getContext(), mHandler, mNotificationList, mUserProfiles); } @@ -3530,7 +3542,7 @@ public class NotificationManagerService extends SystemService { // mServices is the list inside ManagedServices of all the rankers, // There should be only one, but it's a list, so while we enforce // singularity elsewhere, we keep it general here, to avoid surprises. - for (final ManagedServiceInfo info : NotificationRanker.this.mServices) { + for (final ManagedServiceInfo info : NotificationRankers.this.mServices) { boolean sbnVisible = isVisibleToListener(sbn, info); if (!sbnVisible) { continue; diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java index 9cdece525bb3..0945065d62f7 100644 --- a/services/core/java/com/android/server/notification/ZenModeConditions.java +++ b/services/core/java/com/android/server/notification/ZenModeConditions.java @@ -50,7 +50,7 @@ public class ZenModeConditions implements ConditionProviders.Callback { mConditionProviders.addSystemProvider(new ScheduleConditionProvider()); } if (mConditionProviders.isSystemProviderEnabled(ZenModeConfig.EVENT_PATH)) { - mConditionProviders.addSystemProvider(new EventConditionProvider(helper.getLooper())); + mConditionProviders.addSystemProvider(new EventConditionProvider()); } mConditionProviders.setCallback(this); } diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java index 56128708599b..b7cd3185a228 100644 --- a/services/core/java/com/android/server/pm/LauncherAppsService.java +++ b/services/core/java/com/android/server/pm/LauncherAppsService.java @@ -42,6 +42,7 @@ import android.net.Uri; import android.os.Binder; import android.os.Bundle; import android.os.IInterface; +import android.os.ParcelFileDescriptor; import android.os.RemoteCallbackList; import android.os.RemoteException; import android.os.UserHandle; @@ -50,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; @@ -75,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"; @@ -166,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(); @@ -186,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); } @@ -329,6 +335,26 @@ public class LauncherAppsService extends SystemService { } @Override + public int getShortcutIconResId(String callingPackage, ShortcutInfo shortcut, + UserHandle user) { + enforceShortcutPermission(user); + verifyCallingPackage(callingPackage); + + return mShortcutServiceInternal.getShortcutIconResId(callingPackage, shortcut, + user.getIdentifier()); + } + + @Override + public ParcelFileDescriptor getShortcutIconFd(String callingPackage, ShortcutInfo shortcut, + UserHandle user) { + enforceShortcutPermission(user); + verifyCallingPackage(callingPackage); + + return mShortcutServiceInternal.getShortcutIconFd(callingPackage, shortcut, + user.getIdentifier()); + } + + @Override public boolean startShortcut(String callingPackage, String packageName, String shortcutId, Rect sourceBounds, Bundle startActivityOptions, UserHandle user) throws RemoteException { diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java index b84ffa39a803..ef53905d55bb 100644 --- a/services/core/java/com/android/server/pm/PackageInstallerSession.java +++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java @@ -34,6 +34,7 @@ import android.content.IntentSender; import android.content.pm.ApplicationInfo; import android.content.pm.IPackageInstallObserver2; import android.content.pm.IPackageInstallerSession; +import android.content.pm.PackageInfo; import android.content.pm.PackageInstaller; import android.content.pm.PackageInstaller.SessionInfo; import android.content.pm.PackageInstaller.SessionParams; @@ -58,6 +59,7 @@ import android.system.ErrnoException; import android.system.Os; import android.system.OsConstants; import android.system.StructStat; +import android.text.TextUtils; import android.util.ArraySet; import android.util.ExceptionUtils; import android.util.MathUtils; @@ -77,6 +79,7 @@ import com.android.server.pm.PackageInstallerService.PackageInstallObserverAdapt import java.io.File; import java.io.FileDescriptor; +import java.io.FileFilter; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; @@ -86,6 +89,7 @@ import java.util.concurrent.atomic.AtomicInteger; public class PackageInstallerSession extends IPackageInstallerSession.Stub { private static final String TAG = "PackageInstaller"; private static final boolean LOGD = true; + private static final String REMOVE_SPLIT_MARKER_EXTENSION = ".removed"; private static final int MSG_COMMIT = 0; @@ -171,6 +175,25 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { @GuardedBy("mLock") private File mInheritedFilesBase; + private static final FileFilter sAddedFilter = new FileFilter() { + @Override + public boolean accept(File file) { + // Installers can't stage directories, so it's fine to ignore + // entries like "lost+found". + if (file.isDirectory()) return false; + if (file.getName().endsWith(REMOVE_SPLIT_MARKER_EXTENSION)) return false; + return true; + } + }; + private static final FileFilter sRemovedFilter = new FileFilter() { + @Override + public boolean accept(File file) { + if (file.isDirectory()) return false; + if (!file.getName().endsWith(REMOVE_SPLIT_MARKER_EXTENSION)) return false; + return true; + } + }; + private final Handler.Callback mHandlerCallback = new Handler.Callback() { @Override public boolean handleMessage(Message msg) { @@ -346,6 +369,32 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } @Override + public void removeSplit(String splitName) { + if (TextUtils.isEmpty(params.appPackageName)) { + throw new IllegalStateException("Must specify package name to remove a split"); + } + try { + createRemoveSplitMarker(splitName); + } catch (IOException e) { + throw ExceptionUtils.wrap(e); + } + } + + private void createRemoveSplitMarker(String splitName) throws IOException { + try { + final String markerName = splitName + REMOVE_SPLIT_MARKER_EXTENSION; + if (!FileUtils.isValidExtFilename(markerName)) { + throw new IllegalArgumentException("Invalid marker: " + markerName); + } + final File target = new File(resolveStageDir(), markerName); + target.createNewFile(); + Os.chmod(target.getAbsolutePath(), 0 /*mode*/); + } catch (ErrnoException e) { + throw e.rethrowAsIOException(); + } + } + + @Override public ParcelFileDescriptor openWrite(String name, long offsetBytes, long lengthBytes) { try { return openWriteInternal(name, offsetBytes, lengthBytes); @@ -608,22 +657,28 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mResolvedStagedFiles.clear(); mResolvedInheritedFiles.clear(); - final File[] files = mResolvedStageDir.listFiles(); - if (ArrayUtils.isEmpty(files)) { - throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged"); + final File[] removedFiles = mResolvedStageDir.listFiles(sRemovedFilter); + final List<String> removeSplitList = new ArrayList<>(); + if (!ArrayUtils.isEmpty(removedFiles)) { + for (File removedFile : removedFiles) { + final String fileName = removedFile.getName(); + final String splitName = fileName.substring( + 0, fileName.length() - REMOVE_SPLIT_MARKER_EXTENSION.length()); + removeSplitList.add(splitName); + } } + final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter); + if (ArrayUtils.isEmpty(addedFiles) && removeSplitList.size() == 0) { + throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged"); + } // Verify that all staged packages are internally consistent final ArraySet<String> stagedSplits = new ArraySet<>(); - for (File file : files) { - - // Installers can't stage directories, so it's fine to ignore - // entries like "lost+found". - if (file.isDirectory()) continue; - + for (File addedFile : addedFiles) { final ApkLite apk; try { - apk = PackageParser.parseApkLite(file, PackageParser.PARSE_COLLECT_CERTIFICATES); + apk = PackageParser.parseApkLite( + addedFile, PackageParser.PARSE_COLLECT_CERTIFICATES); } catch (PackageParserException e) { throw PackageManagerException.from(e); } @@ -642,7 +697,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mSignatures = apk.signatures; } - assertApkConsistent(String.valueOf(file), apk); + assertApkConsistent(String.valueOf(addedFile), apk); // Take this opportunity to enforce uniform naming final String targetName; @@ -657,8 +712,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { } final File targetFile = new File(mResolvedStageDir, targetName); - if (!file.equals(targetFile)) { - file.renameTo(targetFile); + if (!addedFile.equals(targetFile)) { + addedFile.renameTo(targetFile); } // Base is coming from session @@ -669,6 +724,27 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { mResolvedStagedFiles.add(targetFile); } + if (removeSplitList.size() > 0) { + // validate split names marked for removal + final int flags = mSignatures == null ? PackageManager.GET_SIGNATURES : 0; + final PackageInfo pkg = mPm.getPackageInfo(params.appPackageName, flags, userId); + for (String splitName : removeSplitList) { + if (!ArrayUtils.contains(pkg.splitNames, splitName)) { + throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, + "Split not found: " + splitName); + } + } + + // ensure we've got appropriate package name, version code and signatures + if (mPackageName == null) { + mPackageName = pkg.packageName; + mVersionCode = pkg.versionCode; + } + if (mSignatures == null) { + mSignatures = pkg.signatures; + } + } + if (params.mode == SessionParams.MODE_FULL_INSTALL) { // Full installs must include a base package if (!stagedSplits.contains(null)) { @@ -707,8 +783,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { for (int i = 0; i < existing.splitNames.length; i++) { final String splitName = existing.splitNames[i]; final File splitFile = new File(existing.splitCodePaths[i]); - - if (!stagedSplits.contains(splitName)) { + final boolean splitRemoved = removeSplitList.contains(splitName); + if (!stagedSplits.contains(splitName) && !splitRemoved) { mResolvedInheritedFiles.add(splitFile); } } @@ -748,6 +824,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag + " package " + apk.packageName + " inconsistent with " + mPackageName); } + if (params.appPackageName != null && !params.appPackageName.equals(apk.packageName)) { + throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag + + " specified package " + params.appPackageName + + " inconsistent with " + apk.packageName); + } if (mVersionCode != apk.versionCode) { throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, tag + " version code " + apk.versionCode + " inconsistent with " diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index e180e0501d98..debe072b7b98 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -2449,7 +2449,7 @@ public class PackageManagerService extends IPackageManager.Stub { // since core system apps like SettingsProvider and SystemUI // can't wait for user to start final int storageFlags; - if (StorageManager.isFileBasedEncryptionEnabled()) { + if (StorageManager.isFileEncryptedNativeOrEmulated()) { storageFlags = StorageManager.FLAG_STORAGE_DE; } else { storageFlags = StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE; @@ -3231,7 +3231,7 @@ public class PackageManagerService extends IPackageManager.Stub { * Return if the user key is currently unlocked. */ private boolean isUserKeyUnlocked(int userId) { - if (StorageManager.isFileBasedEncryptionEnabled()) { + if (StorageManager.isFileEncryptedNativeOrEmulated()) { final IMountService mount = IMountService.Stub .asInterface(ServiceManager.getService("mount")); if (mount == null) { @@ -18313,7 +18313,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); * the app. */ private boolean maybeMigrateAppData(String volumeUuid, int userId, PackageParser.Package pkg) { - if (pkg.isSystemApp() && !StorageManager.isFileBasedEncryptionEnabled() + if (pkg.isSystemApp() && !StorageManager.isFileEncryptedNativeOrEmulated() && PackageManager.APPLY_FORCE_DEVICE_ENCRYPTED) { final int storageTarget = pkg.applicationInfo.isForceDeviceEncrypted() ? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE; diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java index 28d34a84250f..d77168c505f7 100644 --- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java +++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java @@ -95,6 +95,8 @@ class PackageManagerShellCommand extends ShellCommand { return runInstallCommit(); case "install-create": return runInstallCreate(); + case "install-remove": + return runInstallRemove(); case "install-write": return runInstallWrite(); case "compile": @@ -136,11 +138,12 @@ class PackageManagerShellCommand extends ShellCommand { pw.println("Error: must either specify a package size or an APK file"); return 1; } - if (doWriteSession(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk", + if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk", false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) { return 1; } - if (doCommitSession(sessionId, false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) { + if (doCommitSession(sessionId, false /*logSuccess*/) + != PackageInstaller.STATUS_SUCCESS) { return 1; } abandonSession = false; @@ -225,7 +228,20 @@ class PackageManagerShellCommand extends ShellCommand { final int sessionId = Integer.parseInt(getNextArg()); final String splitName = getNextArg(); final String path = getNextArg(); - return doWriteSession(sessionId, path, sizeBytes, splitName, true /*logSuccess*/); + return doWriteSplit(sessionId, path, sizeBytes, splitName, true /*logSuccess*/); + } + + private int runInstallRemove() throws RemoteException { + final PrintWriter pw = getOutPrintWriter(); + + final int sessionId = Integer.parseInt(getNextArg()); + + final String splitName = getNextArg(); + if (splitName == null) { + pw.println("Error: split name not specified"); + return 1; + } + return doRemoveSplit(sessionId, splitName, true /*logSuccess*/); } private int runCompile() throws RemoteException { @@ -666,12 +682,18 @@ class PackageManagerShellCommand extends ShellCommand { } } - String packageName = getNextArg(); + final String packageName = getNextArg(); if (packageName == null) { pw.println("Error: package name not specified"); return 1; } + // if a split is specified, just remove it and not the whole package + final String splitName = getNextArg(); + if (splitName != null) { + return runRemoveSplit(packageName, splitName); + } + userId = translateUserId(userId, "runUninstall"); if (userId == UserHandle.USER_ALL) { userId = UserHandle.USER_SYSTEM; @@ -709,6 +731,36 @@ class PackageManagerShellCommand extends ShellCommand { } } + private int runRemoveSplit(String packageName, String splitName) throws RemoteException { + final PrintWriter pw = getOutPrintWriter(); + final SessionParams sessionParams = new SessionParams(SessionParams.MODE_INHERIT_EXISTING); + sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING; + sessionParams.appPackageName = packageName; + final int sessionId = + doCreateSession(sessionParams, null /*installerPackageName*/, UserHandle.USER_ALL); + boolean abandonSession = true; + try { + if (doRemoveSplit(sessionId, splitName, false /*logSuccess*/) + != PackageInstaller.STATUS_SUCCESS) { + return 1; + } + if (doCommitSession(sessionId, false /*logSuccess*/) + != PackageInstaller.STATUS_SUCCESS) { + return 1; + } + abandonSession = false; + pw.println("Success"); + return 0; + } finally { + if (abandonSession) { + try { + doAbandonSession(sessionId, false /*logSuccess*/); + } catch (Exception ignore) { + } + } + } + } + private Intent parseIntentAndUser() throws URISyntaxException { mTargetUser = UserHandle.USER_CURRENT; Intent intent = Intent.parseCommandArgs(this, new Intent.CommandOptionHandler() { @@ -948,7 +1000,7 @@ class PackageManagerShellCommand extends ShellCommand { return sessionId; } - private int doWriteSession(int sessionId, String inPath, long sizeBytes, String splitName, + private int doWriteSplit(int sessionId, String inPath, long sizeBytes, String splitName, boolean logSuccess) throws RemoteException { final PrintWriter pw = getOutPrintWriter(); if ("-".equals(inPath)) { @@ -1004,6 +1056,27 @@ class PackageManagerShellCommand extends ShellCommand { } } + private int doRemoveSplit(int sessionId, String splitName, boolean logSuccess) + throws RemoteException { + final PrintWriter pw = getOutPrintWriter(); + PackageInstaller.Session session = null; + try { + session = new PackageInstaller.Session( + mInterface.getPackageInstaller().openSession(sessionId)); + session.removeSplit(splitName); + + if (logSuccess) { + pw.println("Success"); + } + return 0; + } catch (IOException e) { + pw.println("Error: failed to remove split; " + e.getMessage()); + return 1; + } finally { + IoUtils.closeQuietly(session); + } + } + private int doCommitSession(int sessionId, boolean logSuccess) throws RemoteException { final PrintWriter pw = getOutPrintWriter(); PackageInstaller.Session session = null; 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 423767ad87b4..0b0f7abbce4e 100644 --- a/services/core/java/com/android/server/pm/ShortcutService.java +++ b/services/core/java/com/android/server/pm/ShortcutService.java @@ -18,7 +18,9 @@ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; +import android.app.ActivityManager; import android.content.ComponentName; +import android.content.ContentProvider; import android.content.Context; import android.content.Intent; import android.content.pm.IShortcutService; @@ -30,24 +32,34 @@ import android.content.pm.ParceledListSlice; import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutServiceInternal; import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener; +import android.graphics.Bitmap; +import android.graphics.Bitmap.CompressFormat; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.RectF; import android.graphics.drawable.Icon; +import android.net.Uri; import android.os.Binder; -import android.os.Bundle; import android.os.Environment; import android.os.Handler; +import android.os.ParcelFileDescriptor; import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; +import android.os.SELinux; import android.os.ShellCommand; import android.os.UserHandle; import android.text.TextUtils; +import android.text.format.Formatter; import android.text.format.Time; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; +import android.util.KeyValueListParser; import android.util.Slog; import android.util.SparseArray; +import android.util.TypedValue; import android.util.Xml; import com.android.internal.annotations.GuardedBy; @@ -70,264 +82,175 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; import java.io.PrintWriter; 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; /** * TODO: - * - Make save async * - * - Add Bitmap support - * - * - Implement updateShortcuts + * - Detect when already registered instances are passed to APIs again, which might break + * internal bitmap handling. * * - Listen to PACKAGE_*, remove orphan info, update timestamp for icon res + * -> Need to scan all packages when a user starts too. + * -> Clear data -> remove all dynamic? but not the pinned? * * - Pinned per each launcher package (multiple launchers) * - * - Dev option to reset all counts for QA (for now use "adb shell cmd shortcut reset-throttling") + * - Make save async (should we?) + * + * - Scan and remove orphan bitmaps (just in case). * - * - Load config from settings + * - Backup & restore */ public class ShortcutService extends IShortcutService.Stub { - private static final String TAG = "ShortcutService"; + static final String TAG = "ShortcutService"; - private static final boolean DEBUG = true; // STOPSHIP if true - private static final boolean DEBUG_LOAD = true; // STOPSHIP if true + static final boolean DEBUG = false; // STOPSHIP if true + static final boolean DEBUG_LOAD = false; // STOPSHIP if true - private static final int DEFAULT_RESET_INTERVAL_SEC = 24 * 60 * 60; // 1 day - private static final int DEFAULT_MAX_DAILY_UPDATES = 10; - private static final int DEFAULT_MAX_SHORTCUTS_PER_APP = 5; + @VisibleForTesting + static final long DEFAULT_RESET_INTERVAL_SEC = 24 * 60 * 60; // 1 day - private static final int SAVE_DELAY_MS = 5000; // in milliseconds. + @VisibleForTesting + static final int DEFAULT_MAX_DAILY_UPDATES = 10; @VisibleForTesting - static final String FILENAME_BASE_STATE = "shortcut_service.xml"; + static final int DEFAULT_MAX_SHORTCUTS_PER_APP = 5; @VisibleForTesting - static final String DIRECTORY_PER_USER = "shortcut_service"; + static final int DEFAULT_MAX_ICON_DIMENSION_DP = 96; @VisibleForTesting - static final String FILENAME_USER_PACKAGES = "shortcuts.xml"; + static final int DEFAULT_MAX_ICON_DIMENSION_LOWRAM_DP = 48; - private static final String DIRECTORY_BITMAPS = "bitmaps"; + @VisibleForTesting + static final String DEFAULT_ICON_PERSIST_FORMAT = CompressFormat.PNG.name(); - private static final String TAG_ROOT = "root"; - private static final String TAG_LAST_RESET_TIME = "last_reset_time"; - private static final String ATTR_VALUE = "value"; + @VisibleForTesting + static final int DEFAULT_ICON_PERSIST_QUALITY = 100; - private final Context mContext; + private static final int SAVE_DELAY_MS = 5000; // in milliseconds. - private final Object mLock = new Object(); + @VisibleForTesting + static final String FILENAME_BASE_STATE = "shortcut_service.xml"; - private final Handler mHandler; + @VisibleForTesting + static final String DIRECTORY_PER_USER = "shortcut_service"; - @GuardedBy("mLock") - private final ArrayList<ShortcutChangeListener> mListeners = new ArrayList<>(1); + @VisibleForTesting + static final String FILENAME_USER_PACKAGES = "shortcuts.xml"; - @GuardedBy("mLock") - private long mRawLastResetTime; + 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"; + static final String TAG_EXTRAS = "extras"; + static final String TAG_SHORTCUT = "shortcut"; + + static final String ATTR_VALUE = "value"; + static final String ATTR_NAME = "name"; + static final String ATTR_DYNAMIC_COUNT = "dynamic-count"; + static final String ATTR_CALL_COUNT = "call-count"; + static final String ATTR_LAST_RESET = "last-reset"; + static final String ATTR_ID = "id"; + static final String ATTR_ACTIVITY = "activity"; + static final String ATTR_TITLE = "title"; + static final String ATTR_INTENT = "intent"; + static final String ATTR_WEIGHT = "weight"; + static final String ATTR_TIMESTAMP = "timestamp"; + static final String ATTR_FLAGS = "flags"; + static final String ATTR_ICON_RES = "icon-res"; + static final String ATTR_BITMAP_PATH = "bitmap-path"; - /** - * All the information relevant to shortcuts from a single package (per-user). - * - * TODO Move the persisting code to this class. - */ - private static class PackageShortcuts { + @VisibleForTesting + interface ConfigConstants { /** - * All the shortcuts from the package, keyed on IDs. + * Key name for the throttling reset interval, in seconds. (long) */ - final private ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>(); + String KEY_RESET_INTERVAL_SEC = "reset_interval_sec"; /** - * # of dynamic shortcuts. + * Key name for the max number of modifying API calls per app for every interval. (int) */ - private int mDynamicShortcutCount = 0; + String KEY_MAX_DAILY_UPDATES = "max_daily_updates"; /** - * # of times the package has called rate-limited APIs. + * Key name for the max icon dimensions in DP, for non-low-memory devices. */ - private int mApiCallCountInner; + String KEY_MAX_ICON_DIMENSION_DP = "max_icon_dimension_dp"; /** - * When {@link #mApiCallCountInner} was reset last time. + * Key name for the max icon dimensions in DP, for low-memory devices. */ - private long mLastResetTime; + String KEY_MAX_ICON_DIMENSION_DP_LOWRAM = "max_icon_dimension_dp_lowram"; /** - * @return the all shortcuts. Note DO NOT add/remove or touch the flags of the result - * directly, which would cause {@link #mDynamicShortcutCount} to be out of sync. + * Key name for the max dynamic shortcuts per app. (int) */ - @GuardedBy("mLock") - public ArrayMap<String, ShortcutInfo> getShortcuts() { - return mShortcuts; - } + String KEY_MAX_SHORTCUTS = "max_shortcuts"; /** - * Add a shortcut, or update one with the same ID, with taking over existing flags. - * - * It checks the max number of dynamic shortcuts. + * Key name for icon compression quality, 0-100. */ - @GuardedBy("mLock") - public void updateShortcutWithCapping(@NonNull ShortcutService s, - @NonNull ShortcutInfo newShortcut) { - final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId()); - - int oldFlags = 0; - int newDynamicCount = mDynamicShortcutCount; - - if (oldShortcut != null) { - oldFlags = oldShortcut.getFlags(); - if (oldShortcut.isDynamic()) { - newDynamicCount--; - } - } - if (newShortcut.isDynamic()) { - newDynamicCount++; - } - // Make sure there's still room. - s.enforceMaxDynamicShortcuts(newDynamicCount); - - // Okay, make it dynamic and add. - newShortcut.addFlags(oldFlags); - - mShortcuts.put(newShortcut.getId(), newShortcut); - mDynamicShortcutCount = newDynamicCount; - } - - @GuardedBy("mLock") - public void deleteAllDynamicShortcuts() { - ArrayList<String> removeList = null; // Lazily initialize. - - for (int i = mShortcuts.size() - 1; i >= 0; i--) { - final ShortcutInfo si = mShortcuts.valueAt(i); - - if (!si.isDynamic()) { - continue; - } - if (si.isPinned()) { - // Still pinned, so don't remove; just make it non-dynamic. - si.clearFlags(ShortcutInfo.FLAG_DYNAMIC); - } else { - if (removeList == null) { - removeList = new ArrayList<>(); - } - removeList.add(si.getId()); - } - } - if (removeList != null) { - for (int i = removeList.size() - 1 ; i >= 0; i--) { - mShortcuts.remove(removeList.get(i)); - } - } - mDynamicShortcutCount = 0; - } - - @GuardedBy("mLock") - public void deleteDynamicWithId(@NonNull String shortcutId) { - final ShortcutInfo oldShortcut = mShortcuts.get(shortcutId); - - if (oldShortcut == null) { - return; - } - if (oldShortcut.isDynamic()) { - mDynamicShortcutCount--; - } - if (oldShortcut.isPinned()) { - oldShortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC); - } else { - mShortcuts.remove(shortcutId); - } - } - - @GuardedBy("mLock") - public void pinAll(List<String> shortcutIds) { - for (int i = shortcutIds.size() - 1; i >= 0; i--) { - final ShortcutInfo shortcut = mShortcuts.get(shortcutIds.get(i)); - if (shortcut != null) { - shortcut.addFlags(ShortcutInfo.FLAG_PINNED); - } - } - } + String KEY_ICON_QUALITY = "icon_quality"; /** - * Number of calls that the caller has made, since the last reset. + * Key name for icon compression format: "PNG", "JPEG" or "WEBP" */ - @GuardedBy("mLock") - public int getApiCallCount(@NonNull ShortcutService s) { - final long last = s.getLastResetTimeLocked(); - - // If not reset yet, then reset. - if (mLastResetTime < last) { - mApiCallCountInner = 0; - mLastResetTime = last; - } - return mApiCallCountInner; - } + String KEY_ICON_FORMAT = "icon_format"; + } - /** - * If the caller app hasn't been throttled yet, increment {@link #mApiCallCountInner} - * and return true. Otherwise just return false. - */ - @GuardedBy("mLock") - public boolean tryApiCall(@NonNull ShortcutService s) { - if (getApiCallCount(s) >= s.mMaxDailyUpdates) { - return false; - } - mApiCallCountInner++; - return true; - } + final Context mContext; - @GuardedBy("mLock") - public void resetRateLimitingForCommandLine() { - mApiCallCountInner = 0; - mLastResetTime = 0; - } + private final Object mLock = new Object(); - /** - * Find all shortcuts that match {@code query}. - */ - @GuardedBy("mLock") - public void findAll(@NonNull List<ShortcutInfo> result, - @Nullable Predicate<ShortcutInfo> query, int cloneFlag) { - for (int i = 0; i < mShortcuts.size(); i++) { - final ShortcutInfo si = mShortcuts.valueAt(i); - if (query == null || query.test(si)) { - result.add(si.clone(cloneFlag)); - } - } - } - } + private final Handler mHandler; + + @GuardedBy("mLock") + private final ArrayList<ShortcutChangeListener> mListeners = new ArrayList<>(1); + + @GuardedBy("mLock") + 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. */ - @GuardedBy("mLock") private int mMaxDynamicShortcuts; /** * Max number of updating API calls that each application can make a day. */ - @GuardedBy("mLock") - private int mMaxDailyUpdates; + int mMaxDailyUpdates; /** * Actual throttling-reset interval. By default it's a day. */ - @GuardedBy("mLock") private long mResetInterval; + /** + * Icon max width/height in pixels. + */ + private int mMaxIconDimension; + + private CompressFormat mIconPersistFormat; + private int mIconPersistQuality; + public ShortcutService(Context context) { mContext = Preconditions.checkNotNull(context); LocalServices.addService(ShortcutServiceInternal.class, new LocalService()); @@ -363,7 +286,7 @@ public class ShortcutService extends IShortcutService.Stub { } @Override - public void onStartUser(int userId) { + public void onUnlockUser(int userId) { synchronized (mService.mLock) { mService.onStartUserLocked(userId); } @@ -391,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 */ @@ -406,27 +329,90 @@ public class ShortcutService extends IShortcutService.Stub { */ private void initialize() { synchronized (mLock) { - injectLoadConfigurationLocked(); + loadConfigurationLocked(); loadBaseStateLocked(); } } - // Test overrides it to inject different values. + /** + * Load the configuration from Settings. + */ + private void loadConfigurationLocked() { + updateConfigurationLocked(injectShortcutManagerConstants()); + } + + /** + * Load the configuration from Settings. + */ @VisibleForTesting - void injectLoadConfigurationLocked() { - mResetInterval = DEFAULT_RESET_INTERVAL_SEC * 1000L; - mMaxDailyUpdates = DEFAULT_MAX_DAILY_UPDATES; - mMaxDynamicShortcuts = DEFAULT_MAX_SHORTCUTS_PER_APP; + boolean updateConfigurationLocked(String config) { + boolean result = true; + + final KeyValueListParser parser = new KeyValueListParser(','); + try { + parser.setString(config); + } catch (IllegalArgumentException e) { + // Failed to parse the settings string, log this and move on + // with defaults. + Slog.e(TAG, "Bad shortcut manager settings", e); + result = false; + } + + mResetInterval = parser.getLong( + ConfigConstants.KEY_RESET_INTERVAL_SEC, DEFAULT_RESET_INTERVAL_SEC) + * 1000L; + + mMaxDailyUpdates = (int) parser.getLong( + ConfigConstants.KEY_MAX_DAILY_UPDATES, DEFAULT_MAX_DAILY_UPDATES); + + mMaxDynamicShortcuts = (int) parser.getLong( + ConfigConstants.KEY_MAX_SHORTCUTS, DEFAULT_MAX_SHORTCUTS_PER_APP); + + final int iconDimensionDp = injectIsLowRamDevice() + ? (int) parser.getLong( + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP_LOWRAM, + DEFAULT_MAX_ICON_DIMENSION_LOWRAM_DP) + : (int) parser.getLong( + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP, + DEFAULT_MAX_ICON_DIMENSION_DP); + + mMaxIconDimension = injectDipToPixel(iconDimensionDp); + + mIconPersistFormat = CompressFormat.valueOf( + parser.getString(ConfigConstants.KEY_ICON_FORMAT, DEFAULT_ICON_PERSIST_FORMAT)); + + mIconPersistQuality = (int) parser.getLong( + ConfigConstants.KEY_ICON_QUALITY, + DEFAULT_ICON_PERSIST_QUALITY); + + return result; } - // === Persistings === + @VisibleForTesting + String injectShortcutManagerConstants() { + return android.provider.Settings.Global.getString( + mContext.getContentResolver(), + android.provider.Settings.Global.SHORTCUT_MANAGER_CONSTANTS); + } + + @VisibleForTesting + int injectDipToPixel(int dip) { + return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, + mContext.getResources().getDisplayMetrics()); + } + + // === Persisting === @Nullable - private String parseStringAttribute(XmlPullParser parser, String attribute) { + static String parseStringAttribute(XmlPullParser parser, String attribute) { return parser.getAttributeValue(null, attribute); } - private long parseLongAttribute(XmlPullParser parser, String attribute) { + static int parseIntAttribute(XmlPullParser parser, String attribute) { + return (int) parseLongAttribute(parser, attribute); + } + + static long parseLongAttribute(XmlPullParser parser, String attribute) { final String value = parseStringAttribute(parser, attribute); if (TextUtils.isEmpty(value)) { return 0; @@ -440,7 +426,7 @@ public class ShortcutService extends IShortcutService.Stub { } @Nullable - private ComponentName parseComponentNameAttribute(XmlPullParser parser, String attribute) { + static ComponentName parseComponentNameAttribute(XmlPullParser parser, String attribute) { final String value = parseStringAttribute(parser, attribute); if (TextUtils.isEmpty(value)) { return null; @@ -449,7 +435,7 @@ public class ShortcutService extends IShortcutService.Stub { } @Nullable - private Intent parseIntentAttribute(XmlPullParser parser, String attribute) { + static Intent parseIntentAttribute(XmlPullParser parser, String attribute) { final String value = parseStringAttribute(parser, attribute); if (TextUtils.isEmpty(value)) { return null; @@ -462,7 +448,7 @@ public class ShortcutService extends IShortcutService.Stub { } } - private void writeTagValue(XmlSerializer out, String tag, String value) throws IOException { + static void writeTagValue(XmlSerializer out, String tag, String value) throws IOException { if (TextUtils.isEmpty(value)) return; out.startTag(null, tag); @@ -470,11 +456,11 @@ public class ShortcutService extends IShortcutService.Stub { out.endTag(null, tag); } - private void writeTagValue(XmlSerializer out, String tag, long value) throws IOException { + static void writeTagValue(XmlSerializer out, String tag, long value) throws IOException { writeTagValue(out, tag, Long.toString(value)); } - private void writeTagExtra(XmlSerializer out, String tag, PersistableBundle bundle) + static void writeTagExtra(XmlSerializer out, String tag, PersistableBundle bundle) throws IOException, XmlPullParserException { if (bundle == null) return; @@ -483,22 +469,22 @@ public class ShortcutService extends IShortcutService.Stub { out.endTag(null, tag); } - private void writeAttr(XmlSerializer out, String name, String value) throws IOException { + static void writeAttr(XmlSerializer out, String name, String value) throws IOException { if (TextUtils.isEmpty(value)) return; out.attribute(null, name, value); } - private void writeAttr(XmlSerializer out, String name, long value) throws IOException { + static void writeAttr(XmlSerializer out, String name, long value) throws IOException { writeAttr(out, name, String.valueOf(value)); } - private void writeAttr(XmlSerializer out, String name, ComponentName comp) throws IOException { + static void writeAttr(XmlSerializer out, String name, ComponentName comp) throws IOException { if (comp == null) return; writeAttr(out, name, comp.flattenToString()); } - private void writeAttr(XmlSerializer out, String name, Intent intent) throws IOException { + static void writeAttr(XmlSerializer out, String name, Intent intent) throws IOException { if (intent == null) return; writeAttr(out, name, intent.toUri(/* flags =*/ 0)); @@ -598,34 +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 shortcuts = packages.valueAt(i); - - // TODO Move this to PackageShortcuts. - out.startTag(null, "package"); + getUserShortcutsLocked(userId).saveToXml(out); - writeAttr(out, "name", packageName); - writeAttr(out, "dynamic-count", shortcuts.mDynamicShortcutCount); - writeAttr(out, "call-count", shortcuts.mApiCallCountInner); - writeAttr(out, "last-reset", shortcuts.mLastResetTime); - - final int size = shortcuts.getShortcuts().size(); - for (int j = 0; j < size; j++) { - saveShortcut(out, shortcuts.getShortcuts().valueAt(j)); - } - - out.endTag(null, "package"); - } - - // Epilogue. - out.endTag(null, TAG_ROOT); out.endDocument(); // Close. @@ -636,38 +597,16 @@ public class ShortcutService extends IShortcutService.Stub { } } - private void saveShortcut(XmlSerializer out, ShortcutInfo si) - throws IOException, XmlPullParserException { - out.startTag(null, "shortcut"); - writeAttr(out, "id", si.getId()); - // writeAttr(out, "package", si.getPackageName()); // not needed - writeAttr(out, "activity", si.getActivityComponent()); - // writeAttr(out, "icon", si.getIcon()); // We don't save it. - writeAttr(out, "title", si.getTitle()); - writeAttr(out, "intent", si.getIntent()); - writeAttr(out, "weight", si.getWeight()); - writeAttr(out, "timestamp", si.getLastChangedTimestamp()); - writeAttr(out, "flags", si.getFlags()); - writeAttr(out, "icon-res", si.getIconResourceId()); - writeAttr(out, "bitmap-path", si.getBitmapPath()); - - writeTagExtra(out, "intent-extras", si.getIntentPersistableExtras()); - writeTagExtra(out, "extras", si.getExtras()); - - out.endTag(null, "shortcut"); - } - - private static IOException throwForInvalidTag(int depth, String tag) throws IOException { + static IOException throwForInvalidTag(int depth, String tag) throws IOException { throw new IOException(String.format("Invalid tag '%s' found at depth %d", tag, depth)); } @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); } - path.mkdirs(); final AtomicFile file = new AtomicFile(path); final FileInputStream in; @@ -679,14 +618,11 @@ public class ShortcutService extends IShortcutService.Stub { } return null; } - final ArrayMap<String, PackageShortcuts> ret = new ArrayMap<String, PackageShortcuts>(); + UserShortcuts ret = null; try { XmlPullParser parser = Xml.newPullParser(); parser.setInput(in, StandardCharsets.UTF_8.name()); - String packageName = null; - PackageShortcuts shortcuts = null; - int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) { if (type != XmlPullParser.START_TAG) { @@ -694,45 +630,14 @@ public class ShortcutService extends IShortcutService.Stub { } final int depth = parser.getDepth(); - // TODO Move some of this to PackageShortcuts. - final String tag = parser.getName(); if (DEBUG_LOAD) { 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 "package": - packageName = parseStringAttribute(parser, "name"); - shortcuts = new PackageShortcuts(); - ret.put(packageName, shortcuts); - - shortcuts.mDynamicShortcutCount = - (int) parseLongAttribute(parser, "dynamic-count"); - shortcuts.mApiCallCountInner = - (int) parseLongAttribute(parser, "call-count"); - shortcuts.mLastResetTime = parseLongAttribute(parser, "last-reset"); - continue; - } - break; - } - case 3: { - switch (tag) { - case "shortcut": - final ShortcutInfo si = parseShortcut(parser, packageName); - shortcuts.mShortcuts.put(si.getId(), si); - continue; - } - break; - } + if ((depth == 1) && TAG_USER.equals(tag)) { + ret = UserShortcuts.loadFromXml(parser, userId); + continue; } throwForInvalidTag(depth, tag); } @@ -745,60 +650,6 @@ public class ShortcutService extends IShortcutService.Stub { } } - private ShortcutInfo parseShortcut(XmlPullParser parser, String packgeName) - throws IOException, XmlPullParserException { - String id; - ComponentName activityComponent; - Icon icon; - String title; - Intent intent; - PersistableBundle intentPersistableExtras = null; - int weight; - PersistableBundle extras = null; - long lastChangedTimestamp; - int flags; - int iconRes; - String bitmapPath; - - id = parseStringAttribute(parser, "id"); - activityComponent = parseComponentNameAttribute(parser, "activity"); - title = parseStringAttribute(parser, "title"); - intent = parseIntentAttribute(parser, "intent"); - weight = (int) parseLongAttribute(parser, "weight"); - lastChangedTimestamp = (int) parseLongAttribute(parser, "timestamp"); - flags = (int) parseLongAttribute(parser, "flags"); - iconRes = (int) parseLongAttribute(parser, "icon-res"); - bitmapPath = parseStringAttribute(parser, "bitmap-path"); - - 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(); - if (DEBUG_LOAD) { - Slog.d(TAG, String.format(" depth=%d type=%d name=%s", - depth, type, tag)); - } - switch (tag) { - case "intent-extras": - intentPersistableExtras = PersistableBundle.restoreFromXml(parser); - continue; - case "extras": - extras = PersistableBundle.restoreFromXml(parser); - continue; - } - throw throwForInvalidTag(depth, tag); - } - return new ShortcutInfo( - id, packgeName, activityComponent, /* icon =*/ null, title, intent, - intentPersistableExtras, weight, extras, lastChangedTimestamp, flags, - iconRes, bitmapPath); - } - // TODO Actually make it async. private void scheduleSaveBaseState() { synchronized (mLock) { @@ -855,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; } @@ -872,17 +723,206 @@ 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(); - userPackages.put(packageName, shortcuts); + shortcuts = new PackageShortcuts(userId, packageName); + userPackages.getPackages().put(packageName, shortcuts); } return shortcuts; } // === Caller validation === + void removeIcon(@UserIdInt int userId, ShortcutInfo shortcut) { + if (shortcut.getBitmapPath() != null) { + if (DEBUG) { + Slog.d(TAG, "Removing " + shortcut.getBitmapPath()); + } + new File(shortcut.getBitmapPath()).delete(); + + shortcut.setBitmapPath(null); + shortcut.setIconResourceId(0); + shortcut.clearFlags(ShortcutInfo.FLAG_HAS_ICON_FILE | ShortcutInfo.FLAG_HAS_ICON_RES); + } + } + + @VisibleForTesting + static class FileOutputStreamWithPath extends FileOutputStream { + private final File mFile; + + public FileOutputStreamWithPath(File file) throws FileNotFoundException { + super(file); + mFile = file; + } + + public File getFile() { + return mFile; + } + } + + /** + * Build the cached bitmap filename for a shortcut icon. + * + * The filename will be based on the ID, except certain characters will be escaped. + */ + @VisibleForTesting + FileOutputStreamWithPath openIconFileForWrite(@UserIdInt int userId, ShortcutInfo shortcut) + throws IOException { + final File packagePath = new File(getUserBitmapFilePath(userId), + shortcut.getPackageName()); + if (!packagePath.isDirectory()) { + packagePath.mkdirs(); + if (!packagePath.isDirectory()) { + throw new IOException("Unable to create directory " + packagePath); + } + SELinux.restorecon(packagePath); + } + + final String baseName = String.valueOf(injectCurrentTimeMillis()); + for (int suffix = 0;; suffix++) { + final String filename = (suffix == 0 ? baseName : baseName + "_" + suffix) + ".png"; + final File file = new File(packagePath, filename); + if (!file.exists()) { + if (DEBUG) { + Slog.d(TAG, "Saving icon to " + file.getAbsolutePath()); + } + return new FileOutputStreamWithPath(file); + } + } + } + + void saveIconAndFixUpShortcut(@UserIdInt int userId, ShortcutInfo shortcut) { + if (shortcut.hasIconFile() || shortcut.hasIconResource()) { + return; + } + + final long token = Binder.clearCallingIdentity(); + try { + // Clear icon info on the shortcut. + shortcut.setIconResourceId(0); + shortcut.setBitmapPath(null); + + final Icon icon = shortcut.getIcon(); + if (icon == null) { + return; // has no icon + } + + Bitmap bitmap = null; + try { + switch (icon.getType()) { + case Icon.TYPE_RESOURCE: { + injectValidateIconResPackage(shortcut, icon); + + shortcut.setIconResourceId(icon.getResId()); + shortcut.addFlags(ShortcutInfo.FLAG_HAS_ICON_RES); + return; + } + case Icon.TYPE_BITMAP: { + bitmap = icon.getBitmap(); + break; + } + case Icon.TYPE_URI: { + final Uri uri = ContentProvider.maybeAddUserId(icon.getUri(), userId); + + try (InputStream is = mContext.getContentResolver().openInputStream(uri)) { + + bitmap = BitmapFactory.decodeStream(is); + + } catch (IOException e) { + Slog.e(TAG, "Unable to load icon from " + uri); + return; + } + break; + } + default: + // This shouldn't happen because we've already validated the icon, but + // just in case. + throw ShortcutInfo.getInvalidIconException(); + } + if (bitmap == null) { + Slog.e(TAG, "Null bitmap detected"); + return; + } + // Shrink and write to the file. + File path = null; + try { + final FileOutputStreamWithPath out = openIconFileForWrite(userId, shortcut); + try { + path = out.getFile(); + + shrinkBitmap(bitmap, mMaxIconDimension) + .compress(mIconPersistFormat, mIconPersistQuality, out); + + shortcut.setBitmapPath(out.getFile().getAbsolutePath()); + shortcut.addFlags(ShortcutInfo.FLAG_HAS_ICON_FILE); + } finally { + IoUtils.closeQuietly(out); + } + } catch (IOException|RuntimeException e) { + // STOPSHIP Change wtf to e + Slog.wtf(ShortcutService.TAG, "Unable to write bitmap to file", e); + if (path != null && path.exists()) { + path.delete(); + } + } + } finally { + if (bitmap != null) { + bitmap.recycle(); + } + // Once saved, we won't use the original icon information, so null it out. + shortcut.clearIcon(); + } + } finally { + Binder.restoreCallingIdentity(token); + } + } + + // Unfortunately we can't do this check in unit tests because we fake creator package names, + // so override in unit tests. + // TODO CTS this case. + void injectValidateIconResPackage(ShortcutInfo shortcut, Icon icon) { + if (!shortcut.getPackageName().equals(icon.getResPackage())) { + throw new IllegalArgumentException( + "Icon resource must reside in shortcut owner package"); + } + } + + @VisibleForTesting + static Bitmap shrinkBitmap(Bitmap in, int maxSize) { + // Original width/height. + final int ow = in.getWidth(); + final int oh = in.getHeight(); + if ((ow <= maxSize) && (oh <= maxSize)) { + if (DEBUG) { + Slog.d(TAG, String.format("Icon size %dx%d, no need to shrink", ow, oh)); + } + return in; + } + final int longerDimension = Math.max(ow, oh); + + // New width and height. + final int nw = ow * maxSize / longerDimension; + final int nh = oh * maxSize / longerDimension; + if (DEBUG) { + Slog.d(TAG, String.format("Icon size %dx%d, shrinking to %dx%d", + ow, oh, nw, nh)); + } + + final Bitmap scaledBitmap = Bitmap.createBitmap(nw, nh, Bitmap.Config.ARGB_8888); + final Canvas c = new Canvas(scaledBitmap); + + final RectF dst = new RectF(0, 0, nw, nh); + + c.drawBitmap(in, /*src=*/ null, dst, /* paint =*/ null); + + in.recycle(); + + return scaledBitmap; + } + + // === Caller validation === + private boolean isCallerSystem() { final int callingUid = injectBinderCallingUid(); return UserHandle.isSameApp(callingUid, Process.SYSTEM_UID); @@ -915,31 +955,21 @@ public class ShortcutService extends IShortcutService.Stub { if (UserHandle.getUserId(callingUid) != userId) { throw new SecurityException("Invalid user-ID"); } - verifyCallingPackage(packageName); - } - - private void verifyCallingPackage(@NonNull String packageName) { - Preconditions.checkStringNotEmpty(packageName, "packageName"); - - if (isCallerSystem()) { - return; // no check - } - - if (injectGetPackageUid(packageName) == injectBinderCallingUid()) { + if (injectGetPackageUid(packageName, userId) == injectBinderCallingUid()) { return; // Caller is valid. } throw new SecurityException("Caller UID= doesn't own " + packageName); } // Test overrides it. - int injectGetPackageUid(String packageName) { + int injectGetPackageUid(@NonNull String packageName, @UserIdInt int userId) { try { // TODO Is MATCH_UNINSTALLED_PACKAGES correct to get SD card app info? - return mContext.getPackageManager().getPackageUid(packageName, + return mContext.getPackageManager().getPackageUidAsUser(packageName, PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE - | PackageManager.MATCH_UNINSTALLED_PACKAGES); + | PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); } catch (NameNotFoundException e) { return -1; } @@ -983,8 +1013,10 @@ public class ShortcutService extends IShortcutService.Stub { * - Make sure the intent's extras are persistable, and them to set * {@link ShortcutInfo#mIntentPersistableExtras}. Also clear its extras. * - Clear flags. + * + * TODO Detailed unit tests */ - private void fixUpIncomingShortcutInfo(@NonNull ShortcutInfo shortcut) { + private void fixUpIncomingShortcutInfo(@NonNull ShortcutInfo shortcut, boolean forUpdate) { Preconditions.checkNotNull(shortcut, "Null shortcut detected"); if (shortcut.getActivityComponent() != null) { Preconditions.checkState( @@ -993,22 +1025,58 @@ public class ShortcutService extends IShortcutService.Stub { "Activity package name mismatch"); } - shortcut.enforceMandatoryFields(); + if (!forUpdate) { + shortcut.enforceMandatoryFields(); + } + if (shortcut.getIcon() != null) { + ShortcutInfo.validateIcon(shortcut.getIcon()); + } - final Intent intent = shortcut.getIntent(); - final Bundle intentExtras = intent.getExtras(); - if (intentExtras != null && intentExtras.size() > 0) { - intent.replaceExtras((Bundle) null); + validateForXml(shortcut.getId()); + validateForXml(shortcut.getTitle()); + validatePersistableBundleForXml(shortcut.getIntentPersistableExtras()); + validatePersistableBundleForXml(shortcut.getExtras()); - // PersistableBundle's constructor will throw IllegalArgumentException if original - // extras contain something not persistable. - shortcut.setIntentPersistableExtras(new PersistableBundle(intentExtras)); + shortcut.setFlags(0); + } + + // KXmlSerializer is strict and doesn't allow certain characters, so we disallow those + // characters. + + private static void validatePersistableBundleForXml(PersistableBundle b) { + if (b == null || b.size() == 0) { + return; } + for (String key : b.keySet()) { + validateForXml(key); + final Object value = b.get(key); + if (value == null) { + continue; + } else if (value instanceof String) { + validateForXml((String) value); + } else if (value instanceof String[]) { + for (String v : (String[]) value) { + validateForXml(v); + } + } else if (value instanceof PersistableBundle) { + validatePersistableBundleForXml((PersistableBundle) value); + } + } + } - // TODO Save the icon - shortcut.setIcon(null); + private static void validateForXml(String s) { + if (TextUtils.isEmpty(s)) { + return; + } + for (int i = s.length() - 1; i >= 0; i--) { + if (!isAllowedInXml(s.charAt(i))) { + throw new IllegalArgumentException("Unsupported character detected in: " + s); + } + } + } - shortcut.setFlags(0); + private static boolean isAllowedInXml(char c) { + return (c >= 0x20 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xfffd); } // === APIs === @@ -1032,11 +1100,11 @@ public class ShortcutService extends IShortcutService.Stub { // Validate the shortcuts. for (int i = 0; i < size; i++) { - fixUpIncomingShortcutInfo(newShortcuts.get(i)); + fixUpIncomingShortcutInfo(newShortcuts.get(i), /* forUpdate= */ false); } // First, remove all un-pinned; dynamic shortcuts - ps.deleteAllDynamicShortcuts(); + ps.deleteAllDynamicShortcuts(this); // Then, add/update all. We need to make sure to take over "pinned" flag. for (int i = 0; i < size; i++) { @@ -1046,7 +1114,6 @@ public class ShortcutService extends IShortcutService.Stub { } } userPackageChanged(packageName, userId); - return true; } @@ -1056,15 +1123,34 @@ public class ShortcutService extends IShortcutService.Stub { verifyCaller(packageName, userId); final List<ShortcutInfo> newShortcuts = (List<ShortcutInfo>) shortcutInfoList.getList(); + final int size = newShortcuts.size(); synchronized (mLock) { + final PackageShortcuts ps = getPackageShortcutsLocked(packageName, userId); - if (true) { - throw new RuntimeException("not implemented yet"); + // Throttling. + if (!ps.tryApiCall(this)) { + return false; } - // TODO Similar to setDynamicShortcuts, but don't add new ones, and don't change flags. - // Update non-null fields only. + for (int i = 0; i < size; i++) { + final ShortcutInfo source = newShortcuts.get(i); + fixUpIncomingShortcutInfo(source, /* forUpdate= */ true); + + final ShortcutInfo target = ps.findShortcutById(source.getId()); + if (target != null) { + final boolean replacingIcon = (source.getIcon() != null); + if (replacingIcon) { + removeIcon(userId, target); + } + + target.copyNonNullFieldsFrom(source); + + if (replacingIcon) { + saveIconAndFixUpShortcut(userId, target); + } + } + } } userPackageChanged(packageName, userId); @@ -1085,7 +1171,7 @@ public class ShortcutService extends IShortcutService.Stub { } // Validate the shortcut. - fixUpIncomingShortcutInfo(newShortcut); + fixUpIncomingShortcutInfo(newShortcut, /* forUpdate= */ false); // Add it. newShortcut.addFlags(ShortcutInfo.FLAG_DYNAMIC); @@ -1103,7 +1189,7 @@ public class ShortcutService extends IShortcutService.Stub { Preconditions.checkStringNotEmpty(shortcutId, "shortcutId must be provided"); synchronized (mLock) { - getPackageShortcutsLocked(packageName, userId).deleteDynamicWithId(shortcutId); + getPackageShortcutsLocked(packageName, userId).deleteDynamicWithId(this, shortcutId); } userPackageChanged(packageName, userId); } @@ -1113,7 +1199,7 @@ public class ShortcutService extends IShortcutService.Stub { verifyCaller(packageName, userId); synchronized (mLock) { - getPackageShortcutsLocked(packageName, userId).deleteAllDynamicShortcuts(); + getPackageShortcutsLocked(packageName, userId).deleteAllDynamicShortcuts(this); } userPackageChanged(packageName, userId); } @@ -1177,6 +1263,13 @@ public class ShortcutService extends IShortcutService.Stub { } } + @Override + public int getIconMaxDimensions(String packageName, int userId) throws RemoteException { + synchronized (mLock) { + return mMaxIconDimension; + } + } + /** * Reset all throttling, for developer options and command line. Only system/shell can call it. */ @@ -1193,6 +1286,7 @@ public class ShortcutService extends IShortcutService.Stub { mRawLastResetTime = injectCurrentTimeMillis(); } scheduleSaveBaseState(); + Slog.i(TAG, "ShortcutManager: throttling counter reset"); } /** @@ -1216,8 +1310,8 @@ public class ShortcutService extends IShortcutService.Stub { userId, ret, cloneFlag); } else { final ArrayMap<String, PackageShortcuts> packages = - getUserShortcutsLocked(userId); - for (int i = 0; i < packages.size(); i++) { + getUserShortcutsLocked(userId).getPackages(); + for (int i = packages.size() - 1; i >= 0; i--) { getShortcutsInnerLocked( packages.keyAt(i), changedSince, componentName, queryFlags, userId, ret, cloneFlag); @@ -1274,7 +1368,8 @@ public class ShortcutService extends IShortcutService.Stub { Preconditions.checkNotNull(shortcutIds, "shortcutIds"); synchronized (mLock) { - getPackageShortcutsLocked(packageName, userId).pinAll(shortcutIds); + getPackageShortcutsLocked(packageName, userId).replacePinned( + ShortcutService.this, callingPackage, shortcutIds); } userPackageChanged(packageName, userId); } @@ -1289,18 +1384,8 @@ public class ShortcutService extends IShortcutService.Stub { synchronized (mLock) { final ShortcutInfo fullShortcut = getPackageShortcutsLocked(packageName, userId) - .getShortcuts().get(shortcutId); - if (fullShortcut == null) { - return null; - } else { - final Intent intent = fullShortcut.getIntent(); - final PersistableBundle extras = fullShortcut.getIntentPersistableExtras(); - if (extras != null) { - intent.replaceExtras(new Bundle(extras)); - } - - return intent; - } + .findShortcutById(shortcutId); + return fullShortcut == null ? null : fullShortcut.getIntent(); } } @@ -1310,6 +1395,45 @@ public class ShortcutService extends IShortcutService.Stub { mListeners.add(Preconditions.checkNotNull(listener)); } } + + @Override + public int getShortcutIconResId(@NonNull String callingPackage, + @NonNull ShortcutInfo shortcut, int userId) { + Preconditions.checkNotNull(shortcut, "shortcut"); + + synchronized (mLock) { + final ShortcutInfo shortcutInfo = getPackageShortcutsLocked( + shortcut.getPackageName(), userId).findShortcutById(shortcut.getId()); + return (shortcutInfo != null && shortcutInfo.hasIconResource()) + ? shortcutInfo.getIconResourceId() : 0; + } + } + + @Override + public ParcelFileDescriptor getShortcutIconFd(@NonNull String callingPackage, + @NonNull ShortcutInfo shortcutIn, int userId) { + Preconditions.checkNotNull(shortcutIn, "shortcut"); + + synchronized (mLock) { + final ShortcutInfo shortcutInfo = getPackageShortcutsLocked( + shortcutIn.getPackageName(), userId).findShortcutById(shortcutIn.getId()); + if (shortcutInfo == null || !shortcutInfo.hasIconFile()) { + return null; + } + try { + if (shortcutInfo.getBitmapPath() == null) { + Slog.w(TAG, "null bitmap detected in getShortcutIconFd()"); + return null; + } + return ParcelFileDescriptor.open( + new File(shortcutInfo.getBitmapPath()), + ParcelFileDescriptor.MODE_READ_ONLY); + } catch (FileNotFoundException e) { + Slog.e(TAG, "Icon file not found: " + shortcutInfo.getBitmapPath()); + return null; + } + } + } } // === Dump === @@ -1336,78 +1460,42 @@ public class ShortcutService extends IShortcutService.Stub { pw.print(now); pw.print("] "); pw.print(formatTime(now)); + pw.print(" Raw last reset: ["); pw.print(mRawLastResetTime); pw.print("] "); pw.print(formatTime(mRawLastResetTime)); final long last = getLastResetTimeLocked(); - final long next = getNextResetTimeLocked(); pw.print(" Last reset: ["); pw.print(last); pw.print("] "); pw.print(formatTime(last)); + final long next = getNextResetTimeLocked(); pw.print(" Next reset: ["); pw.print(next); pw.print("] "); pw.print(formatTime(next)); pw.println(); + pw.print(" Max icon dim: "); + pw.print(mMaxIconDimension); + pw.print(" Icon format: "); + pw.print(mIconPersistFormat); + pw.print(" Icon quality: "); + pw.print(mIconPersistQuality); pw.println(); - for (int i = 0; i < mShortcuts.size(); i++) { - dumpUserLocked(pw, mShortcuts.keyAt(i)); - } - - } - } - - 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 shortcuts = mShortcuts.get(userId).get(packageName); - if (shortcuts == null) { - return; - } - - pw.print(" Package: "); - pw.print(packageName); - pw.println(); - - pw.print(" Calls: "); - pw.print(shortcuts.getApiCallCount(this)); - pw.println(); - - // This should be after getApiCallCount(), which may update it. - pw.print(" Last reset: ["); - pw.print(shortcuts.mLastResetTime); - pw.print("] "); - pw.print(formatTime(shortcuts.mLastResetTime)); - pw.println(); - pw.println(" Shortcuts:"); - final int size = shortcuts.getShortcuts().size(); - for (int i = 0; i < size; i++) { - pw.print(" "); - pw.println(shortcuts.getShortcuts().valueAt(i).toInsecureString()); + for (int i = 0; i < mUsers.size(); i++) { + pw.println(); + mUsers.valueAt(i).dump(this, pw, " "); + } } } - private static String formatTime(long time) { + static String formatTime(long time) { Time tobj = new Time(); tobj.set(time); return tobj.format("%Y-%m-%d %H:%M:%S"); @@ -1434,14 +1522,27 @@ public class ShortcutService extends IShortcutService.Stub { return handleDefaultCommands(cmd); } final PrintWriter pw = getOutPrintWriter(); - switch(cmd) { + int ret = 1; + switch (cmd) { case "reset-package-throttling": - return handleResetPackageThrottling(); + ret = handleResetPackageThrottling(); + break; case "reset-throttling": - return handleResetThrottling(); + ret = handleResetThrottling(); + break; + case "override-config": + ret = handleOverrideConfig(); + break; + case "reset-config": + ret = handleResetConfig(); + break; default: return handleDefaultCommands(cmd); } + if (ret == 0) { + pw.println("Success"); + } + return ret; } @Override @@ -1455,6 +1556,12 @@ public class ShortcutService extends IShortcutService.Stub { pw.println("cmd shortcut reset-throttling"); pw.println(" Reset throttling for all packages and users"); pw.println(); + pw.println("cmd shortcut override-config CONFIG"); + pw.println(" Override the configuration for testing (will last until reboot)"); + pw.println(); + pw.println("cmd shortcut reset-config"); + pw.println(" Reset the configuration set with \"update-config\""); + pw.println(); } private int handleResetThrottling() { @@ -1486,6 +1593,26 @@ public class ShortcutService extends IShortcutService.Stub { return 0; } + + private int handleOverrideConfig() { + final PrintWriter pw = getOutPrintWriter(); + final String config = getNextArgRequired(); + + synchronized (mLock) { + if (!updateConfigurationLocked(config)) { + pw.println("override-config failed. See logcat for details."); + return 1; + } + } + return 0; + } + + private int handleResetConfig() { + synchronized (mLock) { + loadConfigurationLocked(); + } + return 0; + } } // === Unit test support === @@ -1505,26 +1632,520 @@ public class ShortcutService extends IShortcutService.Stub { } File injectUserDataPath(@UserIdInt int userId) { - return new File(Environment.getDataSystemDeDirectory(userId), DIRECTORY_PER_USER); + return new File(Environment.getDataSystemCeDirectory(userId), DIRECTORY_PER_USER); + } + + @VisibleForTesting + boolean injectIsLowRamDevice() { + return ActivityManager.isLowRamDeviceStatic(); + } + + File getUserBitmapFilePath(@UserIdInt int userId) { + return new File(injectUserDataPath(userId), DIRECTORY_BITMAPS); } @VisibleForTesting - SparseArray<ArrayMap<String, PackageShortcuts>> getShortcutsForTest() { - return mShortcuts; + SparseArray<UserShortcuts> getShortcutsForTest() { + return mUsers; } @VisibleForTesting - void setMaxDynamicShortcutsForTest(int max) { - mMaxDynamicShortcuts = max; + int getMaxDynamicShortcutsForTest() { + return mMaxDynamicShortcuts; } @VisibleForTesting - void setMaxDailyUpdatesForTest(int max) { - mMaxDailyUpdates = max; + int getMaxDailyUpdatesForTest() { + return mMaxDailyUpdates; } @VisibleForTesting - public void setResetIntervalForTest(long interval) { - mResetInterval = interval; + long getResetIntervalForTest() { + return mResetInterval; + } + + @VisibleForTesting + int getMaxIconDimensionForTest() { + return mMaxIconDimension; + } + + @VisibleForTesting + CompressFormat getIconPersistFormatForTest() { + return mIconPersistFormat; + } + + @VisibleForTesting + int getIconPersistQualityForTest() { + return mIconPersistQuality; + } + + @VisibleForTesting + ShortcutInfo getPackageShortcutForTest(String packageName, String shortcutId, int userId) { + synchronized (mLock) { + return getPackageShortcutsLocked(packageName, userId).findShortcutById(shortcutId); + } + } +} + +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). + */ +class PackageShortcuts { + private static final String TAG = ShortcutService.TAG; + + @UserIdInt + final int mUserId; + + @NonNull + final String mPackageName; + + /** + * All the shortcuts from the package, keyed on IDs. + */ + final private ArrayMap<String, ShortcutInfo> mShortcuts = new ArrayMap<>(); + + /** + * # of dynamic shortcuts. + */ + private int mDynamicShortcutCount = 0; + + /** + * # of times the package has called rate-limited APIs. + */ + private int mApiCallCount; + + /** + * When {@link #mApiCallCount} was reset last time. + */ + private long mLastResetTime; + + PackageShortcuts(int userId, String packageName) { + mUserId = userId; + mPackageName = packageName; + } + + @GuardedBy("mLock") + @Nullable + public ShortcutInfo findShortcutById(String id) { + return mShortcuts.get(id); + } + + private ShortcutInfo deleteShortcut(@NonNull ShortcutService s, + @NonNull String id) { + final ShortcutInfo shortcut = mShortcuts.remove(id); + if (shortcut != null) { + s.removeIcon(mUserId, shortcut); + shortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_PINNED); + } + return shortcut; + } + + void addShortcut(@NonNull ShortcutService s, @NonNull ShortcutInfo newShortcut) { + deleteShortcut(s, newShortcut.getId()); + s.saveIconAndFixUpShortcut(mUserId, newShortcut); + mShortcuts.put(newShortcut.getId(), newShortcut); + } + + /** + * Add a shortcut, or update one with the same ID, with taking over existing flags. + * + * It checks the max number of dynamic shortcuts. + */ + @GuardedBy("mLock") + public void updateShortcutWithCapping(@NonNull ShortcutService s, + @NonNull ShortcutInfo newShortcut) { + final ShortcutInfo oldShortcut = mShortcuts.get(newShortcut.getId()); + + int oldFlags = 0; + int newDynamicCount = mDynamicShortcutCount; + + if (oldShortcut != null) { + oldFlags = oldShortcut.getFlags(); + if (oldShortcut.isDynamic()) { + newDynamicCount--; + } + } + if (newShortcut.isDynamic()) { + newDynamicCount++; + } + // Make sure there's still room. + s.enforceMaxDynamicShortcuts(newDynamicCount); + + // Okay, make it dynamic and add. + newShortcut.addFlags(oldFlags); + + addShortcut(s, newShortcut); + mDynamicShortcutCount = newDynamicCount; + } + + /** + * Remove all shortcuts that aren't pinned nor dynamic. + */ + private void removeOrphans(@NonNull ShortcutService s) { + ArrayList<String> removeList = null; // Lazily initialize. + + for (int i = mShortcuts.size() - 1; i >= 0; i--) { + final ShortcutInfo si = mShortcuts.valueAt(i); + + if (si.isPinned() || si.isDynamic()) continue; + + if (removeList == null) { + removeList = new ArrayList<>(); + } + removeList.add(si.getId()); + } + if (removeList != null) { + for (int i = removeList.size() - 1 ; i >= 0; i--) { + deleteShortcut(s, removeList.get(i)); + } + } + } + + @GuardedBy("mLock") + public void deleteAllDynamicShortcuts(@NonNull ShortcutService s) { + for (int i = mShortcuts.size() - 1; i >= 0; i--) { + mShortcuts.valueAt(i).clearFlags(ShortcutInfo.FLAG_DYNAMIC); + } + removeOrphans(s); + mDynamicShortcutCount = 0; + } + + @GuardedBy("mLock") + public void deleteDynamicWithId(@NonNull ShortcutService s, @NonNull String shortcutId) { + final ShortcutInfo oldShortcut = mShortcuts.get(shortcutId); + + if (oldShortcut == null) { + return; + } + if (oldShortcut.isDynamic()) { + mDynamicShortcutCount--; + } + if (oldShortcut.isPinned()) { + oldShortcut.clearFlags(ShortcutInfo.FLAG_DYNAMIC); + } else { + deleteShortcut(s, shortcutId); + } + } + + @GuardedBy("mLock") + public void replacePinned(@NonNull ShortcutService s, String launcherPackage, + List<String> shortcutIds) { + + // TODO Should be per launcherPackage. + + // First, un-pin all shortcuts + for (int i = mShortcuts.size() - 1; i >= 0; i--) { + mShortcuts.valueAt(i).clearFlags(ShortcutInfo.FLAG_PINNED); + } + + // Then pin ALL + for (int i = shortcutIds.size() - 1; i >= 0; i--) { + final ShortcutInfo shortcut = mShortcuts.get(shortcutIds.get(i)); + if (shortcut != null) { + shortcut.addFlags(ShortcutInfo.FLAG_PINNED); + } + } + + removeOrphans(s); + } + + /** + * Number of calls that the caller has made, since the last reset. + */ + @GuardedBy("mLock") + public int getApiCallCount(@NonNull ShortcutService s) { + final long last = s.getLastResetTimeLocked(); + + final long now = s.injectCurrentTimeMillis(); + if (mLastResetTime > now) { + // Clock rewound. // TODO Test it + mLastResetTime = now; + } + + // If not reset yet, then reset. + if (mLastResetTime < last) { + mApiCallCount = 0; + mLastResetTime = last; + } + return mApiCallCount; + } + + /** + * If the caller app hasn't been throttled yet, increment {@link #mApiCallCount} + * and return true. Otherwise just return false. + */ + @GuardedBy("mLock") + public boolean tryApiCall(@NonNull ShortcutService s) { + if (getApiCallCount(s) >= s.mMaxDailyUpdates) { + return false; + } + mApiCallCount++; + return true; + } + + @GuardedBy("mLock") + public void resetRateLimitingForCommandLine() { + mApiCallCount = 0; + mLastResetTime = 0; + } + + /** + * Find all shortcuts that match {@code query}. + */ + @GuardedBy("mLock") + public void findAll(@NonNull List<ShortcutInfo> result, + @Nullable Predicate<ShortcutInfo> query, int cloneFlag) { + for (int i = 0; i < mShortcuts.size(); i++) { + final ShortcutInfo si = mShortcuts.valueAt(i); + if (query == null || query.test(si)) { + result.add(si.clone(cloneFlag)); + } + } + } + + public void dump(@NonNull ShortcutService s, @NonNull PrintWriter pw, @NonNull String prefix) { + pw.print(prefix); + pw.print("Package: "); + pw.print(mPackageName); + pw.println(); + + pw.print(prefix); + pw.print(" "); + pw.print("Calls: "); + pw.print(getApiCallCount(s)); + pw.println(); + + // This should be after getApiCallCount(), which may update it. + pw.print(prefix); + pw.print(" "); + pw.print("Last reset: ["); + pw.print(mLastResetTime); + pw.print("] "); + pw.print(s.formatTime(mLastResetTime)); + pw.println(); + + pw.println(" Shortcuts:"); + long totalBitmapSize = 0; + final ArrayMap<String, ShortcutInfo> shortcuts = mShortcuts; + final int size = shortcuts.size(); + for (int i = 0; i < size; i++) { + final ShortcutInfo si = shortcuts.valueAt(i); + pw.print(" "); + pw.println(si.toInsecureString()); + if (si.getBitmapPath() != null) { + final long len = new File(si.getBitmapPath()).length(); + pw.print(" "); + pw.print("bitmap size="); + pw.println(len); + + totalBitmapSize += len; + } + } + pw.print(prefix); + pw.print(" "); + pw.print("Total bitmap size: "); + pw.print(totalBitmapSize); + pw.print(" ("); + pw.print(Formatter.formatFileSize(s.mContext, totalBitmapSize)); + pw.println(")"); + } + + public void saveToXml(@NonNull XmlSerializer out) throws IOException, XmlPullParserException { + out.startTag(null, ShortcutService.TAG_PACKAGE); + + ShortcutService.writeAttr(out, ShortcutService.ATTR_NAME, mPackageName); + ShortcutService.writeAttr(out, ShortcutService.ATTR_DYNAMIC_COUNT, mDynamicShortcutCount); + ShortcutService.writeAttr(out, ShortcutService.ATTR_CALL_COUNT, mApiCallCount); + ShortcutService.writeAttr(out, ShortcutService.ATTR_LAST_RESET, mLastResetTime); + + final int size = mShortcuts.size(); + for (int j = 0; j < size; j++) { + saveShortcut(out, mShortcuts.valueAt(j)); + } + + out.endTag(null, ShortcutService.TAG_PACKAGE); + } + + private static void saveShortcut(XmlSerializer out, ShortcutInfo si) + throws IOException, XmlPullParserException { + out.startTag(null, ShortcutService.TAG_SHORTCUT); + ShortcutService.writeAttr(out, ShortcutService.ATTR_ID, si.getId()); + // writeAttr(out, "package", si.getPackageName()); // not needed + ShortcutService.writeAttr(out, ShortcutService.ATTR_ACTIVITY, si.getActivityComponent()); + // writeAttr(out, "icon", si.getIcon()); // We don't save it. + ShortcutService.writeAttr(out, ShortcutService.ATTR_TITLE, si.getTitle()); + ShortcutService.writeAttr(out, ShortcutService.ATTR_INTENT, si.getIntentNoExtras()); + ShortcutService.writeAttr(out, ShortcutService.ATTR_WEIGHT, si.getWeight()); + ShortcutService.writeAttr(out, ShortcutService.ATTR_TIMESTAMP, + si.getLastChangedTimestamp()); + ShortcutService.writeAttr(out, ShortcutService.ATTR_FLAGS, si.getFlags()); + ShortcutService.writeAttr(out, ShortcutService.ATTR_ICON_RES, si.getIconResourceId()); + ShortcutService.writeAttr(out, ShortcutService.ATTR_BITMAP_PATH, si.getBitmapPath()); + + ShortcutService.writeTagExtra(out, ShortcutService.TAG_INTENT_EXTRAS, + si.getIntentPersistableExtras()); + ShortcutService.writeTagExtra(out, ShortcutService.TAG_EXTRAS, si.getExtras()); + + out.endTag(null, ShortcutService.TAG_SHORTCUT); + } + + public static PackageShortcuts loadFromXml(XmlPullParser parser, int userId) + throws IOException, XmlPullParserException { + + final String packageName = ShortcutService.parseStringAttribute(parser, + ShortcutService.ATTR_NAME); + + final PackageShortcuts ret = new PackageShortcuts(userId, packageName); + + ret.mDynamicShortcutCount = + ShortcutService.parseIntAttribute(parser, ShortcutService.ATTR_DYNAMIC_COUNT); + ret.mApiCallCount = + ShortcutService.parseIntAttribute(parser, ShortcutService.ATTR_CALL_COUNT); + ret.mLastResetTime = + ShortcutService.parseLongAttribute(parser, ShortcutService.ATTR_LAST_RESET); + + 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_SHORTCUT: + final ShortcutInfo si = parseShortcut(parser, packageName); + + // Don't use addShortcut(), we don't need to save the icon. + ret.mShortcuts.put(si.getId(), si); + continue; + } + throw ShortcutService.throwForInvalidTag(depth, tag); + } + return ret; + } + + private static ShortcutInfo parseShortcut(XmlPullParser parser, String packageName) + throws IOException, XmlPullParserException { + String id; + ComponentName activityComponent; + // Icon icon; + String title; + Intent intent; + PersistableBundle intentPersistableExtras = null; + int weight; + PersistableBundle extras = null; + long lastChangedTimestamp; + int flags; + int iconRes; + String bitmapPath; + + id = ShortcutService.parseStringAttribute(parser, ShortcutService.ATTR_ID); + activityComponent = ShortcutService.parseComponentNameAttribute(parser, + ShortcutService.ATTR_ACTIVITY); + title = ShortcutService.parseStringAttribute(parser, ShortcutService.ATTR_TITLE); + intent = ShortcutService.parseIntentAttribute(parser, ShortcutService.ATTR_INTENT); + weight = (int) ShortcutService.parseLongAttribute(parser, ShortcutService.ATTR_WEIGHT); + lastChangedTimestamp = (int) ShortcutService.parseLongAttribute(parser, + ShortcutService.ATTR_TIMESTAMP); + flags = (int) ShortcutService.parseLongAttribute(parser, ShortcutService.ATTR_FLAGS); + iconRes = (int) ShortcutService.parseLongAttribute(parser, ShortcutService.ATTR_ICON_RES); + bitmapPath = ShortcutService.parseStringAttribute(parser, ShortcutService.ATTR_BITMAP_PATH); + + 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(); + if (ShortcutService.DEBUG_LOAD) { + Slog.d(TAG, String.format(" depth=%d type=%d name=%s", + depth, type, tag)); + } + switch (tag) { + case ShortcutService.TAG_INTENT_EXTRAS: + intentPersistableExtras = PersistableBundle.restoreFromXml(parser); + continue; + case ShortcutService.TAG_EXTRAS: + extras = PersistableBundle.restoreFromXml(parser); + continue; + } + throw ShortcutService.throwForInvalidTag(depth, tag); + } + return new ShortcutInfo( + id, packageName, activityComponent, /* icon =*/ null, title, intent, + intentPersistableExtras, weight, extras, lastChangedTimestamp, flags, + iconRes, bitmapPath); } } diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 549026090a49..8206bdab255d 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -50,6 +50,7 @@ import android.os.PersistableBundle; import android.os.Process; import android.os.RemoteException; import android.os.ResultReceiver; +import android.os.SELinux; import android.os.ServiceManager; import android.os.ShellCommand; import android.os.UserHandle; @@ -758,23 +759,28 @@ public class UserManagerService extends IUserManager.Stub { } @Override - public ParcelFileDescriptor getUserIcon(int userId) { + public ParcelFileDescriptor getUserIcon(int targetUserId) { String iconPath; synchronized (mPackagesLock) { - UserInfo info = getUserInfoNoChecks(userId); - if (info == null || info.partial) { - Slog.w(LOG_TAG, "getUserIcon: unknown user #" + userId); + UserInfo targetUserInfo = getUserInfoNoChecks(targetUserId); + if (targetUserInfo == null || targetUserInfo.partial) { + Slog.w(LOG_TAG, "getUserIcon: unknown user #" + targetUserId); return null; } - int callingGroupId = getUserInfoNoChecks(UserHandle.getCallingUserId()).profileGroupId; - if (callingGroupId == UserInfo.NO_PROFILE_GROUP_ID - || callingGroupId != info.profileGroupId) { + + final int callingUserId = UserHandle.getCallingUserId(); + final int callingGroupId = getUserInfoNoChecks(callingUserId).profileGroupId; + final int targetGroupId = targetUserInfo.profileGroupId; + final boolean sameGroup = (callingGroupId != UserInfo.NO_PROFILE_GROUP_ID + && callingGroupId == targetGroupId); + if ((callingUserId != targetUserId) && !sameGroup) { checkManageUsersPermission("get the icon of a user who is not related"); } - if (info.iconPath == null) { + + if (targetUserInfo.iconPath == null) { return null; } - iconPath = info.iconPath; + iconPath = targetUserInfo.iconPath; } try { @@ -1229,7 +1235,7 @@ public class UserManagerService extends IUserManager.Stub { } FileOutputStream os; if (bitmap.compress(Bitmap.CompressFormat.PNG, 100, os = new FileOutputStream(tmp)) - && tmp.renameTo(file)) { + && tmp.renameTo(file) && SELinux.restorecon(file)) { info.iconPath = file.getAbsolutePath(); } try { diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 1603f1c12cd0..9af1304afc68 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; @@ -211,6 +214,13 @@ public class PhoneWindowManager implements WindowManagerPolicy { static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP = 0; static final int SHORT_PRESS_SLEEP_GO_TO_SLEEP_AND_GO_HOME = 1; + // Controls navigation bar opacity depending on which workspace stacks are currently + // visible. + // Nav bar is always opaque when either the freeform stack or docked stack is visible. + static final int NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED = 0; + // Nav bar is always translucent when the freeform stack is visible, otherwise always opaque. + static final int NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE = 1; + static final int APPLICATION_MEDIA_SUBLAYER = -2; static final int APPLICATION_MEDIA_OVERLAY_SUBLAYER = -1; static final int APPLICATION_PANEL_SUBLAYER = 1; @@ -244,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 */ @@ -378,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; @@ -430,6 +447,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { int mLongPressOnPowerBehavior; int mDoublePressOnPowerBehavior; int mTriplePressOnPowerBehavior; + int mLongPressOnBackBehavior; int mShortPressOnSleepBehavior; int mShortPressWindowBehavior; boolean mAwake; @@ -539,7 +557,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { boolean mForceStatusBar; boolean mForceStatusBarFromKeyguard; private boolean mForceStatusBarTransparent; - boolean mForceNavBarOpaque; + int mNavBarOpacityMode = NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED; boolean mHideLockScreen; boolean mForcingShowNavBar; int mForcingShowNavBarLayer; @@ -686,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; @@ -750,6 +769,9 @@ public class PhoneWindowManager implements WindowManagerPolicy { case MSG_REQUEST_TV_PICTURE_IN_PICTURE: requestTvPictureInPictureInternal(); break; + case MSG_BACK_LONG_PRESS: + backLongPress(); + break; } } } @@ -1096,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 " @@ -1203,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*/); @@ -1231,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 @@ -1560,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( @@ -1729,8 +1778,8 @@ public class PhoneWindowManager implements WindowManagerPolicy { mShortPressWindowBehavior = SHORT_PRESS_WINDOW_PICTURE_IN_PICTURE; } - mForceNavBarOpaque = res.getBoolean( - com.android.internal.R.bool.config_forceNavBarAlwaysOpaque); + mNavBarOpacityMode = res.getInteger( + com.android.internal.R.integer.config_navBarOpacityMode); } @Override @@ -5179,6 +5228,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { if (mScreenshotConnection != null) { mContext.unbindService(mScreenshotConnection); mScreenshotConnection = null; + notifyScreenshotError(); } } } @@ -5190,10 +5240,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) { @@ -5228,17 +5278,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) { @@ -5309,6 +5377,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: { @@ -7093,7 +7184,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { // is visible but also when we are resizing for the transitions when docked stack // visibility changes. mForceShowSystemBars = dockedStackVisible || freeformStackVisible || resizing; - final boolean forceOpaqueSystemBars = mForceShowSystemBars && !mForceStatusBarFromKeyguard; + final boolean forceOpaqueStatusBar = mForceShowSystemBars && !mForceStatusBarFromKeyguard; // apply translucent bar vis flags WindowState transWin = isStatusBarKeyguard() && !mHideLockScreen @@ -7118,14 +7209,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { } if ((!areTranslucentBarsAllowed() && transWin != mStatusBar) - || forceOpaqueSystemBars) { - vis &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSLUCENT - | View.SYSTEM_UI_TRANSPARENT); + || forceOpaqueStatusBar) { + vis &= ~(View.STATUS_BAR_TRANSLUCENT | View.STATUS_BAR_TRANSPARENT); } - if (mForceNavBarOpaque) { - vis &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT); - } + vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing); if (mForceWindowDrawsStatusBarBackground) { vis |= View.STATUS_BAR_TRANSPARENT; @@ -7199,6 +7287,41 @@ public class PhoneWindowManager implements WindowManagerPolicy { return vis; } + /** + * @return the current visibility flags with the nav-bar opacity related flags toggled based + * on the nav bar opacity rules chosen by {@link #mNavBarOpacityMode}. + */ + private int configureNavBarOpacity(int visibility, boolean dockedStackVisible, + boolean freeformStackVisible, boolean isDockedDividerResizing) { + if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) { + if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) { + visibility = setNavBarOpaqueFlag(visibility); + } + } else if (mNavBarOpacityMode == NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE) { + if (isDockedDividerResizing) { + visibility = setNavBarOpaqueFlag(visibility); + } else if (freeformStackVisible) { + visibility = setNavBarTranslucentFlag(visibility); + } else { + visibility = setNavBarOpaqueFlag(visibility); + } + } + + if (!areTranslucentBarsAllowed()) { + visibility &= ~View.NAVIGATION_BAR_TRANSLUCENT; + } + return visibility; + } + + private int setNavBarOpaqueFlag(int visibility) { + return visibility &= ~(View.NAVIGATION_BAR_TRANSLUCENT | View.NAVIGATION_BAR_TRANSPARENT); + } + + private int setNavBarTranslucentFlag(int visibility) { + visibility &= ~View.NAVIGATION_BAR_TRANSPARENT; + return visibility |= View.NAVIGATION_BAR_TRANSLUCENT; + } + private void clearClearableFlagsLw() { int newVal = mResettingSystemUiFlags | View.SYSTEM_UI_CLEARABLE_FLAGS; if (newVal != mResettingSystemUiFlags) { @@ -7326,6 +7449,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/webkit/WebViewUpdateService.java b/services/core/java/com/android/server/webkit/WebViewUpdateService.java index 9c770e1fdd27..2db6b5d4bf90 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdateService.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdateService.java @@ -190,7 +190,7 @@ public class WebViewUpdateService extends SystemService { userAddedFilter.addAction(Intent.ACTION_USER_ADDED); getContext().registerReceiver(mWebViewUpdatedReceiver, userAddedFilter); - publishBinderService("webviewupdate", new BinderService()); + publishBinderService("webviewupdate", new BinderService(), true /*allowIsolated*/); } private static boolean existsValidNonFallbackProvider(WebViewProviderInfo[] providers) { diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java index 73cea52adb0f..521221136c80 100644 --- a/services/core/java/com/android/server/wm/DisplayContent.java +++ b/services/core/java/com/android/server/wm/DisplayContent.java @@ -29,6 +29,7 @@ import static com.android.server.wm.WindowState.RESIZE_HANDLE_WIDTH_IN_DP; import android.app.ActivityManager.StackId; import android.graphics.Rect; import android.graphics.Region; +import android.graphics.Region.Op; import android.util.DisplayMetrics; import android.util.Slog; import android.view.Display; @@ -426,6 +427,10 @@ class DisplayContent { win.getTouchableRegion(mTmpRegion); mTouchExcludeRegion.op(mTmpRegion, Region.Op.UNION); } + if (getDockedStackVisibleForUserLocked() != null) { + mDividerControllerLocked.getTouchRegion(mTmpRect); + mTouchExcludeRegion.op(mTmpRegion, Op.UNION); + } if (mTapDetector != null) { mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion, mNonResizeableRegion); } diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java index 9bceee72b8dc..36e8bbbf4638 100644 --- a/services/core/java/com/android/server/wm/DockedStackDividerController.java +++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java @@ -95,6 +95,7 @@ public class DockedStackDividerController implements DimLayerUser { private long mAnimationDuration; private final Interpolator mMinimizedDockInterpolator; private float mMaximizeMeetFraction; + private final Rect mTouchRegion = new Rect(); DockedStackDividerController(WindowManagerService service, DisplayContent displayContent) { mService = service; @@ -129,6 +130,15 @@ public class DockedStackDividerController implements DimLayerUser { } } + void setTouchRegion(Rect touchRegion) { + mTouchRegion.set(touchRegion); + } + + void getTouchRegion(Rect outRegion) { + outRegion.set(mTouchRegion); + outRegion.offset(mWindow.getFrameLw().left, mWindow.getFrameLw().top); + } + private void resetDragResizingChangeReported() { final WindowList windowList = mDisplayContent.getWindowList(); for (int i = windowList.size() - 1; i >= 0; i--) { diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java index 676b90fd4d38..60b2e4a68f6d 100644 --- a/services/core/java/com/android/server/wm/TaskStack.java +++ b/services/core/java/com/android/server/wm/TaskStack.java @@ -148,9 +148,7 @@ public class TaskStack implements DimLayer.DimLayerUser, boolean setBounds( Rect stackBounds, SparseArray<Configuration> configs, SparseArray<Rect> taskBounds, SparseArray<Rect> taskTempInsetBounds) { - if (!setBounds(stackBounds)) { - return false; - } + setBounds(stackBounds); // Update bounds of containing tasks. for (int taskNdx = mTasks.size() - 1; taskNdx >= 0; --taskNdx) { @@ -608,13 +606,6 @@ public class TaskStack implements DimLayer.DimLayerUser, } updateDisplayInfo(bounds); - - if (mStackId == DOCKED_STACK_ID) { - // Attaching a docked stack to the display affects the size of all other static - // stacks since the docked stack occupies a dedicated region on screen. - // Resize existing static stacks so they are pushed to the side of the docked stack. - resizeNonDockedStacks(!FULLSCREEN, mBounds); - } } void getStackDockedModeBoundsLocked(Rect outBounds, boolean ignoreVisibility) { @@ -723,36 +714,6 @@ public class TaskStack implements DimLayer.DimLayerUser, DockedDividerUtils.sanitizeStackBounds(outBounds, !dockOnTopOrLeft); } - /** Resizes all non-docked stacks in the system to either fullscreen or the appropriate size - * based on the presence of a docked stack. - * @param fullscreen If true the stacks will be resized to fullscreen, else they will be - * resized to the appropriate size based on the presence of a docked stack. - * @param dockedBounds Bounds of the docked stack. - */ - private void resizeNonDockedStacks(boolean fullscreen, Rect dockedBounds) { - // Not using mTmpRect because we are posting the object in a message. - final Rect bounds = new Rect(); - mDisplayContent.getLogicalDisplayRect(bounds); - if (!fullscreen) { - final boolean dockedOnTopOrLeft = mService.mDockedStackCreateMode - == DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT; - getStackDockedModeBounds(bounds, bounds, FULLSCREEN_WORKSPACE_STACK_ID, dockedBounds, - mDisplayContent.mDividerControllerLocked.getContentWidth(), dockedOnTopOrLeft); - } - - final int count = mService.mStackIdToStack.size(); - for (int i = 0; i < count; i++) { - final TaskStack otherStack = mService.mStackIdToStack.valueAt(i); - final int otherStackId = otherStack.mStackId; - if (StackId.isResizeableByDockedStack(otherStackId) - && !otherStack.mBounds.equals(bounds)) { - mService.mH.sendMessage( - mService.mH.obtainMessage(RESIZE_STACK, otherStackId, - 1 /*allowResizeInDockedMode*/, fullscreen ? null : bounds)); - } - } - } - void resetDockedStackToMiddle() { if (mStackId != DOCKED_STACK_ID) { throw new IllegalStateException("Not a docked stack=" + this); @@ -786,12 +747,6 @@ public class TaskStack implements DimLayer.DimLayerUser, mService.mWindowPlacerLocked.requestTraversal(); } - if (mStackId == DOCKED_STACK_ID) { - // Docked stack was detached from the display, so we no longer need to restrict the - // region of the screen other static stacks occupy. Go ahead and make them fullscreen. - resizeNonDockedStacks(FULLSCREEN, null); - } - close(); } diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java index a998bc3be63b..304449dd9f98 100644 --- a/services/core/java/com/android/server/wm/WindowManagerService.java +++ b/services/core/java/com/android/server/wm/WindowManagerService.java @@ -10438,6 +10438,15 @@ public class WindowManagerService extends IWindowManager.Stub } @Override + public void setDockedStackDividerTouchRegion(Rect touchRegion) { + synchronized (mWindowMap) { + getDefaultDisplayContentLocked().getDockedDividerController() + .setTouchRegion(touchRegion); + setFocusTaskRegionLocked(); + } + } + + @Override public void setResizeDimLayer(boolean visible, int targetStackId, float alpha) { synchronized (mWindowMap) { getDefaultDisplayContentLocked().getDockedDividerController().setResizeDimLayer( diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 617d2b4d28e3..910788ea8b91 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -780,9 +780,9 @@ final class WindowState implements WindowManagerPolicy.WindowState { Math.min(mStableFrame.bottom, frame.bottom)); } - if (!windowsAreFloating) { - // Windows from floating tasks (e.g. freeform, pinned) may be positioned outside - // of the display frame, but that is not a reason to provide them with overscan insets. + if (fullscreenTask && !windowsAreFloating) { + // Windows that are not fullscreen can be positioned outside of the display frame, + // but that is not a reason to provide them with overscan insets. mOverscanInsets.set(Math.max(mOverscanFrame.left - frame.left, 0), Math.max(mOverscanFrame.top - frame.top, 0), Math.max(frame.right - mOverscanFrame.right, 0), @@ -2257,7 +2257,7 @@ final class WindowState implements WindowManagerPolicy.WindowState { // background. return (mDisplayContent.mDividerControllerLocked.isResizing() || mAppToken != null && !mAppToken.mFrozenBounds.isEmpty()) && - !task.inFreeformWorkspace() && isVisibleLw(); + !task.inFreeformWorkspace() && !isGoneForLayoutLw(); } diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp index 60ed4977f984..e2c71a1aa2f8 100644 --- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp +++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp @@ -1087,8 +1087,25 @@ template<> const char *const JavaMethodHelper<bool>::signature_ = "(Z)V"; #define SET(setter, value) object.callSetter("set" # setter, (value)) -#define SET_IF(flag, setter, value) \ - if (flags & (flag)) object.callSetter("set" # setter, (value)) + +// If you want to check if a flag is not set, use SET_IF_NOT(FLAG, setter, +// value) to do that. SET_IF(!FLAG, setter, value) won't compile. +// +// This macros generates compilation error if the provided 'flag' is not a +// single token. For example, 'GNSS_CLOCK_HAS_BIAS' can be accepted, but +// '!GNSS_CLOCK_HAS_DRIFT' will fail to compile. +#define SET_IF(flag, setter, value) do { \ + if (flags & flag) { \ + JavaObject& name_check_##flag = object; \ + name_check_##flag.callSetter("set" # setter, (value)); \ + } \ + } while (false) +#define SET_IF_NOT(flag, setter, value) do { \ + if (!(flags & flag)) { \ + JavaObject& name_check_##flag = object; \ + name_check_##flag.callSetter("set" # setter, (value)); \ + } \ + } while (false) static jobject translate_gps_clock(JNIEnv* env, GpsClock* clock) { static uint32_t discontinuity_count_to_handle_old_lock_type = 0; @@ -1209,6 +1226,10 @@ static jobject translate_gps_measurement(JNIEnv* env, static_cast<int32_t>(measurement->multipath_indicator)); SET_IF(GNSS_MEASUREMENT_HAS_SNR, SnrInDb, measurement->snr_db); + SET_IF_NOT(GPS_MEASUREMENT_HAS_UNCORRECTED_PSEUDORANGE_RATE, + PseudorangeRateCorrected, + true); + return object.get(); } 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 4831db5f3dc3..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(); } @@ -1637,14 +1655,12 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } // Still at the first stage of CryptKeeper double bounce, mOwners.hasDeviceOwner is // always false at this point. - if ("encrypted".equals(mInjector.systemPropertiesGet("ro.crypto.state")) - && "trigger_restart_min_framework".equals( - mInjector.systemPropertiesGet("vold.decrypt"))){ + if (StorageManager.inCryptKeeperBounce()) { return; } if (!TextUtils.isEmpty(mInjector.systemPropertiesGet(PROPERTY_DEVICE_OWNER_PRESENT))) { - Slog.wtf(LOG_TAG, "Trying to set ro.device_owner, but it has already been set?"); + Slog.w(LOG_TAG, "Trying to set ro.device_owner, but it has already been set?"); } else { if (mOwners.hasDeviceOwner()) { mInjector.systemPropertiesSet(PROPERTY_DEVICE_OWNER_PRESENT, "true"); @@ -2868,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 @@ -4238,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; @@ -4837,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; } /** @@ -4860,21 +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() { - String status = mInjector.systemPropertiesGet("ro.crypto.state", "unsupported"); - if ("encrypted".equalsIgnoreCase(status)) { - final long token = mInjector.binderClearCallingIdentity(); - try { - return LockPatternUtils.isDeviceEncrypted() - ? DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE - : DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY; - } finally { - mInjector.binderRestoreCallingIdentity(token); - } - } else if ("unencrypted".equalsIgnoreCase(status)) { + 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; @@ -4887,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. */ @@ -6045,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); } @@ -6130,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"; } } @@ -8215,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/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index 59f8284a5200..e7daaa15d247 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -726,9 +726,6 @@ public final class SystemServer { // Always start the Device Policy Manager, so that the API is compatible with // API8. mSystemServiceManager.startService(DevicePolicyManagerService.Lifecycle.class); - -// TODO is this a good place? - mSystemServiceManager.startService(ShortcutService.Lifecycle.class); } if (!disableSystemUI) { @@ -1139,6 +1136,8 @@ public final class SystemServer { } Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER); } + // LauncherAppsService uses ShortcutService. + mSystemServiceManager.startService(ShortcutService.Lifecycle.class); mSystemServiceManager.startService(LauncherAppsService.class); } diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java index 6a255e599631..e27f69efbe83 100644 --- a/services/net/java/android/net/dhcp/DhcpPacket.java +++ b/services/net/java/android/net/dhcp/DhcpPacket.java @@ -819,7 +819,11 @@ abstract class DhcpPacket { // server-to-server packets, e.g. for relays. if (!isPacketToOrFromClient(udpSrcPort, udpDstPort) && !isPacketServerToServer(udpSrcPort, udpDstPort)) { - return null; + // This should almost never happen because we use SO_ATTACH_FILTER on the packet + // socket to drop packets that don't have the right source ports. However, it's + // possible that a packet arrives between when the socket is bound and when the + // filter is set. http://b/26696823 . + throw new ParseException("Unexpected UDP ports %d->%d", udpSrcPort, udpDstPort); } } diff --git a/services/tests/servicestests/res/drawable-nodpi/black_1024x4096.png b/services/tests/servicestests/res/drawable-nodpi/black_1024x4096.png Binary files differnew file mode 100644 index 000000000000..f70032698896 --- /dev/null +++ b/services/tests/servicestests/res/drawable-nodpi/black_1024x4096.png diff --git a/services/tests/servicestests/res/drawable-nodpi/black_16x64.png b/services/tests/servicestests/res/drawable-nodpi/black_16x64.png Binary files differnew file mode 100644 index 000000000000..315763e45602 --- /dev/null +++ b/services/tests/servicestests/res/drawable-nodpi/black_16x64.png diff --git a/services/tests/servicestests/res/drawable-nodpi/black_32x32.png b/services/tests/servicestests/res/drawable-nodpi/black_32x32.png Binary files differnew file mode 100644 index 000000000000..8958f6b1eabd --- /dev/null +++ b/services/tests/servicestests/res/drawable-nodpi/black_32x32.png diff --git a/services/tests/servicestests/res/drawable-nodpi/black_4096x1024.png b/services/tests/servicestests/res/drawable-nodpi/black_4096x1024.png Binary files differnew file mode 100644 index 000000000000..f67503017734 --- /dev/null +++ b/services/tests/servicestests/res/drawable-nodpi/black_4096x1024.png diff --git a/services/tests/servicestests/res/drawable-nodpi/black_4096x4096.png b/services/tests/servicestests/res/drawable-nodpi/black_4096x4096.png Binary files differnew file mode 100644 index 000000000000..999d8585fc6f --- /dev/null +++ b/services/tests/servicestests/res/drawable-nodpi/black_4096x4096.png diff --git a/services/tests/servicestests/res/drawable-nodpi/black_512x512.png b/services/tests/servicestests/res/drawable-nodpi/black_512x512.png Binary files differnew file mode 100644 index 000000000000..40d1c2c41f14 --- /dev/null +++ b/services/tests/servicestests/res/drawable-nodpi/black_512x512.png diff --git a/services/tests/servicestests/res/drawable-nodpi/black_64x16.png b/services/tests/servicestests/res/drawable-nodpi/black_64x16.png Binary files differnew file mode 100644 index 000000000000..588301519975 --- /dev/null +++ b/services/tests/servicestests/res/drawable-nodpi/black_64x16.png diff --git a/services/tests/servicestests/res/drawable-nodpi/black_64x64.png b/services/tests/servicestests/res/drawable-nodpi/black_64x64.png Binary files differnew file mode 100644 index 000000000000..71cfafc2ad30 --- /dev/null +++ b/services/tests/servicestests/res/drawable-nodpi/black_64x64.png diff --git a/services/tests/servicestests/res/drawable-nodpi/icon1.png b/services/tests/servicestests/res/drawable-nodpi/icon1.png Binary files differnew file mode 100644 index 000000000000..64eb294363d2 --- /dev/null +++ b/services/tests/servicestests/res/drawable-nodpi/icon1.png diff --git a/services/tests/servicestests/res/drawable-nodpi/icon2.png b/services/tests/servicestests/res/drawable-nodpi/icon2.png Binary files differnew file mode 100644 index 000000000000..75024841d327 --- /dev/null +++ b/services/tests/servicestests/res/drawable-nodpi/icon2.png diff --git a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java index 2a967e651f04..c322ab8cce0a 100644 --- a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java +++ b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java @@ -558,6 +558,39 @@ public class DhcpPacketTest extends TestCase { } @SmallTest + public void testUdpInvalidDstPort() throws Exception { + final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode(( + // Ethernet header. + "9cd917000000001c2e0000000800" + + // IP header. + "45a00148000040003d115087d18194fb0a0f7af2" + + // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation). + // NOTE: The destination port is a non-DHCP port. + "0043aaaa01341268" + + // BOOTP header. + "02010600d628ba8200000000000000000a0f7af2000000000a0fc818" + + // MAC address. + "9cd91700000000000000000000000000" + + // Server name. + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + // File. + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + "0000000000000000000000000000000000000000000000000000000000000000" + + // Options. + "6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" + + "d18180060f0777766d2e6564751c040a0fffffff000000" + ).toCharArray(), false)); + + try { + DhcpPacket.decodeFullPacket(packet, ENCAP_L2); + fail("Packet with invalid dst port did not throw ParseException"); + } catch (ParseException expected) {} + } + + @SmallTest public void testMultipleRouters() throws Exception { final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode(( // Ethernet header. diff --git a/services/tests/servicestests/src/com/android/server/DropBoxTest.java b/services/tests/servicestests/src/com/android/server/DropBoxTest.java index 055ce7609413..7f28d442c777 100644 --- a/services/tests/servicestests/src/com/android/server/DropBoxTest.java +++ b/services/tests/servicestests/src/com/android/server/DropBoxTest.java @@ -54,7 +54,7 @@ public class DropBoxTest extends AndroidTestCase { public void testAddText() throws Exception { File dir = getEmptyDir("testAddText"); DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); - DropBoxManager dropbox = new DropBoxManager(service.getServiceStub()); + DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); long before = System.currentTimeMillis(); Thread.sleep(5); @@ -90,7 +90,7 @@ public class DropBoxTest extends AndroidTestCase { public void testAddData() throws Exception { File dir = getEmptyDir("testAddData"); DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); - DropBoxManager dropbox = new DropBoxManager(service.getServiceStub()); + DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); long before = System.currentTimeMillis(); dropbox.addData("DropBoxTest", "TEST".getBytes(), 0); @@ -135,7 +135,7 @@ public class DropBoxTest extends AndroidTestCase { gz3.close(); DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); - DropBoxManager dropbox = new DropBoxManager(service.getServiceStub()); + DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); dropbox.addFile("DropBoxTest", f0, DropBoxManager.IS_TEXT); dropbox.addFile("DropBoxTest", f1, DropBoxManager.IS_TEXT | DropBoxManager.IS_GZIPPED); @@ -201,7 +201,7 @@ public class DropBoxTest extends AndroidTestCase { new FileOutputStream(new File(dir, "DropBoxTest@" + (before + 100002) + ".lost")).close(); DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); - DropBoxManager dropbox = new DropBoxManager(service.getServiceStub()); + DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); // Until a write, the timestamps are taken at face value DropBoxManager.Entry e0 = dropbox.getNextEntry(null, before); @@ -252,7 +252,7 @@ public class DropBoxTest extends AndroidTestCase { public void testIsTagEnabled() throws Exception { File dir = getEmptyDir("testIsTagEnabled"); DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); - DropBoxManager dropbox = new DropBoxManager(service.getServiceStub()); + DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); long before = System.currentTimeMillis(); dropbox.addText("DropBoxTest", "TEST-ENABLED"); @@ -285,7 +285,7 @@ public class DropBoxTest extends AndroidTestCase { public void testGetNextEntry() throws Exception { File dir = getEmptyDir("testGetNextEntry"); DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); - DropBoxManager dropbox = new DropBoxManager(service.getServiceStub()); + DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); long before = System.currentTimeMillis(); dropbox.addText("DropBoxTest.A", "A0"); @@ -347,7 +347,7 @@ public class DropBoxTest extends AndroidTestCase { final int overhead = 64; long before = System.currentTimeMillis(); DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); - DropBoxManager dropbox = new DropBoxManager(service.getServiceStub()); + DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); addRandomEntry(dropbox, "DropBoxTest0", blockSize - overhead); addRandomEntry(dropbox, "DropBoxTest0", blockSize - overhead); @@ -441,7 +441,7 @@ public class DropBoxTest extends AndroidTestCase { // Write one normal entry and another so big that it is instantly tombstoned long before = System.currentTimeMillis(); DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); - DropBoxManager dropbox = new DropBoxManager(service.getServiceStub()); + DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); dropbox.addText("DropBoxTest", "TEST"); addRandomEntry(dropbox, "DropBoxTest", blockSize * 20); @@ -472,7 +472,7 @@ public class DropBoxTest extends AndroidTestCase { File dir = getEmptyDir("testFileCountLimits"); DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); - DropBoxManager dropbox = new DropBoxManager(service.getServiceStub()); + DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); dropbox.addText("DropBoxTest", "TEST0"); dropbox.addText("DropBoxTest", "TEST1"); dropbox.addText("DropBoxTest", "TEST2"); @@ -525,7 +525,7 @@ public class DropBoxTest extends AndroidTestCase { File dir = new File(getEmptyDir("testCreateDropBoxManagerWith"), "InvalidDirectory"); new FileOutputStream(dir).close(); // Create an empty file DropBoxManagerService service = new DropBoxManagerService(getContext(), dir); - DropBoxManager dropbox = new DropBoxManager(service.getServiceStub()); + DropBoxManager dropbox = new DropBoxManager(getContext(), service.getServiceStub()); dropbox.addText("DropBoxTest", "should be ignored"); dropbox.addData("DropBoxTest", "should be ignored".getBytes(), 0); 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 1f805e9116ba..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,29 +15,46 @@ */ 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; +import android.content.res.Resources; +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; import android.util.Log; 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; + +import libcore.io.IoUtils; import org.junit.Assert; @@ -45,13 +62,16 @@ import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileReader; +import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; /** * Tests for ShortcutService and ShortcutManager. @@ -61,7 +81,15 @@ import java.util.Map; -r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk && adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest \ -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 { private static final String TAG = "ShortcutManagerTest"; @@ -69,10 +97,31 @@ public class ShortcutManagerTest extends AndroidTestCase { * Whether to enable dump or not. Should be only true when debugging to avoid bugs where * dump affecting the behavior. */ - private static final boolean ENABLE_DUMP = true; // DO NOT SUBMIT WITH true + private static final boolean ENABLE_DUMP = false; // DO NOT SUBMIT WITH true + + private class BaseContext extends MockContext { + @Override + public Object getSystemService(String name) { + switch (name) { + case Context.USER_SERVICE: + return mMockUserManager; + } + throw new UnsupportedOperationException(); + } + + @Override + public PackageManager getPackageManager() { + return mMockPackageManager; + } + + @Override + public Resources getResources() { + return ShortcutManagerTest.this.getContext().getResources(); + } + } /** Context used in the client side */ - private final class ClientContext extends MockContext { + private class ClientContext extends BaseContext { @Override public String getPackageName() { return mInjectedClientPackage; @@ -80,7 +129,7 @@ public class ShortcutManagerTest extends AndroidTestCase { } /** Context used in the service side */ - private final class ServiceContext extends MockContext { + private final class ServiceContext extends BaseContext { } /** ShortcutService with injection override methods. */ @@ -91,10 +140,20 @@ public class ShortcutManagerTest extends AndroidTestCase { } @Override - void injectLoadConfigurationLocked() { - setResetIntervalForTest(INTERVAL); - setMaxDynamicShortcutsForTest(MAX_SHORTCUTS); - setMaxDailyUpdatesForTest(MAX_DAILY_UPDATES); + String injectShortcutManagerConstants() { + return ConfigConstants.KEY_RESET_INTERVAL_SEC + "=" + (INTERVAL / 1000) + "," + + ConfigConstants.KEY_MAX_SHORTCUTS + "=" + MAX_SHORTCUTS + "," + + ConfigConstants.KEY_MAX_DAILY_UPDATES + "=" + MAX_DAILY_UPDATES + "," + + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP + "=" + MAX_ICON_DIMENSION + "," + + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP_LOWRAM + "=" + + MAX_ICON_DIMENSION_LOWRAM + "," + + ConfigConstants.KEY_ICON_FORMAT + "=PNG," + + ConfigConstants.KEY_ICON_QUALITY + "=100"; + } + + @Override + int injectDipToPixel(int dip) { + return dip; } @Override @@ -108,9 +167,9 @@ public class ShortcutManagerTest extends AndroidTestCase { } @Override - int injectGetPackageUid(String packageName) { + int injectGetPackageUid(String packageName, int userId) { Integer uid = mInjectedPackageUidMap.get(packageName); - return uid != null ? uid : -1; + return UserHandle.getUid(getCallingUserId(), (uid != null ? uid : 0)); } @Override @@ -122,10 +181,20 @@ public class ShortcutManagerTest extends AndroidTestCase { File injectUserDataPath(@UserIdInt int userId) { return new File(mInjectedFilePathRoot, "user-" + userId); } + + @Override + void injectValidateIconResPackage(ShortcutInfo shortcut, Icon icon) { + // Can't check + } + + @Override + boolean injectIsLowRamDevice() { + return mInjectdIsLowRamDevice; + } } /** 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); } @@ -136,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 { } @@ -153,15 +243,23 @@ public class ShortcutManagerTest extends AndroidTestCase { private ShortcutManagerTestable mManager; private ShortcutServiceInternal mInternal; + private LauncherAppImplTestable mLauncherAppImpl; + private LauncherAppsTestable mLauncherApps; + private File mInjectedFilePathRoot; private long mInjectedCurrentTimeLillis; + private boolean mInjectdIsLowRamDevice; + private int mInjectedCallingUid; private String mInjectedClientPackage; 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; @@ -177,14 +275,21 @@ public class ShortcutManagerTest extends AndroidTestCase { private static final String LAUNCHER_2 = "com.android.launcher.2"; private static final int LAUNCHER_UID_2 = 10012; + private static final int USER_10 = 10; + private static final int USER_11 = 11; + private static final long START_TIME = 1234560000000L; private static final long INTERVAL = 10000; - private static final int MAX_SHORTCUTS = 5; + private static final int MAX_SHORTCUTS = 10; private static final int MAX_DAILY_UPDATES = 3; + private static final int MAX_ICON_DIMENSION = 128; + + private static final int MAX_ICON_DIMENSION_LOWRAM = 32; + @Override protected void setUp() throws Exception { super.setUp(); @@ -192,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; @@ -226,24 +334,48 @@ 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); } /** Replace the current calling package */ - private void setCaller(String packageName) { + private void setCaller(String packageName, int userId) { mInjectedClientPackage = packageName; - mInjectedCallingUid = Preconditions.checkNotNull(mInjectedPackageUidMap.get(packageName)); + mInjectedCallingUid = UserHandle.getUid(userId, + Preconditions.checkNotNull(mInjectedPackageUidMap.get(packageName), + "Unknown package")); + } + + private void setCaller(String packageName) { + setCaller(packageName, UserHandle.USER_SYSTEM); } private String getCallingPackage() { return mInjectedClientPackage; } + private void runWithCaller(String packageName, int userId, Runnable r) { + final String previousPackage = mInjectedClientPackage; + final int previousUid = mInjectedCallingUid; + + setCaller(packageName, userId); + + r.run(); + + setCaller(previousPackage, previousUid); + } + private int getCallingUserId() { return UserHandle.getUserId(mInjectedCallingUid); } + private UserHandle getCallingUser() { + return UserHandle.of(getCallingUserId()); + } + /** For debugging */ private void dumpsysOnLogcat() { if (!ENABLE_DUMP) return; @@ -343,6 +475,27 @@ public class ShortcutManagerTest extends AndroidTestCase { } /** + * Make a shortcut with an ID and icon. + */ + private ShortcutInfo makeShortcutWithIcon(String id, Icon icon) { + return makeShortcut( + id, "Title-" + id, /* activity =*/ null, icon, + makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* weight =*/ 0); + } + + private ShortcutInfo makePackageShortcut(String packageName, String id) { + String origCaller = getCallingPackage(); + + setCaller(packageName); + ShortcutInfo s = makeShortcut( + id, "Title-" + id, /* activity =*/ null, /* icon =*/ null, + makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* weight =*/ 0); + setCaller(origCaller); // restore the caller + + return s; + } + + /** * Make multiple shortcuts with IDs. */ private List<ShortcutInfo> makeShortcuts(String... ids) { @@ -353,6 +506,10 @@ public class ShortcutManagerTest extends AndroidTestCase { return ret; } + private ShortcutInfo.Builder makeShortcutBuilder() { + return new ShortcutInfo.Builder(mClientContext); + } + /** * Make a shortcut with details. */ @@ -413,6 +570,7 @@ public class ShortcutManagerTest extends AndroidTestCase { @NonNull private List<ShortcutInfo> assertShortcutIds(@NonNull List<ShortcutInfo> actualShortcuts, String... expectedIds) { + assertEquals(expectedIds.length, actualShortcuts.size()); final HashSet<String> expected = new HashSet<>(Arrays.asList(expectedIds)); final HashSet<String> actual = new HashSet<>(); for (ShortcutInfo s : actualShortcuts) { @@ -461,6 +619,44 @@ public class ShortcutManagerTest extends AndroidTestCase { } @NonNull + private List<ShortcutInfo> assertAllNotHaveIcon( + @NonNull List<ShortcutInfo> actualShortcuts) { + for (ShortcutInfo s : actualShortcuts) { + assertNull("ID " + s.getId(), s.getIcon()); + } + return actualShortcuts; + } + + @NonNull + private List<ShortcutInfo> assertAllHaveIconResId( + @NonNull List<ShortcutInfo> actualShortcuts) { + for (ShortcutInfo s : actualShortcuts) { + assertTrue("ID " + s.getId() + " not have icon res ID", s.hasIconResource()); + assertFalse("ID " + s.getId() + " shouldn't have icon FD", s.hasIconFile()); + } + return actualShortcuts; + } + + @NonNull + private List<ShortcutInfo> assertAllHaveIconFile( + @NonNull List<ShortcutInfo> actualShortcuts) { + for (ShortcutInfo s : actualShortcuts) { + assertFalse("ID " + s.getId() + " shouldn't have icon res ID", s.hasIconResource()); + assertTrue("ID " + s.getId() + " not have icon FD", s.hasIconFile()); + } + return actualShortcuts; + } + + @NonNull + private List<ShortcutInfo> assertAllHaveIcon( + @NonNull List<ShortcutInfo> actualShortcuts) { + for (ShortcutInfo s : actualShortcuts) { + assertTrue("ID " + s.getId(), s.hasIconFile() || s.hasIconResource()); + } + return actualShortcuts; + } + + @NonNull private List<ShortcutInfo> assertAllHaveFlags(@NonNull List<ShortcutInfo> actualShortcuts, int shortcutFlags) { for (ShortcutInfo s : actualShortcuts) { @@ -470,6 +666,24 @@ public class ShortcutManagerTest extends AndroidTestCase { } @NonNull + private List<ShortcutInfo> assertAllKeyFieldsOnly( + @NonNull List<ShortcutInfo> actualShortcuts) { + for (ShortcutInfo s : actualShortcuts) { + assertTrue("ID " + s.getId(), s.hasKeyFieldsOnly()); + } + return actualShortcuts; + } + + @NonNull + private List<ShortcutInfo> assertAllNotKeyFieldsOnly( + @NonNull List<ShortcutInfo> actualShortcuts) { + for (ShortcutInfo s : actualShortcuts) { + assertFalse("ID " + s.getId(), s.hasKeyFieldsOnly()); + } + return actualShortcuts; + } + + @NonNull private List<ShortcutInfo> assertAllDynamic(@NonNull List<ShortcutInfo> actualShortcuts) { return assertAllHaveFlags(actualShortcuts, ShortcutInfo.FLAG_DYNAMIC); } @@ -488,6 +702,47 @@ public class ShortcutManagerTest extends AndroidTestCase { return actualShortcuts; } + private void assertBitmapSize(int expectedWidth, int expectedHeight, @NonNull Bitmap bitmap) { + assertEquals("width", expectedWidth, bitmap.getWidth()); + assertEquals("height", expectedHeight, bitmap.getHeight()); + } + + private <T> void assertAllUnique(Collection<T> list) { + final Set<Object> set = new HashSet<>(); + for (T item : list) { + if (set.contains(item)) { + fail("Duplicate item found: " + item + " (in the list: " + list + ")"); + } + set.add(item); + } + } + + @NonNull + private Bitmap pfdToBitmap(@NonNull ParcelFileDescriptor pfd) { + Preconditions.checkNotNull(pfd); + try { + return BitmapFactory.decodeFileDescriptor(pfd.getFileDescriptor()); + } finally { + IoUtils.closeQuietly(pfd); + } + } + + 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); + } + + private ShortcutInfo getPackageShortcut(String packageName, String shortcutId) { + return getPackageShortcut(packageName, shortcutId, getCallingUserId()); + } + + private ShortcutInfo getCallerShortcut(String shortcutId) { + return getPackageShortcut(getCallingPackage(), shortcutId, getCallingUserId()); + } + /** * Test for the first launch path, no settings file available. */ @@ -549,6 +804,44 @@ public class ShortcutManagerTest extends AndroidTestCase { // TODO Add various broken cases. } + public void testLoadConfig() { + mService.updateConfigurationLocked( + ConfigConstants.KEY_RESET_INTERVAL_SEC + "=123," + + ConfigConstants.KEY_MAX_SHORTCUTS + "=4," + + ConfigConstants.KEY_MAX_DAILY_UPDATES + "=5," + + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP + "=100," + + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP_LOWRAM + "=50," + + ConfigConstants.KEY_ICON_FORMAT + "=WEBP," + + ConfigConstants.KEY_ICON_QUALITY + "=75"); + assertEquals(123000, mService.getResetIntervalForTest()); + assertEquals(4, mService.getMaxDynamicShortcutsForTest()); + assertEquals(5, mService.getMaxDailyUpdatesForTest()); + assertEquals(100, mService.getMaxIconDimensionForTest()); + assertEquals(CompressFormat.WEBP, mService.getIconPersistFormatForTest()); + assertEquals(75, mService.getIconPersistQualityForTest()); + + mInjectdIsLowRamDevice = true; + mService.updateConfigurationLocked( + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP + "=100," + + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP_LOWRAM + "=50," + + ConfigConstants.KEY_ICON_FORMAT + "=JPEG"); + assertEquals(ShortcutService.DEFAULT_RESET_INTERVAL_SEC * 1000, + mService.getResetIntervalForTest()); + + assertEquals(ShortcutService.DEFAULT_MAX_SHORTCUTS_PER_APP, + mService.getMaxDynamicShortcutsForTest()); + + assertEquals(ShortcutService.DEFAULT_MAX_DAILY_UPDATES, + mService.getMaxDailyUpdatesForTest()); + + assertEquals(50, mService.getMaxIconDimensionForTest()); + + assertEquals(CompressFormat.JPEG, mService.getIconPersistFormatForTest()); + + assertEquals(ShortcutService.DEFAULT_ICON_PERSIST_QUALITY, + mService.getIconPersistQualityForTest()); + } + // === Test for app side APIs === /** Test for {@link android.content.pm.ShortcutManager#getMaxDynamicShortcutCount()} */ @@ -594,13 +887,17 @@ public class ShortcutManagerTest extends AndroidTestCase { final ShortcutInfo si3 = makeShortcut("shortcut3"); assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2))); - assertEquals(2, mManager.getDynamicShortcuts().size()); + assertShortcutIds(assertAllNotKeyFieldsOnly( + mManager.getDynamicShortcuts()), + "shortcut1", "shortcut2"); assertEquals(2, mManager.getRemainingCallCount()); // TODO: Check fields assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1))); - assertEquals(1, mManager.getDynamicShortcuts().size()); + assertShortcutIds(assertAllNotKeyFieldsOnly( + mManager.getDynamicShortcuts()), + "shortcut1"); assertEquals(1, mManager.getRemainingCallCount()); assertTrue(mManager.setDynamicShortcuts(Arrays.asList())); @@ -629,16 +926,22 @@ public class ShortcutManagerTest extends AndroidTestCase { assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1))); assertEquals(2, mManager.getRemainingCallCount()); - assertEquals(1, mManager.getDynamicShortcuts().size()); + assertShortcutIds(assertAllNotKeyFieldsOnly( + mManager.getDynamicShortcuts()), + "shortcut1"); assertTrue(mManager.addDynamicShortcut(si2)); assertEquals(1, mManager.getRemainingCallCount()); - assertEquals(2, mManager.getDynamicShortcuts().size()); + assertShortcutIds(assertAllNotKeyFieldsOnly( + mManager.getDynamicShortcuts()), + "shortcut1", "shortcut2"); // Add with the same ID assertTrue(mManager.addDynamicShortcut(makeShortcut("shortcut1"))); assertEquals(0, mManager.getRemainingCallCount()); - assertEquals(2, mManager.getDynamicShortcuts().size()); // Still 2 + assertShortcutIds(assertAllNotKeyFieldsOnly( + mManager.getDynamicShortcuts()), + "shortcut1", "shortcut2"); // TODO Check max number @@ -651,24 +954,35 @@ public class ShortcutManagerTest extends AndroidTestCase { final ShortcutInfo si3 = makeShortcut("shortcut3"); assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2, si3))); - assertEquals(3, mManager.getDynamicShortcuts().size()); + assertShortcutIds(assertAllNotKeyFieldsOnly( + mManager.getDynamicShortcuts()), + "shortcut1", "shortcut2", "shortcut3"); assertEquals(2, mManager.getRemainingCallCount()); mManager.deleteDynamicShortcut("shortcut1"); - assertEquals(2, mManager.getDynamicShortcuts().size()); + assertShortcutIds(assertAllNotKeyFieldsOnly( + mManager.getDynamicShortcuts()), + "shortcut2", "shortcut3"); mManager.deleteDynamicShortcut("shortcut1"); - assertEquals(2, mManager.getDynamicShortcuts().size()); + assertShortcutIds(assertAllNotKeyFieldsOnly( + mManager.getDynamicShortcuts()), + "shortcut2", "shortcut3"); mManager.deleteDynamicShortcut("shortcutXXX"); - assertEquals(2, mManager.getDynamicShortcuts().size()); + assertShortcutIds(assertAllNotKeyFieldsOnly( + mManager.getDynamicShortcuts()), + "shortcut2", "shortcut3"); mManager.deleteDynamicShortcut("shortcut2"); - assertEquals(1, mManager.getDynamicShortcuts().size()); + assertShortcutIds(assertAllNotKeyFieldsOnly( + mManager.getDynamicShortcuts()), + "shortcut3"); mManager.deleteDynamicShortcut("shortcut3"); - assertEquals(0, mManager.getDynamicShortcuts().size()); + assertShortcutIds(assertAllNotKeyFieldsOnly( + mManager.getDynamicShortcuts())); // Still 2 calls left. assertEquals(2, mManager.getRemainingCallCount()); @@ -682,7 +996,9 @@ public class ShortcutManagerTest extends AndroidTestCase { final ShortcutInfo si3 = makeShortcut("shortcut3"); assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2, si3))); - assertEquals(3, mManager.getDynamicShortcuts().size()); + assertShortcutIds(assertAllNotKeyFieldsOnly( + mManager.getDynamicShortcuts()), + "shortcut1", "shortcut2", "shortcut3"); assertEquals(2, mManager.getRemainingCallCount()); @@ -732,7 +1048,7 @@ public class ShortcutManagerTest extends AndroidTestCase { // Now it should work. mInjectedCurrentTimeLillis++; - assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1))); + assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1))); // fail assertEquals(2, mManager.getRemainingCallCount()); mInjectedCurrentTimeLillis++; @@ -831,11 +1147,363 @@ public class ShortcutManagerTest extends AndroidTestCase { assertFalse(mManager.setDynamicShortcuts(Arrays.asList(si2))); } + public void testIcons() { + final Icon res32x32 = Icon.createWithResource(mContext, R.drawable.black_32x32); + final Icon res64x64 = Icon.createWithResource(mContext, R.drawable.black_64x64); + final Icon res512x512 = Icon.createWithResource(mContext, R.drawable.black_512x512); + + final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource( + mContext.getResources(), R.drawable.black_32x32)); + final Icon bmp64x64 = Icon.createWithBitmap(BitmapFactory.decodeResource( + mContext.getResources(), R.drawable.black_64x64)); + final Icon bmp512x512 = Icon.createWithBitmap(BitmapFactory.decodeResource( + mContext.getResources(), R.drawable.black_512x512)); + + // Set from package 1 + setCaller(CALLING_PACKAGE_1); + assertTrue(mManager.setDynamicShortcuts(Arrays.asList( + makeShortcutWithIcon("res32x32", res32x32), + makeShortcutWithIcon("res64x64", res64x64), + makeShortcutWithIcon("bmp32x32", bmp32x32), + makeShortcutWithIcon("bmp64x64", bmp64x64), + makeShortcutWithIcon("bmp512x512", bmp512x512), + makeShortcut("none") + ))); + + // getDynamicShortcuts() shouldn't return icons, thus assertAllNotHaveIcon(). + assertShortcutIds(assertAllNotHaveIcon(mManager.getDynamicShortcuts()), + "res32x32", + "res64x64", + "bmp32x32", + "bmp64x64", + "bmp512x512", + "none"); + + // Call from another caller with the same ID, just to make sure storage is per-package. + setCaller(CALLING_PACKAGE_2); + assertTrue(mManager.setDynamicShortcuts(Arrays.asList( + makeShortcutWithIcon("res32x32", res512x512), + makeShortcutWithIcon("res64x64", res512x512), + makeShortcutWithIcon("none", res512x512) + ))); + assertShortcutIds(assertAllNotHaveIcon(mManager.getDynamicShortcuts()), + "res32x32", + "res64x64", + "none"); + + // Re-initialize and load from the files. + initService(); + + // Load from launcher. + Bitmap bmp; + + setCaller(LAUNCHER_1); + + // Check hasIconResource()/hasIconFile(). + 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, + mLauncherApps.getShortcutIconResId( + makePackageShortcut(CALLING_PACKAGE_1, "res32x32"), getCallingUser())); + + assertEquals( + R.drawable.black_64x64, + mLauncherApps.getShortcutIconResId( + + makePackageShortcut(CALLING_PACKAGE_1, "res64x64"), getCallingUser())); + + assertEquals( + 0, // because it's not a resource + mLauncherApps.getShortcutIconResId( + makePackageShortcut(CALLING_PACKAGE_1, "bmp32x32"), getCallingUser())); + assertEquals( + 0, // because it's not a resource + mLauncherApps.getShortcutIconResId( + makePackageShortcut(CALLING_PACKAGE_1, "bmp64x64"), getCallingUser())); + assertEquals( + 0, // because it's not a resource + mLauncherApps.getShortcutIconResId( + makePackageShortcut(CALLING_PACKAGE_1, "bmp512x512"), getCallingUser())); + + bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd( + makePackageShortcut(CALLING_PACKAGE_1, "bmp32x32"), getCallingUser())); + assertBitmapSize(32, 32, bmp); + + bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd( + makePackageShortcut(CALLING_PACKAGE_1, "bmp64x64"), getCallingUser())); + assertBitmapSize(64, 64, bmp); + + bmp = pfdToBitmap(mLauncherApps.getShortcutIconFd( + makePackageShortcut(CALLING_PACKAGE_1, "bmp512x512"), getCallingUser())); + assertBitmapSize(128, 128, bmp); + + // TODO Test the content URI case too. + } + + private void checkShrinkBitmap(int expectedWidth, int expectedHeight, int resId, int maxSize) { + assertBitmapSize(expectedWidth, expectedHeight, + ShortcutService.shrinkBitmap(BitmapFactory.decodeResource( + mContext.getResources(), resId), + maxSize)); + } + + public void testShrinkBitmap() { + checkShrinkBitmap(32, 32, R.drawable.black_512x512, 32); + checkShrinkBitmap(511, 511, R.drawable.black_512x512, 511); + checkShrinkBitmap(512, 512, R.drawable.black_512x512, 512); + + checkShrinkBitmap(1024, 4096, R.drawable.black_1024x4096, 4096); + checkShrinkBitmap(1024, 4096, R.drawable.black_1024x4096, 4100); + checkShrinkBitmap(512, 2048, R.drawable.black_1024x4096, 2048); + + checkShrinkBitmap(4096, 1024, R.drawable.black_4096x1024, 4096); + checkShrinkBitmap(4096, 1024, R.drawable.black_4096x1024, 4100); + checkShrinkBitmap(2048, 512, R.drawable.black_4096x1024, 2048); + } + + private File openIconFileForWriteAndGetPath(int userId, String packageName) + throws IOException { + // Shortcut IDs aren't used in the path, so just pass the same ID. + final FileOutputStreamWithPath out = + mService.openIconFileForWrite(userId, makePackageShortcut(packageName, "id")); + out.close(); + return out.getFile(); + } + + public void testOpenIconFileForWrite() throws IOException { + mInjectedCurrentTimeLillis = 1000; + + final File p10_1_1 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1); + final File p10_1_2 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1); + + final File p10_2_1 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_2); + final File p10_2_2 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_2); + + final File p11_1_1 = openIconFileForWriteAndGetPath(11, CALLING_PACKAGE_1); + final File p11_1_2 = openIconFileForWriteAndGetPath(11, CALLING_PACKAGE_1); + + mInjectedCurrentTimeLillis++; + + final File p10_1_3 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1); + final File p10_1_4 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1); + final File p10_1_5 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1); + + final File p10_2_3 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_2); + final File p11_1_3 = openIconFileForWriteAndGetPath(11, CALLING_PACKAGE_1); + + // Make sure their paths are all unique + assertAllUnique(Arrays.asList( + p10_1_1, + p10_1_2, + p10_1_3, + p10_1_4, + p10_1_5, + + p10_2_1, + p10_2_2, + p10_2_3, + + p11_1_1, + p11_1_2, + p11_1_3 + )); + + // Check each set has the same parent. + assertEquals(p10_1_1.getParent(), p10_1_2.getParent()); + assertEquals(p10_1_1.getParent(), p10_1_3.getParent()); + assertEquals(p10_1_1.getParent(), p10_1_4.getParent()); + assertEquals(p10_1_1.getParent(), p10_1_5.getParent()); + + assertEquals(p10_2_1.getParent(), p10_2_2.getParent()); + assertEquals(p10_2_1.getParent(), p10_2_3.getParent()); + + assertEquals(p11_1_1.getParent(), p11_1_2.getParent()); + assertEquals(p11_1_1.getParent(), p11_1_3.getParent()); + + // Check the parents are still unique. + assertAllUnique(Arrays.asList( + p10_1_1.getParent(), + p10_2_1.getParent(), + p11_1_1.getParent() + )); + + // All files created at the same time for the same package/user, expcet for the first ones, + // will have "_" in the path. + assertFalse(p10_1_1.getName().contains("_")); + assertTrue(p10_1_2.getName().contains("_")); + assertFalse(p10_1_3.getName().contains("_")); + assertTrue(p10_1_4.getName().contains("_")); + assertTrue(p10_1_5.getName().contains("_")); + + assertFalse(p10_2_1.getName().contains("_")); + assertTrue(p10_2_2.getName().contains("_")); + assertFalse(p10_2_3.getName().contains("_")); + + assertFalse(p11_1_1.getName().contains("_")); + assertTrue(p11_1_2.getName().contains("_")); + 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. @@ -860,53 +1528,56 @@ public class ShortcutManagerTest extends AndroidTestCase { // Get dynamic assertAllDynamic(assertAllHaveTitle(assertAllNotHaveIntents(assertShortcutIds( - mInternal.getShortcuts(getCallingPackage(), /* time =*/ 0, CALLING_PACKAGE_1, - /* activity =*/ null, - ShortcutQuery.FLAG_GET_DYNAMIC, getCallingUserId()), + assertAllNotKeyFieldsOnly( + 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( - mInternal.getShortcuts(getCallingPackage(), /* time =*/ 1000, CALLING_PACKAGE_2, + 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( - mInternal.getShortcuts(getCallingPackage(), /* time =*/ 1000, CALLING_PACKAGE_2, + 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( - mInternal.getShortcuts(getCallingPackage(), /* time =*/ 1000, CALLING_PACKAGE_2, + 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( - mInternal.getShortcuts(getCallingPackage(), + assertShortcutIds(assertAllNotKeyFieldsOnly( + 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 @@ -950,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(); @@ -968,20 +1639,21 @@ public class ShortcutManagerTest extends AndroidTestCase { // Note we don't guarantee the orders. list = assertShortcutIds(assertAllHaveTitle(assertAllNotHaveIntents( - mInternal.getShortcutInfo(getCallingPackage(), CALLING_PACKAGE_1, - Arrays.asList("s2", "s1", "s3", null), getCallingUserId()))), + assertAllNotKeyFieldsOnly( + 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()); } @@ -1007,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); @@ -1036,19 +1708,19 @@ public class ShortcutManagerTest extends AndroidTestCase { setCaller(LAUNCHER_1); // CALLING_PACKAGE_1 deleted s2, but it's pinned, so it still exists. - assertShortcutIds(assertAllPinned( - mInternal.getShortcuts(getCallingPackage(), /* time =*/ 0, CALLING_PACKAGE_1, - /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED, getCallingUserId())), + assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly( + mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1, + /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))), "s2"); - assertShortcutIds(assertAllPinned( - mInternal.getShortcuts(getCallingPackage(), /* time =*/ 0, CALLING_PACKAGE_2, - /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED, getCallingUserId())), + assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly( + mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_2, + /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))), "s3", "s4"); - assertShortcutIds(assertAllPinned( - mInternal.getShortcuts(getCallingPackage(), /* time =*/ 0, CALLING_PACKAGE_3, - /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED, getCallingUserId())) + assertShortcutIds(assertAllPinned(assertAllNotKeyFieldsOnly( + mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_3, + /* activity =*/ null, ShortcutQuery.FLAG_GET_PINNED), getCallingUser()))) /* none */); } @@ -1087,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); @@ -1135,35 +1807,87 @@ public class ShortcutManagerTest extends AndroidTestCase { */ public void testSaveAndLoadUser() { // First, create some shortcuts and save. - final Icon icon1 = Icon.createWithResource(mContext, R.drawable.icon1); - final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource( - mContext.getResources(), R.drawable.icon2)); - - final ShortcutInfo si1 = makeShortcut( - "shortcut1", - "Title 1", - makeComponent(ShortcutActivity.class), - icon1, - makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class, - "key1", "val1", "nest", makeBundle("key", 123)), - /* weight */ 10); - - final ShortcutInfo si2 = makeShortcut( - "shortcut2", - "Title 2", - /* activity */ null, - icon2, - makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class), - /* weight */ 12); - - assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2))); - - assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); - assertEquals(2, mManager.getRemainingCallCount()); - - Log.i(TAG, "Saved state"); - dumpsysOnLogcat(); - dumpUserFile(0); + runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> { + final Icon icon1 = Icon.createWithResource(mContext, R.drawable.black_64x16); + final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource( + mContext.getResources(), R.drawable.icon2)); + + final ShortcutInfo si1 = makeShortcut( + "s1", + "title1-1", + makeComponent(ShortcutActivity.class), + icon1, + makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class, + "key1", "val1", "nest", makeBundle("key", 123)), + /* weight */ 10); + + final ShortcutInfo si2 = makeShortcut( + "s2", + "title1-2", + /* activity */ null, + icon2, + makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class), + /* weight */ 12); + + assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2))); + + assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); + assertEquals(2, mManager.getRemainingCallCount()); + }); + runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> { + final Icon icon1 = Icon.createWithResource(mContext, R.drawable.black_16x64); + final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource( + mContext.getResources(), R.drawable.icon2)); + + final ShortcutInfo si1 = makeShortcut( + "s1", + "title2-1", + makeComponent(ShortcutActivity.class), + icon1, + makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class, + "key1", "val1", "nest", makeBundle("key", 123)), + /* weight */ 10); + + final ShortcutInfo si2 = makeShortcut( + "s2", + "title2-2", + /* activity */ null, + icon2, + makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class), + /* weight */ 12); + + assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2))); + + assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); + assertEquals(2, mManager.getRemainingCallCount()); + }); + runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { + final Icon icon1 = Icon.createWithResource(mContext, R.drawable.black_64x64); + final Icon icon2 = Icon.createWithBitmap(BitmapFactory.decodeResource( + mContext.getResources(), R.drawable.icon2)); + + final ShortcutInfo si1 = makeShortcut( + "s1", + "title10-1-1", + makeComponent(ShortcutActivity.class), + icon1, + makeIntent(Intent.ACTION_ASSIST, ShortcutActivity2.class, + "key1", "val1", "nest", makeBundle("key", 123)), + /* weight */ 10); + + final ShortcutInfo si2 = makeShortcut( + "s2", + "title10-1-2", + /* activity */ null, + icon2, + makeIntent(Intent.ACTION_ASSIST, ShortcutActivity3.class), + /* weight */ 12); + + assertTrue(mManager.setDynamicShortcuts(Arrays.asList(si1, si2))); + + assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); + assertEquals(2, mManager.getRemainingCallCount()); + }); // Restore. initService(); @@ -1177,26 +1901,40 @@ public class ShortcutManagerTest extends AndroidTestCase { // Now it's loaded. assertEquals(1, mService.getShortcutsForTest().size()); - // Start another user - mService.onStartUserLocked(10); + runWithCaller(CALLING_PACKAGE_1, UserHandle.USER_SYSTEM, () -> { + assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon( + mManager.getDynamicShortcuts()))), "s1", "s2"); + assertEquals(2, mManager.getRemainingCallCount()); - // Now the size is 2. - assertEquals(2, mService.getShortcutsForTest().size()); + assertEquals("title1-1", getCallerShortcut("s1").getTitle()); + assertEquals("title1-2", getCallerShortcut("s2").getTitle()); + }); + runWithCaller(CALLING_PACKAGE_2, UserHandle.USER_SYSTEM, () -> { + assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon( + mManager.getDynamicShortcuts()))), "s1", "s2"); + assertEquals(2, mManager.getRemainingCallCount()); - Log.i(TAG, "Dumping the new instance"); + assertEquals("title2-1", getCallerShortcut("s1").getTitle()); + assertEquals("title2-2", getCallerShortcut("s2").getTitle()); + }); - List<ShortcutInfo> loaded = mManager.getDynamicShortcuts(); + // Start another user + mService.onStartUserLocked(USER_10); - Log.i(TAG, "Loaded state"); - dumpsysOnLogcat(); + // Now the size is 2. + assertEquals(2, mService.getShortcutsForTest().size()); - assertEquals(2, loaded.size()); + runWithCaller(CALLING_PACKAGE_1, USER_10, () -> { + assertShortcutIds(assertAllDynamic(assertAllHaveIntents(assertAllHaveIcon( + mManager.getDynamicShortcuts()))), "s1", "s2"); + assertEquals(2, mManager.getRemainingCallCount()); - assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime()); - assertEquals(2, mManager.getRemainingCallCount()); + assertEquals("title10-1-1", getCallerShortcut("s1").getTitle()); + assertEquals("title10-1-2", getCallerShortcut("s2").getTitle()); + }); // Try stopping the user - mService.onCleanupUserInner(UserHandle.USER_SYSTEM); + mService.onCleanupUserInner(USER_10); // Now it's unloaded. assertEquals(1, mService.getShortcutsForTest().size()); diff --git a/services/usb/java/com/android/server/usb/MtpNotificationManager.java b/services/usb/java/com/android/server/usb/MtpNotificationManager.java index 17039bb6870c..101e2008d3e9 100644 --- a/services/usb/java/com/android/server/usb/MtpNotificationManager.java +++ b/services/usb/java/com/android/server/usb/MtpNotificationManager.java @@ -24,6 +24,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.pm.PackageManager; import android.content.res.Resources; import android.hardware.usb.UsbConstants; import android.hardware.usb.UsbDevice; @@ -101,8 +102,8 @@ class MtpNotificationManager { TAG, device.getDeviceId(), notification); } - void hideNotification(UsbDevice device) { - mContext.getSystemService(NotificationManager.class).cancel(TAG, device.getDeviceId()); + void hideNotification(int deviceId) { + mContext.getSystemService(NotificationManager.class).cancel(TAG, deviceId); } private class Receiver extends BroadcastReceiver { @@ -121,7 +122,13 @@ class MtpNotificationManager { } } - static boolean isMtpDevice(UsbDevice device) { + static boolean shouldShowNotification(PackageManager packageManager, UsbDevice device) { + // We don't show MTP notification for devices that has FEATURE_AUTOMOTIVE. + return !packageManager.hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE) && + isMtpDevice(device); + } + + private static boolean isMtpDevice(UsbDevice device) { for (int i = 0; i < device.getInterfaceCount(); i++) { final UsbInterface usbInterface = device.getInterface(i); if ((usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_STILL_IMAGE && diff --git a/services/usb/java/com/android/server/usb/UsbSettingsManager.java b/services/usb/java/com/android/server/usb/UsbSettingsManager.java index c4d7336b3f49..de9ede397c13 100644 --- a/services/usb/java/com/android/server/usb/UsbSettingsManager.java +++ b/services/usb/java/com/android/server/usb/UsbSettingsManager.java @@ -738,7 +738,7 @@ class UsbSettingsManager { // Send broadcast to running activity with registered intent mUserContext.sendBroadcast(intent); - if (MtpNotificationManager.isMtpDevice(device)) { + if (MtpNotificationManager.shouldShowNotification(mPackageManager, device)) { // Show notification if the device is MTP storage. mMtpNotificationManager.showNotification(device); } else { @@ -769,9 +769,7 @@ class UsbSettingsManager { if (DEBUG) Slog.d(TAG, "usbDeviceRemoved, sending " + intent); mContext.sendBroadcastAsUser(intent, UserHandle.ALL); - if (MtpNotificationManager.isMtpDevice(device)) { - mMtpNotificationManager.hideNotification(device); - } + mMtpNotificationManager.hideNotification(device.getDeviceId()); } public void accessoryAttached(UsbAccessory accessory) { diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java index 605e0d3acd90..8afb4556b97d 100644 --- a/telecomm/java/android/telecom/TelecomManager.java +++ b/telecomm/java/android/telecom/TelecomManager.java @@ -1442,7 +1442,7 @@ public class TelecomManager { /** * Creates the {@link Intent} which can be used with {@link Context#startActivity(Intent)} to * launch the activity to manage blocked numbers. - * <p> This method displays the UI to manage blocked numbers only if + * <p> The activity will display the UI to manage blocked numbers only if * {@link android.provider.BlockedNumberContract#canCurrentUserBlockNumbers(Context)} returns * {@code true} for the current user. */ diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java index cd1c5e9ac229..ea437d02ce2a 100644 --- a/telephony/java/android/telephony/CarrierConfigManager.java +++ b/telephony/java/android/telephony/CarrierConfigManager.java @@ -251,6 +251,30 @@ public class CarrierConfigManager { */ public static final String KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL = "carrier_wfc_ims_available_bool"; + /** + * Default WFC_IMS_mode 0: WIFI_ONLY + * 1: CELLULAR_PREFERRED + * 2: WIFI_PREFERRED + * @hide + */ + public static final String KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT = + "carrier_default_wfc_ims_mode_int"; + /** + * Default WFC_IMS_enabled: true VoWiFi by default is on + * false VoWiFi by default is off + * @hide + */ + public static final String KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL = + "carrier_default_wfc_ims_enabled_bool"; + + /** + * Default WFC_IMS_roaming_enabled: true VoWiFi roaming by default is on + * false VoWiFi roaming by default is off + * @hide + */ + public static final String KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL = + "carrier_default_wfc_ims_roaming_enabled_bool"; + /** Flag specifying whether provisioning is required for VOLTE. */ public static final String KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL = "carrier_volte_provisioning_required_bool"; @@ -613,6 +637,9 @@ public class CarrierConfigManager { sDefaults.putBoolean(KEY_CARRIER_VOLTE_AVAILABLE_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VT_AVAILABLE_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_WFC_IMS_AVAILABLE_BOOL, false); + sDefaults.putBoolean(KEY_CARRIER_DEFAULT_WFC_IMS_ENABLED_BOOL, false); + sDefaults.putBoolean(KEY_CARRIER_DEFAULT_WFC_IMS_ROAMING_ENABLED_BOOL, false); + sDefaults.putInt(KEY_CARRIER_DEFAULT_WFC_IMS_MODE_INT, 2); sDefaults.putBoolean(KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL, false); sDefaults.putBoolean(KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL, true); 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/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/tests/NetworkSecurityConfigTest/res/xml/bad_extra_debug_resource.xml b/tests/NetworkSecurityConfigTest/res/xml/bad_extra_debug_resource.xml new file mode 100644 index 000000000000..8093b9d05153 --- /dev/null +++ b/tests/NetworkSecurityConfigTest/res/xml/bad_extra_debug_resource.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<network-security-config> + <base-config> + <trust-anchors> + </trust-anchors> + </base-config> +</network-security-config> diff --git a/tests/NetworkSecurityConfigTest/res/xml/bad_extra_debug_resource_debug.xml b/tests/NetworkSecurityConfigTest/res/xml/bad_extra_debug_resource_debug.xml new file mode 100644 index 000000000000..fc24df5f783c --- /dev/null +++ b/tests/NetworkSecurityConfigTest/res/xml/bad_extra_debug_resource_debug.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- debug-overrides not inside network-security-config should cause a parsing error --> +<debug-overrides> + <trust-anchors> + <certificates src="system" /> + </trust-anchors> +</debug-overrides> diff --git a/tests/NetworkSecurityConfigTest/res/xml/extra_debug_resource.xml b/tests/NetworkSecurityConfigTest/res/xml/extra_debug_resource.xml new file mode 100644 index 000000000000..8093b9d05153 --- /dev/null +++ b/tests/NetworkSecurityConfigTest/res/xml/extra_debug_resource.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="utf-8"?> +<network-security-config> + <base-config> + <trust-anchors> + </trust-anchors> + </base-config> +</network-security-config> diff --git a/tests/NetworkSecurityConfigTest/res/xml/extra_debug_resource_debug.xml b/tests/NetworkSecurityConfigTest/res/xml/extra_debug_resource_debug.xml new file mode 100644 index 000000000000..6a2ad37113c9 --- /dev/null +++ b/tests/NetworkSecurityConfigTest/res/xml/extra_debug_resource_debug.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="utf-8"?> +<network-security-config> + <debug-overrides> + <trust-anchors> + <certificates src="system" /> + </trust-anchors> + </debug-overrides> +</network-security-config> diff --git a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java index 35e3ef4c38cc..10bcc18a0019 100644 --- a/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java +++ b/tests/NetworkSecurityConfigTest/src/android/security/net/config/XmlConfigTests.java @@ -431,4 +431,37 @@ public class XmlConfigTests extends AndroidTestCase { TestUtils.assertConnectionSucceeds(context, "android.com", 443); TestUtils.assertUrlConnectionSucceeds(context, "android.com", 443); } + + public void testExtraDebugResource() throws Exception { + XmlConfigSource source = + new XmlConfigSource(getContext(), R.xml.extra_debug_resource, true); + ApplicationConfig appConfig = new ApplicationConfig(source); + assertFalse(appConfig.hasPerDomainConfigs()); + NetworkSecurityConfig config = appConfig.getConfigForHostname(""); + MoreAsserts.assertNotEmpty(config.getTrustAnchors()); + + // Check that the _debug file is ignored if debug is false. + source = new XmlConfigSource(getContext(), R.xml.extra_debug_resource, false); + appConfig = new ApplicationConfig(source); + assertFalse(appConfig.hasPerDomainConfigs()); + config = appConfig.getConfigForHostname(""); + MoreAsserts.assertEmpty(config.getTrustAnchors()); + } + + public void testExtraDebugResourceIgnored() throws Exception { + // Verify that parsing the extra debug config resource fails only when debugging is true. + XmlConfigSource source = + new XmlConfigSource(getContext(), R.xml.bad_extra_debug_resource, false); + ApplicationConfig appConfig = new ApplicationConfig(source); + // Force parsing the config file. + appConfig.getConfigForHostname(""); + + source = new XmlConfigSource(getContext(), R.xml.bad_extra_debug_resource, true); + appConfig = new ApplicationConfig(source); + try { + appConfig.getConfigForHostname(""); + fail("Bad extra debug resource did not fail to parse"); + } catch (RuntimeException expected) { + } + } } diff --git a/tools/aapt2/Android.mk b/tools/aapt2/Android.mk index 57a769221a8f..85d22ffacd4c 100644 --- a/tools/aapt2/Android.mk +++ b/tools/aapt2/Android.mk @@ -90,6 +90,7 @@ testSources := \ proto/TableProtoSerializer_test.cpp \ split/TableSplitter_test.cpp \ util/BigBuffer_test.cpp \ + util/Files_test.cpp \ util/Maybe_test.cpp \ util/StringPiece_test.cpp \ util/Util_test.cpp \ @@ -124,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/aapt2/Resource.h b/tools/aapt2/Resource.h index 4d1db5b0c9ad..03ca42b286d6 100644 --- a/tools/aapt2/Resource.h +++ b/tools/aapt2/Resource.h @@ -77,7 +77,7 @@ struct ResourceName { ResourceType type; std::u16string entry; - ResourceName() = default; + ResourceName() : type(ResourceType::kRaw) {} ResourceName(const StringPiece16& p, ResourceType t, const StringPiece16& e); bool isValid() const; diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp index b100e84f8a46..9704d97029b7 100644 --- a/tools/aapt2/ResourceParser.cpp +++ b/tools/aapt2/ResourceParser.cpp @@ -81,6 +81,12 @@ struct ParsedResource { // Recursively adds resources to the ResourceTable. static bool addResourcesToTable(ResourceTable* table, IDiagnostics* diag, ParsedResource* res) { + StringPiece16 trimmedComment = util::trimWhitespace(res->comment); + if (trimmedComment.size() != res->comment.size()) { + // Only if there was a change do we re-assign. + res->comment = trimmedComment.toString(); + } + if (res->symbolState) { Symbol symbol; symbol.state = res->symbolState.value(); diff --git a/tools/aapt2/integration-tests/StaticLibOne/res/values/values.xml b/tools/aapt2/integration-tests/StaticLibOne/res/values/values.xml index 2b24544d3d83..d09a4851f7b4 100644 --- a/tools/aapt2/integration-tests/StaticLibOne/res/values/values.xml +++ b/tools/aapt2/integration-tests/StaticLibOne/res/values/values.xml @@ -15,8 +15,13 @@ --> <resources> + <!-- An attribute from StaticLibOne --> <attr name="StaticLibOne_attr" format="string" /> <string name="Foo">Foo</string> <string name="Foo" product="tablet">Bar</string> + + <declare-styleable name="Widget"> + <attr name="StaticLibOne_attr" /> + </declare-styleable> </resources> diff --git a/tools/aapt2/java/AnnotationProcessor.cpp b/tools/aapt2/java/AnnotationProcessor.cpp index 9c25d4e35975..496e92e0bf93 100644 --- a/tools/aapt2/java/AnnotationProcessor.cpp +++ b/tools/aapt2/java/AnnotationProcessor.cpp @@ -38,7 +38,7 @@ void AnnotationProcessor::appendCommentLine(const std::string& comment) { mComment << "/**"; } - mComment << "\n" << " * " << std::move(comment); + mComment << "\n * " << std::move(comment); } void AnnotationProcessor::appendComment(const StringPiece16& comment) { @@ -60,6 +60,10 @@ void AnnotationProcessor::appendComment(const StringPiece& comment) { } } +void AnnotationProcessor::appendNewLine() { + mComment << "\n *"; +} + void AnnotationProcessor::writeToStream(std::ostream* out, const StringPiece& prefix) { if (mHasComments) { std::string result = mComment.str(); diff --git a/tools/aapt2/java/AnnotationProcessor.h b/tools/aapt2/java/AnnotationProcessor.h index e7f2be0dc12b..fadf58440991 100644 --- a/tools/aapt2/java/AnnotationProcessor.h +++ b/tools/aapt2/java/AnnotationProcessor.h @@ -61,6 +61,8 @@ public: void appendComment(const StringPiece16& comment); void appendComment(const StringPiece& comment); + void appendNewLine(); + /** * Writes the comments and annotations to the stream, with the given prefix before each line. */ diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp index 1076ffe1b01d..01330dc6b5a1 100644 --- a/tools/aapt2/java/JavaClassGenerator.cpp +++ b/tools/aapt2/java/JavaClassGenerator.cpp @@ -23,6 +23,7 @@ #include "java/AnnotationProcessor.h" #include "java/ClassDefinitionWriter.h" #include "java/JavaClassGenerator.h" +#include "process/SymbolTable.h" #include "util/StringPiece.h" #include <algorithm> @@ -33,8 +34,9 @@ namespace aapt { -JavaClassGenerator::JavaClassGenerator(ResourceTable* table, JavaClassGeneratorOptions options) : - mTable(table), mOptions(options) { +JavaClassGenerator::JavaClassGenerator(IAaptContext* context, ResourceTable* table, + const JavaClassGeneratorOptions& options) : + mContext(context), mTable(table), mOptions(options) { } static void generateHeader(const StringPiece16& packageNameToGenerate, std::ostream* out) { @@ -103,6 +105,85 @@ static std::string transformNestedAttr(const ResourceNameRef& attrName, return output; } +static void addAttributeFormatDoc(AnnotationProcessor* processor, Attribute* attr) { + const uint32_t typeMask = attr->typeMask; + if (typeMask & android::ResTable_map::TYPE_REFERENCE) { + processor->appendComment( + "<p>May be a reference to another resource, in the form\n" + "\"<code>@[+][<i>package</i>:]<i>type</i>/<i>name</i></code>\" or a theme\n" + "attribute in the form\n" + "\"<code>?[<i>package</i>:]<i>type</i>/<i>name</i></code>\"."); + } + + if (typeMask & android::ResTable_map::TYPE_STRING) { + processor->appendComment( + "<p>May be a string value, using '\\\\;' to escape characters such as\n" + "'\\\\n' or '\\\\uxxxx' for a unicode character;"); + } + + if (typeMask & android::ResTable_map::TYPE_INTEGER) { + processor->appendComment("<p>May be an integer value, such as \"<code>100</code>\"."); + } + + if (typeMask & android::ResTable_map::TYPE_BOOLEAN) { + processor->appendComment( + "<p>May be a boolean value, such as \"<code>true</code>\" or\n" + "\"<code>false</code>\"."); + } + + if (typeMask & android::ResTable_map::TYPE_COLOR) { + processor->appendComment( + "<p>May be a color value, in the form of \"<code>#<i>rgb</i></code>\",\n" + "\"<code>#<i>argb</i></code>\", \"<code>#<i>rrggbb</i></code\", or \n" + "\"<code>#<i>aarrggbb</i></code>\"."); + } + + if (typeMask & android::ResTable_map::TYPE_FLOAT) { + processor->appendComment( + "<p>May be a floating point value, such as \"<code>1.2</code>\"."); + } + + if (typeMask & android::ResTable_map::TYPE_DIMENSION) { + processor->appendComment( + "<p>May be a dimension value, which is a floating point number appended with a\n" + "unit such as \"<code>14.5sp</code>\".\n" + "Available units are: px (pixels), dp (density-independent pixels),\n" + "sp (scaled pixels based on preferred font size), in (inches), and\n" + "mm (millimeters)."); + } + + if (typeMask & android::ResTable_map::TYPE_FRACTION) { + processor->appendComment( + "<p>May be a fractional value, which is a floating point number appended with\n" + "either % or %p, such as \"<code>14.5%</code>\".\n" + "The % suffix always means a percentage of the base size;\n" + "the optional %p suffix provides a size relative to some parent container."); + } + + if (typeMask & (android::ResTable_map::TYPE_FLAGS | android::ResTable_map::TYPE_ENUM)) { + if (typeMask & android::ResTable_map::TYPE_FLAGS) { + processor->appendComment( + "<p>Must be one or more (separated by '|') of the following " + "constant values.</p>"); + } else { + processor->appendComment("<p>Must be one of the following constant values.</p>"); + } + + processor->appendComment("<table>\n<colgroup align=\"left\" />\n" + "<colgroup align=\"left\" />\n" + "<colgroup align=\"left\" />\n" + "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>\n"); + for (const Attribute::Symbol& symbol : attr->symbols) { + std::stringstream line; + line << "<tr><td>" << symbol.symbol.name.value().entry << "</td>" + << "<td>" << std::hex << symbol.value << std::dec << "</td>" + << "<td>" << util::trimWhitespace(symbol.symbol.getComment()) << "</td></tr>"; + processor->appendComment(line.str()); + } + processor->appendComment("</table>"); + } +} + bool JavaClassGenerator::skipSymbol(SymbolState state) { switch (mOptions.types) { case JavaClassGeneratorOptions::SymbolTypes::kAll: @@ -117,6 +198,7 @@ bool JavaClassGenerator::skipSymbol(SymbolState state) { struct StyleableAttr { const Reference* attrRef; + std::shared_ptr<Attribute> attribute; std::string fieldName; }; @@ -148,8 +230,29 @@ void JavaClassGenerator::writeStyleableEntryForClass(ClassDefinitionWriter* outC assert((!mOptions.useFinal || attr.id) && "no ID set for Styleable entry"); assert(attr.name && "no name set for Styleable entry"); - sortedAttributes.emplace_back(StyleableAttr{ - &attr, transformNestedAttr(attr.name.value(), className, packageNameToGenerate) }); + StyleableAttr styleableAttr = {}; + styleableAttr.attrRef = &attr; + styleableAttr.fieldName = transformNestedAttr(attr.name.value(), className, + packageNameToGenerate); + + Reference mangledReference; + mangledReference.id = attr.id; + mangledReference.name = attr.name; + if (mangledReference.name.value().package.empty()) { + mangledReference.name.value().package = mContext->getCompilationPackage(); + } + + if (Maybe<ResourceName> mangledName = + mContext->getNameMangler()->mangleName(mangledReference.name.value())) { + mangledReference.name = mangledName; + } + + const SymbolTable::Symbol* symbol = mContext->getExternalSymbols()->findByReference( + mangledReference); + if (symbol) { + styleableAttr.attribute = symbol->attribute; + } + sortedAttributes.push_back(std::move(styleableAttr)); } std::sort(sortedAttributes.begin(), sortedAttributes.end(), lessStyleableAttr); @@ -159,16 +262,34 @@ void JavaClassGenerator::writeStyleableEntryForClass(ClassDefinitionWriter* outC // Build the comment string for the Styleable. It includes details about the // child attributes. std::stringstream styleableComment; - styleableComment << "Attributes that can be used with a " << className << ".\n"; - styleableComment << "<table>\n" + if (!styleable->getComment().empty()) { + styleableComment << styleable->getComment() << "\n"; + } else { + styleableComment << "Attributes that can be used with a " << className << ".\n"; + } + styleableComment << + "<p>Includes the following attributes:</p>\n" + "<table>\n" + "<colgroup align=\"left\" />\n" "<colgroup align=\"left\" />\n" - "<colgroup align=\"left\">\n" "<tr><th>Attribute</th><th>Description</th></tr>\n"; + for (const auto& entry : sortedAttributes) { const ResourceName& attrName = entry.attrRef->name.value(); - styleableComment << "<tr><td><code>{@link #" << entry.fieldName << " " - << attrName.package << ":" << attrName.entry - << "}</code></td><td></td></tr>\n"; + styleableComment << "<tr><td>"; + styleableComment << "<code>{@link #" + << entry.fieldName << " " + << (!attrName.package.empty() + ? attrName.package : mContext->getCompilationPackage()) + << ":" << attrName.entry + << "}</code>"; + styleableComment << "</td>"; + + styleableComment << "<td>"; + if (entry.attribute) { + styleableComment << entry.attribute->getComment(); + } + styleableComment << "</td></tr>\n"; } styleableComment << "</table>\n"; for (const auto& entry : sortedAttributes) { @@ -189,96 +310,45 @@ void JavaClassGenerator::writeStyleableEntryForClass(ClassDefinitionWriter* outC // Now we emit the indices into the array. for (size_t i = 0; i < attrCount; i++) { - const ResourceName& attrName = sortedAttributes[i].attrRef->name.value(); + const StyleableAttr& styleableAttr = sortedAttributes[i]; + const ResourceName& attrName = styleableAttr.attrRef->name.value(); - AnnotationProcessor attrProcessor; - std::stringstream doclavaComments; - doclavaComments << "@attr name "; - if (!attrName.package.empty()) { - doclavaComments << attrName.package << ":"; + StringPiece16 packageName = attrName.package; + if (packageName.empty()) { + packageName = mContext->getCompilationPackage(); } - doclavaComments << attrName.entry; - attrProcessor.appendComment(doclavaComments.str()); - outClassDef->addIntMember(sortedAttributes[i].fieldName, &attrProcessor, i); - } -} - -static void addAttributeFormatDoc(AnnotationProcessor* processor, Attribute* attr) { - const uint32_t typeMask = attr->typeMask; - if (typeMask & android::ResTable_map::TYPE_REFERENCE) { - processor->appendComment( - "<p>May be a reference to another resource, in the form\n" - "\"<code>@[+][<i>package</i>:]<i>type</i>/<i>name</i></code>\" or a theme\n" - "attribute in the form\n" - "\"<code>?[<i>package</i>:]<i>type</i>/<i>name</i></code>\"."); - } - - if (typeMask & android::ResTable_map::TYPE_STRING) { - processor->appendComment( - "<p>May be a string value, using '\\\\;' to escape characters such as\n" - "'\\\\n' or '\\\\uxxxx' for a unicode character;"); - } - - if (typeMask & android::ResTable_map::TYPE_INTEGER) { - processor->appendComment("<p>May be an integer value, such as \"<code>100</code>\"."); - } - - if (typeMask & android::ResTable_map::TYPE_BOOLEAN) { - processor->appendComment( - "<p>May be a boolean value, such as \"<code>true</code>\" or\n" - "\"<code>false</code>\"."); - } - - if (typeMask & android::ResTable_map::TYPE_COLOR) { - processor->appendComment( - "<p>May be a color value, in the form of \"<code>#<i>rgb</i></code>\",\n" - "\"<code>#<i>argb</i></code>\", \"<code>#<i>rrggbb</i></code\", or \n" - "\"<code>#<i>aarrggbb</i></code>\"."); - } - - if (typeMask & android::ResTable_map::TYPE_FLOAT) { - processor->appendComment( - "<p>May be a floating point value, such as \"<code>1.2</code>\"."); - } - if (typeMask & android::ResTable_map::TYPE_DIMENSION) { - processor->appendComment( - "<p>May be a dimension value, which is a floating point number appended with a\n" - "unit such as \"<code>14.5sp</code>\".\n" - "Available units are: px (pixels), dp (density-independent pixels),\n" - "sp (scaled pixels based on preferred font size), in (inches), and\n" - "mm (millimeters)."); - } + AnnotationProcessor attrProcessor; - if (typeMask & android::ResTable_map::TYPE_FRACTION) { - processor->appendComment( - "<p>May be a fractional value, which is a floating point number appended with\n" - "either % or %p, such as \"<code>14.5%</code>\".\n" - "The % suffix always means a percentage of the base size;\n" - "the optional %p suffix provides a size relative to some parent container."); - } + StringPiece16 comment = styleableAttr.attrRef->getComment(); + if (styleableAttr.attribute && comment.empty()) { + comment = styleableAttr.attribute->getComment(); + } - if (typeMask & (android::ResTable_map::TYPE_FLAGS | android::ResTable_map::TYPE_ENUM)) { - if (typeMask & android::ResTable_map::TYPE_FLAGS) { - processor->appendComment( - "<p>Must be one or more (separated by '|') of the following " - "constant values.</p>"); + if (!comment.empty()) { + attrProcessor.appendComment("<p>\n@attr description"); + attrProcessor.appendComment(comment); } else { - processor->appendComment("<p>Must be one of the following constant values.</p>"); + std::stringstream defaultComment; + defaultComment + << "<p>This symbol is the offset where the " + << "{@link " << packageName << ".R.attr#" << transform(attrName.entry) << "}\n" + << "attribute's value can be found in the " + << "{@link #" << className << "} array."; + attrProcessor.appendComment(defaultComment.str()); } - processor->appendComment("<table>\n<colgroup align=\"left\" />\n" - "<colgroup align=\"left\" />\n" - "<colgroup align=\"left\" />\n" - "<tr><th>Constant</th><th>Value</th><th>Description</th></tr>\n"); - for (const Attribute::Symbol& symbol : attr->symbols) { - std::stringstream line; - line << "<tr><td>" << symbol.symbol.name.value().entry << "</td>" - << "<td>" << std::hex << symbol.value << std::dec << "</td>" - << "<td>" << util::trimWhitespace(symbol.symbol.getComment()) << "</td></tr>"; - processor->appendComment(line.str()); + attrProcessor.appendNewLine(); + + if (styleableAttr.attribute) { + addAttributeFormatDoc(&attrProcessor, styleableAttr.attribute.get()); + attrProcessor.appendNewLine(); } - processor->appendComment("</table>"); + + std::stringstream doclavaName; + doclavaName << "@attr name " << packageName << ":" << attrName.entry;; + attrProcessor.appendComment(doclavaName.str()); + outClassDef->addIntMember(sortedAttributes[i].fieldName, &attrProcessor, i); } } diff --git a/tools/aapt2/java/JavaClassGenerator.h b/tools/aapt2/java/JavaClassGenerator.h index 023d6d635f8c..7e46f8c9043c 100644 --- a/tools/aapt2/java/JavaClassGenerator.h +++ b/tools/aapt2/java/JavaClassGenerator.h @@ -19,7 +19,7 @@ #include "ResourceTable.h" #include "ResourceValues.h" - +#include "process/IResourceTableConsumer.h" #include "util/StringPiece.h" #include <ostream> @@ -51,7 +51,8 @@ struct JavaClassGeneratorOptions { */ class JavaClassGenerator { public: - JavaClassGenerator(ResourceTable* table, JavaClassGeneratorOptions options); + JavaClassGenerator(IAaptContext* context, ResourceTable* table, + const JavaClassGeneratorOptions& options); /* * Writes the R.java file to `out`. Only symbols belonging to `package` are written. @@ -82,6 +83,7 @@ private: bool skipSymbol(SymbolState state); + IAaptContext* mContext; ResourceTable* mTable; JavaClassGeneratorOptions mOptions; std::string mError; diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp index 63d38a8981f4..4f041b88efbc 100644 --- a/tools/aapt2/java/JavaClassGenerator_test.cpp +++ b/tools/aapt2/java/JavaClassGenerator_test.cpp @@ -15,11 +15,9 @@ */ #include "java/JavaClassGenerator.h" +#include "test/Test.h" #include "util/Util.h" -#include "test/Builders.h" - -#include <gtest/gtest.h> #include <sstream> #include <string> @@ -31,7 +29,11 @@ TEST(JavaClassGeneratorTest, FailWhenEntryIsJavaKeyword) { .addSimple(u"@android:id/class", ResourceId(0x01020000)) .build(); - JavaClassGenerator generator(table.get(), {}); + std::unique_ptr<IAaptContext> context = test::ContextBuilder() + .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) + .setNameManglerPolicy(NameManglerPolicy{ u"android" }) + .build(); + JavaClassGenerator generator(context.get(), table.get(), {}); std::stringstream out; EXPECT_FALSE(generator.generate(u"android", &out)); @@ -48,7 +50,11 @@ TEST(JavaClassGeneratorTest, TransformInvalidJavaIdentifierCharacter) { .build()) .build(); - JavaClassGenerator generator(table.get(), {}); + std::unique_ptr<IAaptContext> context = test::ContextBuilder() + .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) + .setNameManglerPolicy(NameManglerPolicy{ u"android" }) + .build(); + JavaClassGenerator generator(context.get(), table.get(), {}); std::stringstream out; EXPECT_TRUE(generator.generate(u"android", &out)); @@ -72,7 +78,11 @@ TEST(JavaClassGeneratorTest, CorrectPackageNameIsUsed) { .addSimple(u"@android:id/com.foo$two", ResourceId(0x01020001)) .build(); - JavaClassGenerator generator(table.get(), {}); + std::unique_ptr<IAaptContext> context = test::ContextBuilder() + .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) + .setNameManglerPolicy(NameManglerPolicy{ u"android" }) + .build(); + JavaClassGenerator generator(context.get(), table.get(), {}); std::stringstream out; ASSERT_TRUE(generator.generate(u"android", u"com.android.internal", &out)); @@ -90,7 +100,11 @@ TEST(JavaClassGeneratorTest, AttrPrivateIsWrittenAsAttr) { .addSimple(u"@android:^attr-private/one", ResourceId(0x01010000)) .build(); - JavaClassGenerator generator(table.get(), {}); + std::unique_ptr<IAaptContext> context = test::ContextBuilder() + .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) + .setNameManglerPolicy(NameManglerPolicy{ u"android" }) + .build(); + JavaClassGenerator generator(context.get(), table.get(), {}); std::stringstream out; ASSERT_TRUE(generator.generate(u"android", &out)); @@ -110,10 +124,15 @@ TEST(JavaClassGeneratorTest, OnlyWritePublicResources) { .setSymbolState(u"@android:id/two", ResourceId(0x01020001), SymbolState::kPrivate) .build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder() + .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) + .setNameManglerPolicy(NameManglerPolicy{ u"android" }) + .build(); + JavaClassGeneratorOptions options; options.types = JavaClassGeneratorOptions::SymbolTypes::kPublic; { - JavaClassGenerator generator(table.get(), options); + JavaClassGenerator generator(context.get(), table.get(), options); std::stringstream out; ASSERT_TRUE(generator.generate(u"android", &out)); std::string output = out.str(); @@ -124,7 +143,7 @@ TEST(JavaClassGeneratorTest, OnlyWritePublicResources) { options.types = JavaClassGeneratorOptions::SymbolTypes::kPublicPrivate; { - JavaClassGenerator generator(table.get(), options); + JavaClassGenerator generator(context.get(), table.get(), options); std::stringstream out; ASSERT_TRUE(generator.generate(u"android", &out)); std::string output = out.str(); @@ -135,7 +154,7 @@ TEST(JavaClassGeneratorTest, OnlyWritePublicResources) { options.types = JavaClassGeneratorOptions::SymbolTypes::kAll; { - JavaClassGenerator generator(table.get(), options); + JavaClassGenerator generator(context.get(), table.get(), options); std::stringstream out; ASSERT_TRUE(generator.generate(u"android", &out)); std::string output = out.str(); @@ -189,7 +208,11 @@ TEST(JavaClassGeneratorTest, EmitOtherPackagesAttributesInStyleable) { .build()) .build(); - JavaClassGenerator generator(table.get(), {}); + std::unique_ptr<IAaptContext> context = test::ContextBuilder() + .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) + .setNameManglerPolicy(NameManglerPolicy{ u"android" }) + .build(); + JavaClassGenerator generator(context.get(), table.get(), {}); std::stringstream out; EXPECT_TRUE(generator.generate(u"android", &out)); @@ -207,8 +230,11 @@ TEST(JavaClassGeneratorTest, CommentsForSimpleResourcesArePresent) { test::getValue<Id>(table.get(), u"@android:id/foo") ->setComment(std::u16string(u"This is a comment\n@deprecated")); - JavaClassGenerator generator(table.get(), {}); - + std::unique_ptr<IAaptContext> context = test::ContextBuilder() + .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) + .setNameManglerPolicy(NameManglerPolicy{ u"android" }) + .build(); + JavaClassGenerator generator(context.get(), table.get(), {}); std::stringstream out; ASSERT_TRUE(generator.generate(u"android", &out)); std::string actual = out.str(); @@ -241,10 +267,13 @@ TEST(JavaClassGeneratorTest, CommentsForStyleablesAndNestedAttributesArePresent) std::unique_ptr<Styleable>(styleable.clone(nullptr))) .build(); + std::unique_ptr<IAaptContext> context = test::ContextBuilder() + .addSymbolSource(util::make_unique<ResourceTableSymbolSource>(table.get())) + .setNameManglerPolicy(NameManglerPolicy{ u"android" }) + .build(); JavaClassGeneratorOptions options; options.useFinal = false; - JavaClassGenerator generator(table.get(), options); - + JavaClassGenerator generator(context.get(), table.get(), options); std::stringstream out; ASSERT_TRUE(generator.generate(u"android", &out)); std::string actual = out.str(); diff --git a/tools/aapt2/link/Link.cpp b/tools/aapt2/link/Link.cpp index 5003d9658525..b84074d1cb58 100644 --- a/tools/aapt2/link/Link.cpp +++ b/tools/aapt2/link/Link.cpp @@ -729,20 +729,31 @@ public: std::string outPath = mOptions.generateJavaClassPath.value(); file::appendPath(&outPath, file::packageToPath(util::utf16ToUtf8(outPackage))); - file::mkdirs(outPath); + if (!file::mkdirs(outPath)) { + mContext->getDiagnostics()->error( + DiagMessage() << "failed to create directory '" << outPath << "'"); + return false; + } + file::appendPath(&outPath, "R.java"); std::ofstream fout(outPath, std::ofstream::binary); if (!fout) { - mContext->getDiagnostics()->error(DiagMessage() << strerror(errno)); + mContext->getDiagnostics()->error( + DiagMessage() << "failed writing to '" << outPath << "': " << strerror(errno)); return false; } - JavaClassGenerator generator(table, javaOptions); + JavaClassGenerator generator(mContext, table, javaOptions); if (!generator.generate(packageNameToGenerate, outPackage, &fout)) { mContext->getDiagnostics()->error(DiagMessage(outPath) << generator.getError()); return false; } + + if (!fout) { + mContext->getDiagnostics()->error( + DiagMessage() << "failed writing to '" << outPath << "': " << strerror(errno)); + } return true; } @@ -754,12 +765,18 @@ public: std::string outPath = mOptions.generateJavaClassPath.value(); file::appendPath(&outPath, file::packageToPath(util::utf16ToUtf8(mContext->getCompilationPackage()))); - file::mkdirs(outPath); + if (!file::mkdirs(outPath)) { + mContext->getDiagnostics()->error( + DiagMessage() << "failed to create directory '" << outPath << "'"); + return false; + } + file::appendPath(&outPath, "Manifest.java"); std::ofstream fout(outPath, std::ofstream::binary); if (!fout) { - mContext->getDiagnostics()->error(DiagMessage() << strerror(errno)); + mContext->getDiagnostics()->error( + DiagMessage() << "failed writing to '" << outPath << "': " << strerror(errno)); return false; } @@ -770,7 +787,8 @@ public: } if (!fout) { - mContext->getDiagnostics()->error(DiagMessage() << strerror(errno)); + mContext->getDiagnostics()->error( + DiagMessage() << "failed writing to '" << outPath << "': " << strerror(errno)); return false; } return true; @@ -781,15 +799,18 @@ public: return true; } - std::ofstream fout(mOptions.generateProguardRulesPath.value(), std::ofstream::binary); + const std::string& outPath = mOptions.generateProguardRulesPath.value(); + std::ofstream fout(outPath, std::ofstream::binary); if (!fout) { - mContext->getDiagnostics()->error(DiagMessage() << strerror(errno)); + mContext->getDiagnostics()->error( + DiagMessage() << "failed to open '" << outPath << "': " << strerror(errno)); return false; } proguard::writeKeepSet(&fout, keepSet); if (!fout) { - mContext->getDiagnostics()->error(DiagMessage() << strerror(errno)); + mContext->getDiagnostics()->error( + DiagMessage() << "failed writing to '" << outPath << "': " << strerror(errno)); return false; } return true; diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp index a8f9bfe4fb32..eaaf06f7e530 100644 --- a/tools/aapt2/process/SymbolTable.cpp +++ b/tools/aapt2/process/SymbolTable.cpp @@ -51,6 +51,11 @@ const SymbolTable::Symbol* SymbolTable::findByName(const ResourceName& name) { // doesn't support unique_ptr. std::shared_ptr<Symbol> sharedSymbol = std::shared_ptr<Symbol>(symbol.release()); mCache.put(name, sharedSymbol); + + if (sharedSymbol->id) { + // The symbol has an ID, so we can also cache this! + mIdCache.put(sharedSymbol->id.value(), sharedSymbol); + } return sharedSymbol.get(); } } @@ -76,6 +81,25 @@ const SymbolTable::Symbol* SymbolTable::findById(ResourceId id) { return nullptr; } +const SymbolTable::Symbol* SymbolTable::findByReference(const Reference& ref) { + // First try the ID. This is because when we lookup by ID, we only fill in the ID cache. + // Looking up by name fills in the name and ID cache. So a cache miss will cause a failed + // ID lookup, then a successfull name lookup. Subsequent look ups will hit immediately + // because the ID is cached too. + // + // If we looked up by name first, a cache miss would mean we failed to lookup by name, then + // succeeded to lookup by ID. Subsequent lookups will miss then hit. + const SymbolTable::Symbol* symbol = nullptr; + if (ref.id) { + symbol = findById(ref.id.value()); + } + + if (ref.name && !symbol) { + symbol = findByName(ref.name.value()); + } + return symbol; +} + std::unique_ptr<SymbolTable::Symbol> ResourceTableSymbolSource::findByName( const ResourceName& name) { Maybe<ResourceTable::SearchResult> result = mTable->findResource(name); @@ -102,7 +126,7 @@ std::unique_ptr<SymbolTable::Symbol> ResourceTableSymbolSource::findByName( if (configValue) { // This resource has an Attribute. if (Attribute* attr = valueCast<Attribute>(configValue->value.get())) { - symbol->attribute = util::make_unique<Attribute>(*attr); + symbol->attribute = std::make_shared<Attribute>(*attr); } else { return {}; } @@ -133,7 +157,7 @@ static std::unique_ptr<SymbolTable::Symbol> lookupAttributeInTable(const android // Check to see if it is an attribute. for (size_t i = 0; i < (size_t) count; i++) { if (entry[i].map.name.ident == android::ResTable_map::ATTR_TYPE) { - s->attribute = util::make_unique<Attribute>(false); + s->attribute = std::make_shared<Attribute>(false); s->attribute->typeMask = entry[i].map.value.data; break; } @@ -272,4 +296,15 @@ std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::findById(Resource return {}; } +std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::findByReference( + const Reference& ref) { + // AssetManager always prefers IDs. + if (ref.id) { + return findById(ref.id.value()); + } else if (ref.name) { + return findByName(ref.name.value()); + } + return {}; +} + } // namespace aapt diff --git a/tools/aapt2/process/SymbolTable.h b/tools/aapt2/process/SymbolTable.h index 8ea1c757fc68..0a6a4a541a8d 100644 --- a/tools/aapt2/process/SymbolTable.h +++ b/tools/aapt2/process/SymbolTable.h @@ -52,7 +52,7 @@ class SymbolTable { public: struct Symbol { Maybe<ResourceId> id; - std::unique_ptr<Attribute> attribute; + std::shared_ptr<Attribute> attribute; bool isPublic; }; @@ -69,6 +69,12 @@ public: const Symbol* findByName(const ResourceName& name); const Symbol* findById(ResourceId id); + /** + * Let's the ISymbolSource decide whether looking up by name or ID is faster, if both + * are available. + */ + const Symbol* findByReference(const Reference& ref); + private: std::vector<std::unique_ptr<ISymbolSource>> mSources; @@ -90,6 +96,18 @@ public: virtual std::unique_ptr<SymbolTable::Symbol> findByName(const ResourceName& name) = 0; virtual std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) = 0; + + /** + * Default implementation tries the name if it exists, else the ID. + */ + virtual std::unique_ptr<SymbolTable::Symbol> findByReference(const Reference& ref) { + if (ref.name) { + return findByName(ref.name.value()); + } else if (ref.id) { + return findById(ref.id.value()); + } + return {}; + } }; /** @@ -122,6 +140,7 @@ public: std::unique_ptr<SymbolTable::Symbol> findByName(const ResourceName& name) override; std::unique_ptr<SymbolTable::Symbol> findById(ResourceId id) override; + std::unique_ptr<SymbolTable::Symbol> findByReference(const Reference& ref) override; private: android::AssetManager mAssets; diff --git a/tools/aapt2/util/Files.cpp b/tools/aapt2/util/Files.cpp index 04e8199d85b4..6428e9867334 100644 --- a/tools/aapt2/util/Files.cpp +++ b/tools/aapt2/util/Files.cpp @@ -96,7 +96,7 @@ bool mkdirs(const StringPiece& path) { const char* start = path.begin(); const char* end = path.end(); for (const char* current = start; current != end; ++current) { - if (*current == sDirSep) { + if (*current == sDirSep && current != start) { StringPiece parentPath(start, current - start); int result = mkdirImpl(parentPath); if (result < 0 && errno != EEXIST) { @@ -139,6 +139,20 @@ StringPiece getExtension(const StringPiece& path) { return {}; } +void appendPath(std::string* base, StringPiece part) { + assert(base); + const bool baseHasTrailingSep = (!base->empty() && *(base->end() - 1) == sDirSep); + const bool partHasLeadingSep = (!part.empty() && *(part.begin()) == sDirSep); + if (baseHasTrailingSep && partHasLeadingSep) { + // Remove the part's leading sep + part = part.substr(1, part.size() - 1); + } else if (!baseHasTrailingSep && !partHasLeadingSep) { + // None of the pieces has a separator. + *base += sDirSep; + } + base->append(part.data(), part.size()); +} + std::string packageToPath(const StringPiece& package) { std::string outPath; for (StringPiece part : util::tokenize<char>(package, '.')) { diff --git a/tools/aapt2/util/Files.h b/tools/aapt2/util/Files.h index c58ba5d6d1e3..c2e611543b1e 100644 --- a/tools/aapt2/util/Files.h +++ b/tools/aapt2/util/Files.h @@ -61,14 +61,7 @@ std::vector<std::string> listFiles(const StringPiece& root); /* * Appends a path to `base`, separated by the directory separator. */ -void appendPath(std::string* base, const StringPiece& part); - -/* - * Appends a series of paths to `base`, separated by the - * system directory separator. - */ -template <typename... Ts > -void appendPath(std::string* base, const StringPiece& part, const Ts&... parts); +void appendPath(std::string* base, StringPiece part); /* * Makes all the directories in `path`. The last element in the path @@ -139,20 +132,6 @@ private: std::vector<std::string> mPatternTokens; }; -inline void appendPath(std::string* base, const StringPiece& part) { - assert(base); - *base += sDirSep; - base->append(part.data(), part.size()); -} - -template <typename... Ts > -void appendPath(std::string* base, const StringPiece& part, const Ts&... parts) { - assert(base); - *base += sDirSep; - base->append(part.data(), part.size()); - appendPath(base, parts...); -} - } // namespace file } // namespace aapt diff --git a/tools/aapt2/util/Files_test.cpp b/tools/aapt2/util/Files_test.cpp new file mode 100644 index 000000000000..efb04593ff82 --- /dev/null +++ b/tools/aapt2/util/Files_test.cpp @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "test/Test.h" +#include "util/Files.h" + +#include <sstream> + +namespace aapt { +namespace file { + +class FilesTest : public ::testing::Test { +public: + void SetUp() override { + std::stringstream builder; + builder << "hello" << sDirSep << "there"; + mExpectedPath = builder.str(); + } + +protected: + std::string mExpectedPath; +}; + +TEST_F(FilesTest, appendPath) { + std::string base = "hello"; + appendPath(&base, "there"); + EXPECT_EQ(mExpectedPath, base); +} + +TEST_F(FilesTest, appendPathWithLeadingOrTrailingSeparators) { + std::string base = "hello/"; + appendPath(&base, "there"); + EXPECT_EQ(mExpectedPath, base); + + base = "hello"; + appendPath(&base, "/there"); + EXPECT_EQ(mExpectedPath, base); + + base = "hello/"; + appendPath(&base, "/there"); + EXPECT_EQ(mExpectedPath, base); +} + +} // namespace files +} // namespace aapt 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/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java index 97195e4b32da..62f91f761683 100644 --- a/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java +++ b/tools/layoutlib/bridge/src/android/view/IWindowManagerImpl.java @@ -561,6 +561,10 @@ public class IWindowManagerImpl implements IWindowManager { } @Override + public void setDockedStackDividerTouchRegion(Rect touchableRegion) throws RemoteException { + } + + @Override public void requestAppKeyboardShortcuts(IResultReceiver receiver) throws RemoteException { } 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(); |